From: Josef Weidendorfer Date: Tue, 27 Nov 2007 01:27:12 +0000 (+0000) Subject: callgrind: support for --callgrind-out-file X-Git-Tag: svn/VALGRIND_3_3_0~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1752567fb4dda575901a38ca3fc8ee26db79c8a6;p=thirdparty%2Fvalgrind.git callgrind: support for --callgrind-out-file This removes the --base option, which is replaced by --callgrind-out-file. Plus manual update. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7235 --- diff --git a/callgrind/clo.c b/callgrind/clo.c index 98da3fe446..57d3fb9805 100644 --- a/callgrind/clo.c +++ b/callgrind/clo.c @@ -587,8 +587,8 @@ Bool CLG_(process_cmd_line_option)(Char* arg) fnc->separate_recursions = n; } - else if (0 == VG_(strncmp)(arg, "--base=", 7)) - CLG_(clo).filename_base = VG_(strdup)(arg+7); + else if (0 == VG_(strncmp)(arg, "--callgrind-out-file=", 21)) + CLG_(clo).out_format = VG_(strdup)(arg+21); else if (0 == VG_(strcmp)(arg, "--mangle-names=yes")) CLG_(clo).mangle_names = True; @@ -656,7 +656,7 @@ void CLG_(print_usage)(void) { VG_(printf)( "\n dump creation options:\n" -" --base= Prefix for profile files [" DEFAULT_DUMPNAME "]\n" +" --callgrind-out-file= Output file name [callgrind.out.%%p]\n" " --dump-line=no|yes Dump source lines of costs? [yes]\n" " --dump-instr=no|yes Dump instruction address of costs? [no]\n" " --compress-strings=no|yes Compress strings in profile dump? [yes]\n" @@ -731,7 +731,7 @@ void CLG_(set_clo_defaults)(void) /* Default values for command line arguments */ /* dump options */ - CLG_(clo).filename_base = 0; + CLG_(clo).out_format = 0; CLG_(clo).combine_dumps = False; CLG_(clo).compress_strings = True; CLG_(clo).compress_mangled = False; diff --git a/callgrind/command.c b/callgrind/command.c index faf9f9cc13..d04cbf33e7 100644 --- a/callgrind/command.c +++ b/callgrind/command.c @@ -46,7 +46,7 @@ static Char* result_file = 0; static Char* result_file2 = 0; static Char* current_result_file = 0; static Char* info_file = 0; -static Char* dump_base = 0; +static Char* out_file = 0; static Int thisPID = 0; @@ -57,19 +57,13 @@ static void setup_control(void) { Int fd, size; SysRes res; - Char* dir, *dump_filename; + Char* dir; CLG_ASSERT(thisPID != 0); fd = -1; - dir = CLG_(get_base_directory)(); - dump_base = CLG_(get_dump_file_base)(); - - /* base name of dump files with PID ending */ - size = VG_(strlen)(dump_base) + 10; - dump_filename = (char*) CLG_MALLOC(size); - CLG_ASSERT(dump_filename != 0); - VG_(sprintf)(dump_filename, "%s.%d", dump_base, thisPID); + dir = CLG_(get_out_directory)(); + out_file = CLG_(get_out_file)(); /* name of command file */ size = VG_(strlen)(dir) + VG_(strlen)(DEFAULT_COMMANDNAME) +10; @@ -106,7 +100,7 @@ static void setup_control(void) VG_(sprintf)(info_file, "%s.%d", DEFAULT_INFONAME, thisPID); CLG_DEBUG(1, "Setup for interactive control (PID: %d):\n", thisPID); - CLG_DEBUG(1, " dump file base: '%s'\n", dump_filename); + CLG_DEBUG(1, " output file: '%s'\n", out_file); CLG_DEBUG(1, " command file: '%s'\n", command_file); CLG_DEBUG(1, " result file: '%s'\n", result_file); CLG_DEBUG(1, " info file: '%s'\n", info_file); @@ -139,7 +133,7 @@ static void setup_control(void) VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); WRITE_STR3(fd, "base: ", dir, "\n"); - WRITE_STR3(fd, "dumps: ", dump_filename, "\n"); + WRITE_STR3(fd, "dumps: ", out_file, "\n"); WRITE_STR3(fd, "control: ", command_file, "\n"); WRITE_STR3(fd, "result: ", result_file, "\n"); @@ -209,7 +203,7 @@ static Int dump_info(Int fd) VG_(write)(fd, (void*)buf, VG_(strlen)(buf)); /* "base:" line */ - WRITE_STR3(fd, "base: ", dump_base, "\n"); + WRITE_STR3(fd, "base: ", out_file, "\n"); /* "cmd:" line */ WRITE_STR2(fd, "cmd: ", VG_(args_the_exename)); diff --git a/callgrind/docs/cl-manual.xml b/callgrind/docs/cl-manual.xml index 312c6271dc..d8a34b21ea 100644 --- a/callgrind/docs/cl-manual.xml +++ b/callgrind/docs/cl-manual.xml @@ -126,7 +126,7 @@ on heuristics to detect calls and returns. After program termination, a profile data file named - callgrind.out.pid + callgrind.out.<pid> is generated, where pid is the process ID of the program being profiled. The data file contains information about the calls made in the @@ -135,7 +135,7 @@ on heuristics to detect calls and returns. To generate a function-by-function summary from the profile data file, use - callgrind_annotate [options] callgrind.out.pid + callgrind_annotate [options] callgrind.out.<pid> This summary is similar to the output you get from a Cachegrind run with cg_annotate: the list of functions is ordered by exclusive cost of functions, which also @@ -487,7 +487,7 @@ the output as callgrind --help. xreflabel="Miscellaneous options"> Miscellaneous options - + @@ -515,26 +515,24 @@ the output as callgrind --help. These options influence the name and format of the profile data files. - + - + - + - Specify the base name for the dump file names. To - distinguish different profile runs of the same application, - .<pid> is appended to the - base dump file name with - <pid> being the process ID - of the profiled program. When multiple dumps are made, the file name - is modified further; see below. - This option is - especially useful if your application changes its working - directory. Usually, the dump file is generated in the current - working directory of the application at program termination. By - giving an absolute path with the base specification, you can force - a fixed directory for the dump files. + Write the profile data to + file rather than to the default + output file, + callgrind.out.<pid>. The + and format specifiers + can be used to embed the process ID and/or the contents of an + environment variable in the name, as is the case for the core + option . See here for details. + When multiple dumps are made, the file name + is modified further; see below. @@ -611,7 +609,7 @@ be executed. For interactive control use callgrind_control. - + @@ -664,7 +662,7 @@ be executed. For interactive control use These options specify when events are to be aggregated into event counts. Also see . - + @@ -873,7 +871,7 @@ Also see . xreflabel="Cache simulation options"> Cache simulation options - + @@ -884,7 +882,22 @@ Also see . only instruction read accesses will be profiled. - + + + + + + + Specify whether simulation of a hardware prefetcher should be + added which is able to detect stream access in the second level cache + by comparing accesses to separate to each page. + As the simulation can not decide about any timing issues of prefetching, + it is assumed that any hardware prefetch triggered succeeds before a + real access is done. Thus, this gives a best-case scenario by covering + all possible stream accesses. + + + diff --git a/callgrind/docs/man-annotate.xml b/callgrind/docs/man-annotate.xml index dd668e26e5..529ec78b34 100644 --- a/callgrind/docs/man-annotate.xml +++ b/callgrind/docs/man-annotate.xml @@ -15,7 +15,7 @@ callgrind_annotate produces human readable ASCII output from profile - information in cachegrind.out files + information in callgrind.out.<pid> files diff --git a/callgrind/docs/man-callgrind.xml b/callgrind/docs/man-callgrind.xml index 152543fc67..731c3fb5ff 100644 --- a/callgrind/docs/man-callgrind.xml +++ b/callgrind/docs/man-callgrind.xml @@ -40,7 +40,7 @@ profiling data can be stored into an output file multiple times in a program run, optionally separately for every thread in the case of multithreaded code. For interactive inspection and control, see callgrind_control. The data produced -(callgrind.out.PID) can be analysed with +(callgrind.out.<pid>) can be analysed with callgrind_annotate or better with the graphical profile visualization KCachegrind. Further documentation can be found in HTML format either on your filesystem: diff --git a/callgrind/dump.c b/callgrind/dump.c index 3bfc754317..8a0a646bc2 100644 --- a/callgrind/dump.c +++ b/callgrind/dump.c @@ -36,8 +36,8 @@ /* Dump Part Counter */ static Int out_counter = 0; -static Char* dump_file_base = 0; -static Char* base_directory = 0; +static Char* out_file = 0; +static Char* out_directory = 0; static Bool dumps_initialized = False; /* Command */ @@ -62,16 +62,16 @@ Int CLG_(get_dump_counter)(void) return out_counter; } -Char* CLG_(get_dump_file_base)() +Char* CLG_(get_out_file)() { CLG_ASSERT(dumps_initialized); - return dump_file_base; + return out_file; } -Char* CLG_(get_base_directory)() +Char* CLG_(get_out_directory)() { CLG_ASSERT(dumps_initialized); - return base_directory; + return out_directory; } /*------------------------------------------------------------*/ @@ -1282,7 +1282,7 @@ static int new_dumpfile(Char buf[BUF_LEN], int tid, Char* trigger) CLG_ASSERT(filename != 0); if (!CLG_(clo).combine_dumps) { - i = VG_(sprintf)(filename, "%s.%d", dump_file_base, VG_(getpid)()); + i = VG_(sprintf)(filename, "%s", out_file); if (trigger) i += VG_(sprintf)(filename+i, ".%d", out_counter); @@ -1293,7 +1293,7 @@ static int new_dumpfile(Char buf[BUF_LEN], int tid, Char* trigger) res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_TRUNC, 0); } else { - VG_(sprintf)(filename, "%s.%d", dump_file_base, VG_(getpid)()); + VG_(sprintf)(filename, "%s", out_file); res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_APPEND, 0); if (!res.isError && out_counter>1) appending = True; @@ -1656,69 +1656,43 @@ void init_cmdbuf(void) } /* - * Set up file names for dump output: base_directory, dump_file_base - * The final filename of a dump is constructed at dump time from - * the PID, thread ID and dump counter. + * Set up file names for dump output: , . + * is derived from the output format string, which defaults + * to "callgrind.out.%p", where %p is replaced with the PID. + * For the final file name, on intermediate dumps a counter is appended, + * and further, if separate dumps per thread are requested, the thread ID. * - * These always will contain a full absolute path. - * If no prefix is given (via option "--base="), the current - * working directory at program start is used, otherwise can - * be relative to cwd or absolute. + * always starts with a full absolute path. + * If the output format string represents a relative path, the current + * working directory at program start is used. */ void CLG_(init_dumps)() { - Int size; + Int lastSlash, i; SysRes res; - if (!CLG_(clo).filename_base) - CLG_(clo).filename_base = DEFAULT_DUMPNAME; + if (!CLG_(clo).out_format) + CLG_(clo).out_format = DEFAULT_OUTFORMAT; - /* get base directory for dump/command/result files */ - if (CLG_(clo).filename_base[0] == '/') { - int lastSlash = 0, i =1; - while(CLG_(clo).filename_base[i]) { - for(; CLG_(clo).filename_base[i] && - CLG_(clo).filename_base[i] != '/'; i++); - if (CLG_(clo).filename_base[i] != '/') break; - lastSlash = i; - i++; - } - i = lastSlash; - base_directory = (Char*) CLG_MALLOC(i+1); - VG_(strncpy)(base_directory, CLG_(clo).filename_base, i); - base_directory[i] = 0; + // Setup output filename. + out_file = + VG_(expand_file_name)("--callgrind-out-file", CLG_(clo).out_format); - dump_file_base = CLG_(clo).filename_base; - } - else { - size = 100; - base_directory = 0; - - /* getcwd() fails if the buffer isn't big enough -- keep doubling size - until it succeeds. */ - while (NULL == base_directory) { - base_directory = CLG_MALLOC(size); - if (!VG_(get_startup_wd)(base_directory, size)) { - VG_(free)(base_directory); - base_directory = 0; - size *= 2; - } - /* in fact, this loop could run forever (or at least till - CLG_MALLOC fails) if VG_(getcwd) returns False for any - reason other than the buffer is too small. So be - safe: */ - tl_assert( size < 100 * 200 ); - } - - size = VG_(strlen)(base_directory) + VG_(strlen)(CLG_(clo).filename_base) +2; - dump_file_base = (Char*) CLG_MALLOC(size); - CLG_ASSERT(dump_file_base != 0); - VG_(sprintf)(dump_file_base, "%s/%s", - base_directory, CLG_(clo).filename_base); + /* get base directory for dump/command/result files */ + CLG_ASSERT(out_file[0] == '/'); + lastSlash = 0; + i = 1; + while(out_file[i]) { + if (out_file[i] == '/') lastSlash = i; + i++; } + i = lastSlash; + out_directory = (Char*) CLG_MALLOC(i+1); + VG_(strncpy)(out_directory, out_file, i); + out_directory[i] = 0; /* allocate space big enough for final filenames */ - filename = (Char*) CLG_MALLOC(VG_(strlen)(dump_file_base)+32); + filename = (Char*) CLG_MALLOC(VG_(strlen)(out_file)+32); CLG_ASSERT(filename != 0); /* Make sure the output base file can be written. @@ -1727,7 +1701,7 @@ void CLG_(init_dumps)() * file: This is probably because of missing rights, * and trace parts wouldn't be allowed to be written, too. */ - VG_(sprintf)(filename, "%s.%d", dump_file_base, VG_(getpid)()); + VG_(strcpy)(filename, out_file); res = VG_(open)(filename, VKI_O_WRONLY|VKI_O_TRUNC, 0); if (res.isError) { res = VG_(open)(filename, VKI_O_CREAT|VKI_O_WRONLY, diff --git a/callgrind/global.h b/callgrind/global.h index 82b1d11629..de510a34a1 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -50,7 +50,7 @@ /*--- Command line options ---*/ /*------------------------------------------------------------*/ -#define DEFAULT_DUMPNAME "callgrind.out" +#define DEFAULT_OUTFORMAT "callgrind.out.%p" #define DEFAULT_COMMANDNAME "callgrind.cmd" #define DEFAULT_RESULTNAME "callgrind.res" #define DEFAULT_INFONAME "/tmp/callgrind.info" @@ -59,7 +59,7 @@ typedef struct _CommandLineOptions CommandLineOptions; struct _CommandLineOptions { /* Dump format options */ - Char* filename_base; /* Base name for dumps */ + Char* out_format; /* Format string for callgrind output file name */ Bool combine_dumps; /* Dump trace parts into same file? */ Bool compress_strings; Bool compress_events; @@ -801,8 +801,8 @@ void CLG_(run_post_signal_on_call_stack_bottom)(void); /* from dump.c */ extern FullCost CLG_(total_cost); void CLG_(init_dumps)(void); -Char* CLG_(get_dump_file_base)(void); -Char* CLG_(get_base_directory)(void); +Char* CLG_(get_out_file)(void); +Char* CLG_(get_out_directory)(void); /*------------------------------------------------------------*/ /*--- Exported global variables ---*/ diff --git a/docs/xml/valgrind-manpage.xml b/docs/xml/valgrind-manpage.xml index 4bf9bb7b04..c30b77ce20 100644 --- a/docs/xml/valgrind-manpage.xml +++ b/docs/xml/valgrind-manpage.xml @@ -210,9 +210,20 @@ leaks. Callgrind Options + + + + -