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;
{
VG_(printf)(
"\n dump creation options:\n"
-" --base=<prefix> Prefix for profile files [" DEFAULT_DUMPNAME "]\n"
+" --callgrind-out-file=<f> 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"
/* 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;
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;
{
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;
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);
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");
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));
</para>
<para>After program termination, a profile data file named
- <computeroutput>callgrind.out.pid</computeroutput>
+ <computeroutput>callgrind.out.<pid></computeroutput>
is generated, where <emphasis>pid</emphasis> is the process ID
of the program being profiled.
The data file contains information about the calls made in the
<para>To generate a function-by-function summary from the profile
data file, use
- <screen>callgrind_annotate [options] callgrind.out.pid</screen>
+ <screen>callgrind_annotate [options] callgrind.out.<pid></screen>
This summary is similar to the output you get from a Cachegrind
run with <computeroutput>cg_annotate</computeroutput>: the list
of functions is ordered by exclusive cost of functions, which also
xreflabel="Miscellaneous options">
<title>Miscellaneous options</title>
-<variablelist id="cmd-options.misc">
+<variablelist id="cl.opts.list.misc">
<varlistentry>
<term><option>--help</option></term>
These options influence the name and format of the profile data files.
</para>
-<variablelist id="cmd-options.creation">
+<variablelist id="cl.opts.list.creation">
- <varlistentry id="opt.base">
+ <varlistentry id="opt.callgrind-out-file" xreflabel="--callgrind-out-file">
<term>
- <option><![CDATA[--base=<prefix> [default: callgrind.out] ]]></option>
+ <option><![CDATA[--callgrind-out-file=<file> ]]></option>
</term>
<listitem>
- <para>Specify the base name for the dump file names. To
- distinguish different profile runs of the same application,
- <computeroutput>.<pid></computeroutput> is appended to the
- base dump file name with
- <computeroutput><pid></computeroutput> being the process ID
- of the profiled program. When multiple dumps are made, the file name
- is modified further; see below.</para>
- <para>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.</para>
+ <para>Write the profile data to
+ <computeroutput>file</computeroutput> rather than to the default
+ output file,
+ <computeroutput>callgrind.out.<pid></computeroutput>. The
+ <option>%p</option> and <option>%q</option> 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 <option>--log-file</option>. See <link
+ linkend="manual-core.basicopts">here</link> for details.
+ When multiple dumps are made, the file name
+ is modified further; see below.</para>
</listitem>
</varlistentry>
<computeroutput>callgrind_control</computeroutput>.
</para>
-<variablelist id="cmd-options.activity">
+<variablelist id="cl.opts.list.activity">
<varlistentry id="opt.dump-every-bb" xreflabel="--dump-every-bb">
<term>
These options specify when events are to be aggregated into event counts.
Also see <xref linkend="cl-manual.limits"/>.</para>
-<variablelist id="cmd-options.collection">
+<variablelist id="cl.opts.list.collection">
<varlistentry id="opt.instr-atstart" xreflabel="--instr-atstart">
<term>
xreflabel="Cache simulation options">
<title>Cache simulation options</title>
-<variablelist id="cmd-options.simulation">
+<variablelist id="cl.opts.list.simulation">
<varlistentry id="opt.simulate-cache" xreflabel="--simulate-cache">
<term>
only instruction read accesses will be profiled.</para>
</listitem>
</varlistentry>
-
+
+ <varlistentry id="opt.simulate-hwpref" xreflabel="--simulate-hwpref">
+ <term>
+ <option><![CDATA[--simulate-hwpref=<yes|no> [default: no] ]]></option>
+ </term>
+ <listitem>
+ <para>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.</para>
+ </listitem>
+ </varlistentry>
+
</variablelist>
</sect2>
<refnamediv id="a-name">
<refname>callgrind_annotate</refname>
<refpurpose>produces human readable ASCII output from profile
- information in <command>cachegrind.out</command> files</refpurpose>
+ information in <command>callgrind.out.<pid></command> files</refpurpose>
</refnamediv>
<refsynopsisdiv id="a-synopsis">
program run, optionally separately for every thread in the case of
multithreaded code. For interactive inspection and control, see
<command>callgrind_control</command>. The data produced
-(callgrind.out.PID) can be analysed with
+(callgrind.out.<pid>) can be analysed with
<command>callgrind_annotate</command> or better with the graphical profile
visualization <command>KCachegrind</command>. Further documentation can
be found in HTML format either on your filesystem:
/* 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 */
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;
}
/*------------------------------------------------------------*/
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);
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;
}
/*
- * 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: <out_directory>, <out_file>.
+ * <out_file> 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=<prefix>"), the current
- * working directory at program start is used, otherwise <prefix> can
- * be relative to cwd or absolute.
+ * <out_file> 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.
* 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,
/*--- 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"
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;
/* 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 ---*/
<title>Callgrind Options</title>
<xi:include href="../../callgrind/docs/cl-manual.xml"
- xpointer="cl.opts.list"
+ xpointer="cl.opts.list.misc"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+<xi:include href="../../callgrind/docs/cl-manual.xml"
+ xpointer="cl.opts.list.creation"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+<xi:include href="../../callgrind/docs/cl-manual.xml"
+ xpointer="cl.opts.list.activity"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+<xi:include href="../../callgrind/docs/cl-manual.xml"
+ xpointer="cl.opts.list.collection"
+ xmlns:xi="http://www.w3.org/2001/XInclude" />
+<xi:include href="../../callgrind/docs/cl-manual.xml"
+ xpointer="cl.opts.list.simulation"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
</refsect1>