Valgrind (original) (raw)

3. Callgrind Format Specification

3. Callgrind Format Specification

This chapter describes the Callgrind Format, Version 1.

The format description is meant for the user to be able to understand the file contents; but more important, it is given for authors of measurement or visualization tools to be able to write and read this format.

3.1. Overview

The profile data format is ASCII based. It is written by Callgrind, and it is upwards compatible to the format used by Cachegrind (ie. Cachegrind uses a subset). It can be read by callgrind_annotate and KCachegrind.

This chapter gives on overview of format features and examples. For detailed syntax, look at the format reference.

3.1.1. Basic Structure

To uniquely specify that a file is a callgrind profile, it should add "# callgrind format" as first line. This is optional but recommended for easy format detection.

Each file has a header part of an arbitrary number of lines of the 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 counters for the events, in the order specified by the "positions" and "events" header line.

The "events" header line is always required in contrast to the optional line for "positions", which defaults to "line", i.e. a line number of some source file. In addition, the second part of the file contains position specifications of the form "spec=name". "spec" can be e.g. "fn" for a function name or "fl" for a file name. Cost lines are always related to the function/file specifications given directly before.

3.1.2. Simple Example

The event names in the following example are quite arbitrary, and are not related to event names used by Callgrind. Especially, cycle counts matching real processors probably will never be generated by any Valgrind tools, as these are bound to simulations of simple machine models for acceptable slowdown. However, any profiling tool could use the format described in this chapter.

callgrind format

events: Cycles Instructions Flops fl=file.f fn=main 15 90 14 2 16 20 12

The above example gives profile information for event types "Cycles", "Instructions", and "Flops". Thus, cost lines give the number of CPU cycles passed by, number of executed instructions, and number of floating point operations executed while running code corresponding to some source position. As there is no line specifying the value of "positions", it defaults to "line", which means that the first number of a cost line is always a line number.

Thus, the first cost line specifies that in line 15 of source filefile.f there is code belonging to functionmain. While running, 90 CPU cycles passed by, and 2 of the 14 instructions executed were floating point operations. Similarly, the next line specifies that there were 12 instructions executed in the context of function main which can be related to line 16 in file file.f, taking 20 CPU cycles. If a cost line specifies less event counts than given in the "events" line, the rest is assumed to be zero. I.e. there was no floating point instruction executed relating to line 16.

Note that regular cost lines always give self (also called exclusive) cost of code at a given position. If you specify multiple cost lines for the same position, these will be summed up. On the other hand, in the example above there is no specification of how many times functionmain actually was called: profile data only contains sums.

3.1.3. Associations

The most important extension to the original format of Cachegrind is the 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 two lines. For calls, the format looks like

calls=(Call Count) (Target position) (Source position) (Inclusive cost of call)

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 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.

Other associations are for example (conditional) jumps. See the reference below for details.

3.1.4. Extended Example

The following example shows 3 functions, main,func1, and func2. Functionmain calls func1 once andfunc2 3 times. func1 callsfunc2 2 times.

callgrind format

events: Instructions

fl=file1.c fn=main 16 20 cfn=func1 calls=1 50 16 400 cfi=file2.c cfn=func2 calls=3 20 16 400

fn=func1 51 100 cfi=file2.c cfn=func2 calls=2 20 51 300

fl=file2.c fn=func2 20 700

One can see that in main only code from line 16 is executed where also the other functions are called. Inclusive cost ofmain is 820, which is the sum of self cost 20 and costs spent in the calls: 400 for the single call to func1and 400 as sum for the three calls to func2.

Function func1 is located infile1.c, the same as main. Therefore, a "cfi=" specification for the call to func1is not needed. The function func1 only consists of code at line 51 of file1.c, where func2is called.

3.1.5. Name Compression

With the introduction of association specifications like calls it is needed to specify the same function or same file name multiple times. As absolute filenames or symbol names in C++ can be quite long, it is advantageous to be able to specify integer IDs for position specifications. Here, the term "position" corresponds to a file name (source or object file) or function name.

To support name compression, a position specification can be not only of the format "spec=name", but also "spec=(ID) name" to specify a mapping of an integer ID to a name, and "spec=(ID)" to reference a previously defined ID mapping. There is a separate ID mapping for each position specification, i.e. you can use ID 1 for both a file name and a symbol name.

With string compression, the example from above looks like this:

callgrind format

events: Instructions

fl=(1) file1.c fn=(1) main 16 20 cfn=(2) func1 calls=1 50 16 400 cfi=(2) file2.c cfn=(3) func2 calls=3 20 16 400

fn=(2) 51 100 cfi=(2) cfn=(3) calls=2 20 51 300

fl=(2) fn=(3) 20 700

As position specifications carry no information themselves, but only change the meaning of subsequent cost lines or associations, they can appear everywhere in the file without any negative consequence. Especially, you can define name compression mappings directly after the header, and before any cost lines. Thus, the above example can also be written as

callgrind format

events: Instructions

define file ID mapping

fl=(1) file1.c fl=(2) file2.c

define function ID mapping

fn=(1) main fn=(2) func1 fn=(3) func2

fl=(1) fn=(1) 16 20 ...

3.1.6. Subposition Compression

If a Callgrind data file should hold costs for each assembler instruction of a program, you specify subposition "instr" in the "positions:" header line, and each cost line has to include the address of some instruction. Addresses are allowed to have a size of 64 bits to support 64-bit architectures. Thus, repeating similar, long addresses for almost every line in the data file can enlarge the file size quite significantly, and motivates for subposition compression: instead of every cost line starting with a 16 character long address, one is allowed to specify relative addresses. This relative specification is not only allowed for instruction addresses, but also for line numbers; both addresses and line numbers are called "subpositions".

