|
From: <sv...@va...> - 2013-03-04 17:02:44
|
weidendo 2013-03-04 17:02:35 +0000 (Mon, 04 Mar 2013)
New Revision: 13310
Log:
Fix inconsistency between callgrind and format spec
Bug found by, and fix based on a patch by Mark Wielaard
Callgrind format specification was inconsistent with
what Callgrind generates, and what callgrind_annotate
accepted. Now, callgrind_annotate accepts the examples
in the format specification.
* Callgrind writes 'cfi=' lines for when a call target goes
into another source file. According to the spec, 'cfl=' is
used for this. Change the spec to allow both, and change
callgrind_annotate to accept both.
* The spec requires just an "events:" line as minimum header
to render the file as correct according to the specification.
callgrind_annotate also expected a 'cmd=' line. Fixed.
* The 'summary:' line is optional in the spec. Fixed in
callgrind_annotate. If not provided, summary is calculated
from all cost lines.
Modified files:
trunk/callgrind/callgrind_annotate.in
trunk/callgrind/docs/cl-format.xml
Modified: trunk/callgrind/callgrind_annotate.in (+24 -16)
===================================================================
--- trunk/callgrind/callgrind_annotate.in 2013-03-04 11:27:25 +00:00 (rev 13309)
+++ trunk/callgrind/callgrind_annotate.in 2013-03-04 17:02:35 +00:00 (rev 13310)
@@ -81,6 +81,7 @@
# Total counts for summary (an array reference).
my $summary_CC;
my $totals_CC;
+my $summary_calculated = 0;
# Totals for each function, for overall summary.
# hash(filename:fn_name => CC array)
@@ -440,9 +441,6 @@
}
}
- # Check for needed header entries
- ($cmd ne "") or die("Line $.: missing command line\n");
-
# Read "events:" line. We make a temporary hash in which the Nth event's
# value is N, which is useful for handling --show/--sort options below.
($events ne "") or die("Line $.: missing events line\n");
@@ -630,7 +628,7 @@
} elsif (s/^cob=(.*)$//) {
$curr_cobj = uncompressed_name("ob",$1);
- } elsif (s/^cfi=(.*)$//) {
+ } elsif (s/^cf[il]=(.*)$//) {
$curr_cfile = uncompressed_name("fl",$1);
} elsif (s/^cfn=(.*)$//) {
@@ -681,15 +679,6 @@
}
}
- if ((not defined $summary_CC) || is_zero($summary_CC)) {
- $summary_CC = $totals_CC;
- }
-
- # Check if summary line was present
- if (not defined $summary_CC) {
- warn("WARNING: missing final summary line, no summary will be printed\n");
- }
-
# Finish up handling final filename/fn_name counts
$fn_totals{"$curr_file:$curr_fn"} = $curr_fn_CC
if (defined $curr_file && defined $curr_fn);
@@ -704,6 +693,20 @@
}
close(INPUTFILE);
+
+ if ((not defined $summary_CC) || is_zero($summary_CC)) {
+ $summary_CC = $totals_CC;
+
+ # if neither 'summary:' nor 'totals:' line is given,
+ # calculate summary from fn_totals hash
+ if ((not defined $summary_CC) || is_zero($summary_CC)) {
+ $summary_calculated = 1;
+ $summary_CC = [];
+ foreach my $name (keys %fn_totals) {
+ add_array_a_to_b($fn_totals{$name}, $summary_CC);
+ }
+ }
+ }
}
#-----------------------------------------------------------------------------
@@ -719,6 +722,7 @@
print($fancy);
print($desc);
my $target = $cmd;
+ if ($target eq "") { $target = "(unknown)"; }
if ($pid ne "") {
$target .= " (PID $pid";
if ($part ne "") { $target .= ", part $part"; }
@@ -855,8 +859,11 @@
print("\n");
print($fancy);
print_CC($summary_CC, $summary_CC_col_widths);
- print(" PROGRAM TOTALS\n");
- print("\n");
+ print(" PROGRAM TOTALS");
+ if ($summary_calculated) {
+ print(" (calculated)");
+ }
+ print("\n\n");
# Header for functions
print($fancy);
@@ -921,7 +928,8 @@
print_CC($fn_CC, $fn_CC_col_widths);
if ($tree_caller || $tree_calling) { print " * "; }
print(" $fn_name");
- if (defined $obj_name{$fn_name}) {
+ if ((defined $obj_name{$fn_name}) &&
+ ($obj_name{$fn_name} ne "")) {
print " [$obj_name{$fn_name}]";
}
print "\n";
Modified: trunk/callgrind/docs/cl-format.xml (+37 -24)
===================================================================
--- trunk/callgrind/docs/cl-format.xml 2013-03-04 11:27:25 +00:00 (rev 13309)
+++ trunk/callgrind/docs/cl-format.xml 2013-03-04 17:02:35 +00:00 (rev 13310)
@@ -30,7 +30,9 @@
<title>Basic Structure</title>
<para>Each file has a header part of an arbitrary number of lines of the
-format "key: value". The lines with key "positions" and "events" define
+format "key: value". After the header, lines specifying profile costs
+follow. Everywhere, comments on own lines starting with '#' are allowed.
+The header lines with keys "positions" and "events" define
the meaning of cost lines in the second part of the file: the value of
"positions" is a list of subpositions, and the value of "events" is a list
of event type names. Cost lines consist of subpositions followed by 64-bit
@@ -98,8 +100,8 @@
ability to specify call relationship among functions. More generally, you
specify associations among positions. For this, the second part of the
file also can contain association specifications. These look similar to
-position specifications, but consist of 2 lines. For calls, the format
-looks like
+position specifications, but consist of two lines. For calls, the format
+looks like
<screen>
calls=(Call Count) (Destination position)
(Source position) (Inclusive cost of call)
@@ -108,8 +110,10 @@
<para>The destination only specifies subpositions like line number. Therefore,
to be able to specify a call to another function in another source file, you
have to precede the above lines with a "cfn=" specification for the name of the
-called function, and a "cfl=" specification if the function is in another
-source file. The 2nd line looks like a regular cost line with the difference
+called function, and optionally a "cfi=" specification if the function is in
+another source file ("cfl=" is an alternative specification for "cfi=" because
+of historical reasons, and both should be supported by format readers).
+The second line looks like a regular cost line with the difference
that inclusive cost spent inside of the function call has to be specified.</para>
<para>Other associations are for example (conditional) jumps. See the
@@ -134,14 +138,14 @@
cfn=func1
calls=1 50
16 400
-cfl=file2.c
+cfi=file2.c
cfn=func2
calls=3 20
16 400
fn=func1
51 100
-cfl=file2.c
+cfi=file2.c
cfn=func2
calls=2 20
51 300
@@ -158,7 +162,7 @@
<para>Function <function>func1</function> is located in
<filename>file1.c</filename>, the same as <function>main</function>.
-Therefore, a "cfl=" specification for the call to <function>func1</function>
+Therefore, a "cfi=" specification for the call to <function>func1</function>
is not needed. The function <function>func1</function> only consists of code
at line 51 of <filename>file1.c</filename>, where <function>func2</function>
is called.</para>
@@ -191,14 +195,14 @@
cfn=(2) func1
calls=1 50
16 400
-cfl=(2) file2.c
+cfi=(2) file2.c
cfn=(3) func2
calls=3 20
16 400
fn=(2)
51 100
-cfl=(2)
+cfi=(2)
cfn=(3)
calls=2 20
51 300
@@ -286,8 +290,8 @@
cost of the full run has to be known. Usually, it is assumed that this is the
sum of all cost lines in a file. But sometimes, this is not correct. Thus, you
can specify a "summary:" line in the header giving the full cost for the
-profile run. This has another effect: a import filter can show a progress bar
-while loading a large data file if he knows to cost sum in advance.</para>
+profile run. An import filter may use this to show a progress bar
+while loading a large data file.</para>
</sect3>
@@ -356,7 +360,7 @@
<screen>PositionSpecification := Position "=" Space* PositionName</screen>
<screen>Position := CostPosition | CalledPosition</screen>
<screen>CostPosition := "ob" | "fl" | "fi" | "fe" | "fn"</screen>
-<screen>CalledPosition := " "cob" | "cfl" | "cfn"</screen>
+<screen>CalledPosition := " "cob" | "cfi" | "cfl" | "cfn"</screen>
<screen>PositionName := ( "(" Number ")" )? (Space* NoNewLineChar* )?</screen>
<screen>AssociationSpecification := CallSpecification
| JumpSpecification</screen>
@@ -388,24 +392,24 @@
<para>This is used to distinguish future profile data formats. A
major version of 0 or 1 is supposed to be upwards compatible with
Cachegrind's format. It is optional; if not appearing, version 1
- is supposed. Otherwise, this has to be the first header line.</para>
+ is assumed. Otherwise, this has to be the first header line.</para>
</listitem>
<listitem>
<para><computeroutput>pid: process id</computeroutput> [Callgrind]</para>
- <para>This specifies the process ID of the supervised application
+ <para>Optional. This specifies the process ID of the supervised application
for which this profile was generated.</para>
</listitem>
<listitem>
<para><computeroutput>cmd: program name + args</computeroutput> [Cachegrind]</para>
- <para>This specifies the full command line of the supervised
+ <para>Optional. This specifies the full command line of the supervised
application for which this profile was generated.</para>
</listitem>
<listitem>
<para><computeroutput>part: number</computeroutput> [Callgrind]</para>
- <para>This specifies a sequentially incremented number for each dump
+ <para>Optional. This specifies a sequentially incremented number for each dump
generated, starting at 1.</para>
</listitem>
@@ -468,13 +472,16 @@
<listitem>
<para><computeroutput>summary: costs</computeroutput> [Callgrind]</para>
+ <para>Optional. This header line specifies a summary cost, which should be
+ equal or larger than a total over all self costs. It may be larger as
+ the cost lines may not represent all cost of the program run.</para>
+ </listitem>
+
+ <listitem>
<para><computeroutput>totals: costs</computeroutput> [Cachegrind]</para>
- <para>The value or the total number of events covered by this trace
- file. Both keys have the same meaning, but the "totals:" line
- happens to be at the end of the file, while "summary:" appears in
- the header. This was added to allow postprocessing tools to know
- in advance to total cost. The two lines always give the same cost
- counts.</para>
+ <para>Optional. Should appear at the end of the file (although
+ looking like a header line). Must give the total of all cost lines,
+ to allow for a consistency check.</para>
</listitem>
</itemizedlist>
@@ -534,12 +541,18 @@
</listitem>
<listitem>
- <para><computeroutput>cfl=</computeroutput> [Callgrind]</para>
+ <para><computeroutput>cfi=</computeroutput> [Callgrind]</para>
<para>The source file including the code of the target of the
next call cost lines.</para>
</listitem>
<listitem>
+ <para><computeroutput>cfl=</computeroutput> [Callgrind]</para>
+ <para>Alternative spelling for <computeroutput>cfi=</computeroutput>
+ specification (because of historical reasons).</para>
+ </listitem>
+
+ <listitem>
<para><computeroutput>cfn=</computeroutput> [Callgrind]</para>
<para>The name of the target function of the next call cost
lines.</para>
|