1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Callgrind, a Valgrind tool for call graph 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown profiling programs. 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2002-2011, Josef Weidendorfer (Josef.Weidendorfer@gmx.de) 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This tool is derived from and contains lot of code from Cachegrind 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2002-2011 Nicholas Nethercote (njn@valgrind.org) 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Functions related to interactive commands via "callgrind.cmd" 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "config.h" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "global.h" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_tool_threadstate.h" // VG_N_THREADS 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Version for the syntax in command/result files for interactive control 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define COMMAND_VERSION "1.0" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char outbuf[FILENAME_LEN + FN_NAME_LEN + OBJ_NAME_LEN]; 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* command_file = 0; 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* command_file2 = 0; 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* current_command_file = 0; 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* result_file = 0; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* result_file2 = 0; 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* current_result_file = 0; 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* info_file = 0; 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Char* out_file = 0; 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int thisPID = 0; 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * Setup for interactive control of a callgrind run 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void setup_control(void) 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int fd, size; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* dir; 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov const HChar *tmpdir; 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(thisPID != 0); 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = -1; 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dir = CLG_(get_out_directory)(); 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out_file = CLG_(get_out_file)(); 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* name of command file */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size = VG_(strlen)(dir) + VG_(strlen)(DEFAULT_COMMANDNAME) +10; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown command_file = (char*) CLG_MALLOC("cl.command.sc.1", size); 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(command_file != 0); 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(command_file, "%s/%s.%d", 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dir, DEFAULT_COMMANDNAME, thisPID); 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is for compatibility with the "Force Now" Button of current 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * KCachegrind releases, as it doesn't use ".pid" to distinguish 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * different callgrind instances from same base directory. 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown command_file2 = (char*) CLG_MALLOC("cl.command.sc.2", size); 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(command_file2 != 0); 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(command_file2, "%s/%s", 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dir, DEFAULT_COMMANDNAME); 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size = VG_(strlen)(dir) + VG_(strlen)(DEFAULT_RESULTNAME) +10; 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result_file = (char*) CLG_MALLOC("cl.command.sc.3", size); 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(result_file != 0); 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(result_file, "%s/%s.%d", 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dir, DEFAULT_RESULTNAME, thisPID); 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If we get a command from a command file without .pid, use 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * a result file without .pid suffix 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result_file2 = (char*) CLG_MALLOC("cl.command.sc.4", size); 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(result_file2 != 0); 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(result_file2, "%s/%s", 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dir, DEFAULT_RESULTNAME); 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tmpdir = VG_(tmpdir)(); 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info_file = (char*) CLG_MALLOC("cl.command.sc.5", 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(strlen)(tmpdir) + 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(strlen)(DEFAULT_INFONAME) + 10); 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(info_file != 0); 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_(sprintf)(info_file, "%s/%s.%d", tmpdir, DEFAULT_INFONAME, thisPID); 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, "Setup for interactive control (PID: %d):\n", thisPID); 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, " output file: '%s'\n", out_file); 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, " command file: '%s'\n", command_file); 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, " result file: '%s'\n", result_file); 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_DEBUG(1, " info file: '%s'\n", info_file); 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* create info file to indicate that we are running */ 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = VG_(open)(info_file, VKI_O_WRONLY|VKI_O_TRUNC, 0); 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sr_isError(res)) { 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = VG_(open)(info_file, VKI_O_CREAT|VKI_O_WRONLY, 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VKI_S_IRUSR|VKI_S_IWUSR); 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sr_isError(res)) { 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "warning: can't write info file '%s'\n", info_file); 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info_file = 0; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = -1; 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!sr_isError(res)) 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = (Int) sr_Res(res); 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fd>=0) { 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char buf[512]; 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "# This file is generated by Callgrind-" VERSION ".\n" 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "# It is used to enable controlling the supervision of\n" 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "# '", VG_(args_the_exename), "'\n" 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "# by external tools.\n\n"); 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "version: " COMMAND_VERSION "\n"); 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, "base: ", dir, "\n"); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, "dumps: ", out_file, "\n"); 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, "control: ", command_file, "\n"); 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, "result: ", result_file, "\n"); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR2(fd, "cmd: ", VG_(args_the_exename)); 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i ); 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!arg) continue; 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR2(fd, " ", arg); 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, "\n", 1); 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(close)(fd); 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(init_command)() 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thisPID = VG_(getpid)(); 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setup_control(); 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(finish_command)() 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unlink info file */ 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (info_file) VG_(unlink)(info_file); 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int createRes(Int fd) 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fd > -2) return fd; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* fd == -2: No error, but we need to create the file */ 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_ASSERT(current_result_file != 0); 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = VG_(open)(current_result_file, 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC, 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VKI_S_IRUSR|VKI_S_IWUSR); 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* VG_(open) can return any negative number on error. Remap errors to -1, 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * to not confuse it with our special value -2 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sr_isError(res)) fd = -1; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else fd = (Int) sr_Res(res); 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fd; 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Run Info: Persistant information of the callgrind run */ 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int dump_info(Int fd) 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* buf = outbuf; 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int i; 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( (fd = createRes(fd)) <0) return fd; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* creator */ 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "creator: callgrind-" VERSION "\n"); 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* version */ 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "version: " COMMAND_VERSION "\n"); 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* "pid:" line */ 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "pid: %d\n", VG_(getpid)()); 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* "base:" line */ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR3(fd, "base: ", out_file, "\n"); 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* "cmd:" line */ 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR2(fd, "cmd: ", VG_(args_the_exename)); 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i ); 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!arg) continue; 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WRITE_STR2(fd, " ", arg); 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, "\n", 1); 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fd; 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Helper for dump_state */ 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownInt dump_fd; 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid static dump_state_of_thread(thread_info* ti) 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* buf = outbuf; 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int t = CLG_(current_tid); 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int p, i; 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static FullCost sum = 0, tmp = 0; 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown BBCC *from, *to; 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown call_entry* ce; 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "events-%d: ", t); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(init_cost_lz)( CLG_(sets).full, &sum ); 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost_lz)( CLG_(sets).full, &tmp, ti->lastdump_cost ); 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(add_diff_cost)( CLG_(sets).full, sum, 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ti->lastdump_cost, 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ti->states.entry[0]->cost); 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost)( CLG_(sets).full, ti->lastdump_cost, tmp ); 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += CLG_(sprint_mappingcost)(buf + p, CLG_(dumpmap), sum); 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += VG_(sprintf)(buf+p, "\n"); 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "frames-%d: %d\n", t, 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(current_call_stack).sp); 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ce = 0; 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(i = 0; i < CLG_(current_call_stack).sp; i++) { 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ce = CLG_(get_call_entry)(i); 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* if this frame is skipped, we don't have counters */ 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!ce->jcc) continue; 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from = ce->jcc->from; 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "function-%d-%d: %s\n",t, i, 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from->cxt->fn[0]->name); 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "calls-%d-%d: ",t, i); 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p+= VG_(sprintf)(buf+p, "%llu\n", ce->jcc->call_counter); 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME: EventSets! */ 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost)( CLG_(sets).full, sum, ce->jcc->cost ); 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost)( CLG_(sets).full, tmp, ce->enter_cost ); 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(add_diff_cost)( CLG_(sets).full, sum, 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ce->enter_cost, CLG_(current_state).cost ); 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(copy_cost)( CLG_(sets).full, ce->enter_cost, tmp ); 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "events-%d-%d: ",t, i); 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += CLG_(sprint_mappingcost)(buf + p, CLG_(dumpmap), sum ); 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += VG_(sprintf)(buf+p, "\n"); 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ce && ce->jcc) { 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to = ce->jcc->to; 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "function-%d-%d: %s\n",t, i, 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to->cxt->fn[0]->name ); 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(dump_fd, (void*)buf, p); 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Dump info on current callgrind state */ 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int dump_state(Int fd) 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char* buf = outbuf; 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thread_info** th; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int t, p; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int orig_tid = CLG_(current_tid); 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( (fd = createRes(fd)) <0) return fd; 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "instrumentation: %s\n", 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(instrument_state) ? "on":"off"); 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!CLG_(instrument_state)) return fd; 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "executed-bbs: %llu\n", CLG_(stat).bb_executions); 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "executed-calls: %llu\n", CLG_(stat).call_counter); 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "distinct-bbs: %d\n", CLG_(stat).distinct_bbs); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "distinct-calls: %d\n", CLG_(stat).distinct_jccs); 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "distinct-functions: %d\n", CLG_(stat).distinct_fns); 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "distinct-contexts: %d\n", CLG_(stat).distinct_contexts); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* "events:" line. Given here because it will be dynamic in the future */ 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "events: "); 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(sprint_eventmapping)(buf+p, CLG_(dumpmap)); 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, "\n", 1); 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* "part:" line (number of last part. Is 0 at start */ 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "\npart: %d\n", CLG_(get_dump_counter)()); 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* threads */ 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown th = CLG_(get_threads)(); 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = VG_(sprintf)(buf, "threads:"); 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for(t=1;t<VG_N_THREADS;t++) { 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!th[t]) continue; 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += VG_(sprintf)(buf+p, " %d", t); 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += VG_(sprintf)(buf+p, "\n"); 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, p); 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "current-tid: %d\n", orig_tid); 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* current event counters */ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dump_fd = fd; 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(forall_threads)(dump_state_of_thread); 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return fd; 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid CLG_(check_command)() 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* check for dumps needed */ 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Char buf[512]; 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Char cmdBuffer[512]; 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Char *cmdPos = 0, *cmdNextLine = 0; 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int fd, bytesRead = 0, do_kill = 0; 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes res; 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int currentPID; 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Int check_counter = 0; 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Check for PID change, i.e. whether we run as child after a fork. 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * If yes, we setup interactive control for the new process 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown currentPID = VG_(getpid)(); 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (thisPID != currentPID) { 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thisPID = currentPID; 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown setup_control(); 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Toggle between 2 command files, with/without ".pid" postfix 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * (needed for compatibility with KCachegrind, which wants to trigger 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * a dump by writing into a command file without the ".pid" postfix) 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown check_counter++; 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (check_counter % 2) { 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_command_file = command_file; 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_result_file = result_file; 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_command_file = command_file2; 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_result_file = result_file2; 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = VG_(open)(current_command_file, VKI_O_RDONLY,0); 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!sr_isError(res)) { 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = (Int) sr_Res(res); 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bytesRead = VG_(read)(fd,cmdBuffer,500); 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdBuffer[500] = 0; /* no command overrun please */ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(close)(fd); 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* don't delete command file on read error (e.g. EAGAIN) */ 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (bytesRead>0) { 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos = cmdBuffer; 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* force creation of result file if needed */ 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = -2; 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while((bytesRead>0) && *cmdPos) { 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Calculate pointer for next line */ 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdNextLine = cmdPos+1; 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while((bytesRead>0) && *cmdNextLine && (*cmdNextLine != '\n')) { 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdNextLine++; 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bytesRead--; 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((bytesRead>0) && (*cmdNextLine == '\n')) { 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *cmdNextLine = 0; 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdNextLine++; 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bytesRead--; 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Command with integer option */ 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((*cmdPos >= '0') && (*cmdPos <='9')) { 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int value = *cmdPos-'0'; 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos++; 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while((*cmdPos >= '0') && (*cmdPos <='9')) { 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value = 10*value + (*cmdPos-'0'); 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos++; 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while((*cmdPos == ' ') || (*cmdPos == '\t')) cmdPos++; 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(*cmdPos) { 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if CLG_ENABLE_DEBUG 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* verbosity */ 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'V': 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'v': 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).verbose = value; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos = cmdNextLine; 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Command with boolean/switch option */ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((*cmdPos=='+') || 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (*cmdPos=='-')) { 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int value = (cmdPos[0] == '+'); 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos++; 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while((*cmdPos == ' ') || (*cmdPos == '\t')) cmdPos++; 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(*cmdPos) { 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'I': 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'i': 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(set_instrument_state)("Command", value); 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos = cmdNextLine; 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* regular command */ 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch(*cmdPos) { 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'D': 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'd': 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* DUMP */ 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* skip command */ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while(*cmdPos && (*cmdPos != ' ')) cmdPos++; 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (*cmdPos) 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "Dump Command:%s", cmdPos); 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "Dump Command"); 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(dump_profile)(buf, False); 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'Z': 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'z': 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(zero_all_cost)(False); 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'K': 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'k': 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Kill: Delay to be able to remove command file before. */ 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_kill = 1; 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'I': 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'i': 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = dump_info(fd); 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 's': 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'S': 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fd = dump_state(fd); 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'O': 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'o': 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Options Info */ 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( (fd = createRes(fd)) <0) break; 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "\ndesc: Option: --skip-plt=%s\n", 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).skip_plt ? "yes" : "no"); 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "desc: Option: --collect-jumps=%s\n", 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).collect_jumps ? "yes" : "no"); 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "desc: Option: --separate-recs=%d\n", 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).separate_recursions); 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sprintf)(buf, "desc: Option: --separate-callers=%d\n", 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(clo).separate_callers); 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmdPos = cmdNextLine; 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If command executed, delete command file */ 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cmdPos) VG_(unlink)(current_command_file); 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fd>=0) VG_(close)(fd); 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (do_kill) { 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Killed because of command from %s\n", 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown current_command_file); 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CLG_(fini)(0); 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(exit)(1); 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 536