A relative subposition always is based on the corresponding subposition of the last cost line, and starts with a "+" to specify a positive difference, a "-" to specify a negative difference, or consists of "*" to specify the same subposition. Because absolute subpositions always are positive (ie. never prefixed by "-"), any relative specification is non-ambiguous; additionally, absolute and relative subposition specifications can be mixed freely. Assume the following example (subpositions can always be specified as hexadecimal numbers, beginning with "0x"):

callgrind format

positions: instr line events: ticks

fn=func 0x80001234 90 1 0x80001237 90 5 0x80001238 91 6

With subposition compression, this looks like

callgrind format

positions: instr line events: ticks

fn=func 0x80001234 90 1 +3 * 5 +1 +1 6

Remark: For assembler annotation to work, instruction addresses have to be corrected to correspond to addresses found in the original binary. I.e. for relocatable shared objects, often a load offset has to be subtracted.

3.1.7. Miscellaneous

3.1.7.1. Cost Summary Information

For the visualization to be able to show cost percentage, a sum of the 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. An import filter may use this to show a progress bar while loading a large data file.

3.1.7.2. Long Names for Event Types and inherited Types

Event types for cost lines are specified in the "events:" line with an abbreviated name. For visualization, it makes sense to be able to specify some longer, more descriptive name. For an event type "Ir" which means "Instruction Fetches", this can be specified the header line

event: Ir : Instruction Fetches events: Ir Dr

In this example, "Dr" itself has no long name associated. The order of "event:" lines and the "events:" line is of no importance. Additionally, inherited event types can be introduced for which no raw data is available, but which are calculated from given types. Suppose the last example, you could add

event: Sum = Ir + Dr

to specify an additional event type "Sum", which is calculated by adding costs for "Ir and "Dr".

3.2. Reference

3.2.1. Grammar

ProfileDataFile := FormatSpec? FormatVersion? Creator? PartData*

FormatSpec := "# callgrind format\n"

FormatVersion := "version: 1\n"

Creator := "creator:" NoNewLineChar* "\n"

PartData := (HeaderLine "\n")+ (BodyLine "\n")+

HeaderLine := (empty line) | ('#' NoNewLineChar*) | PartDetail | Description | EventSpecification | CostLineDef

PartDetail := TargetCommand | TargetID

TargetCommand := "cmd:" Space* NoNewLineChar*

TargetID := ("pid"|"thread"|"part") ":" Space* Number

Description := "desc:" Space* Name Space* ":" NoNewLineChar*

EventSpecification := "event:" Space* Name InheritedDef? LongNameDef?

InheritedDef := "=" InheritedExpr

InheritedExpr := Name | Number Space* ("" Space)? Name | InheritedExpr Space* "+" Space* InheritedExpr

LongNameDef := ":" NoNewLineChar*

CostLineDef := "events:" Space* Name (Space+ Name)* | "positions:" "instr"? (Space+ "line")?

BodyLine := (empty line) | ('#' NoNewLineChar*) | CostLine | PositionSpec | CallSpec | UncondJumpSpec | CondJumpSpec

CostLine := SubPositionList Costs?

SubPositionList := (SubPosition+ Space+)+

SubPosition := Number | "+" Number | "-" Number | "*"

Costs := (Number Space+)+

PositionSpec := Position "=" Space* PositionName

Position := CostPosition | CalledPosition

CostPosition := "ob" | "fl" | "fi" | "fe" | "fn"

CalledPosition := " "cob" | "cfi" | "cfl" | "cfn"

PositionName := ( "(" Number ")" )? (Space* NoNewLineChar* )?

CallSpec := CallLine "\n" CostLine

CallLine := "calls=" Space* Number Space+ SubPositionList

UncondJumpSpec := "jump=" Space* Number Space+ SubPositionList

CondJumpSpec := "jcnd=" Space* Number Space+ Number Space+ SubPositionList

Space := " " | "\t"

Number := HexNumber | (Digit)+

Digit := "0" | ... | "9"

HexNumber := "0x" (Digit | HexChar)+

HexChar := "a" | ... | "f" | "A" | ... | "F"

Name = Alpha (Digit | Alpha)*

Alpha = "a" | ... | "z" | "A" | ... | "Z"

NoNewLineChar := all characters without "\n"

A profile data file ("ProfileDataFile") starts with basic information such as a format marker, the version and creator information, and then has a list of parts, where each part has its own header and body. Parts typically are different threads and/or time spans/phases within a profiled application run.

Note that callgrind_annotate currently only supports profile data files with one part. Callgrind may produce multiple parts for one profile run, but defaults to one output file for each part.

3.2.2. Description of Header Lines

Basic information in the first lines of a profile data file:

The header for each part has an arbitrary number of lines of the format "key: value". Possible key values for the header are:

3.2.3. Description of Body Lines

The regular body line is a cost line consisting of one or two position numbers (depending on "positions:" header line, see above) and an array of cost numbers. A position number either is a line numbers into a source file or an instruction address within binary code, with source/binary file names specified as position names (see below). The cost numbers get mapped to event types in the same order as specified in the "events:" header line. If less numbers than event types are given, the costs default to zero for the remaining event types.

Further, there exist linesspec=position name. A position name is an arbitrary string. If it starts with "(" and a digit, it's a string in compressed format. Otherwise it's the real position string. This allows for file and symbol names as position strings, as these never start with "(" + digit. The compressed format is either "(" number ")"space position or only "(" number ")". The first relates_position_ to number in the context of the given format specification from this line to the end of the file; it makes the (number) an alias for_position_. Compressed format is always optional.

Position specifications allowed:

The last type of body line provides specific costs not just related to one position as regular cost lines. It starts with specific strings similar to position name specifications.