15. Valgrind-itrace: The Instruction Trace tool

A tool that trace instructions and memory accesses.

Table of Contents

15.1. Instruction Trace
15.1.1. Instruction Tracer
15.1.2. Memory Tracer
15.2. Instruction Trace Howto
15.2.1. Valgrind-itrace invoking and options
15.2.2. Instruction Trace Text Output Format
15.2.3. Instruction Trace Output Example

15.1. Instruction Trace

For help in using this tool, specify --tool=itrace --help on the Valgrind command line.

Itrace is a simple tool to output a trace of the instructions executed by the processor. Instruction traces can be used by subsequent, architecture-specific tools to look for problematic code sequences, to find misaligned memory access, for calculating cycle counts (often complex as processors develop deeper and more sophisticated pipelines), to determine structural coverage on an object-code basis, or for analyzing sub-optimal sequences and mis-optimizations in executing instruction streams.

Valgrind-itrace is a tool for tracing instructions and memory accesses and recording all the executed guest instructions and memory addresses. In particular, it records:

  • Instruction address and content;

  • Load and Store operation;

  • Run-time data and address for memory access.

15.1.1. Instruction Tracer

Trace all executed instructions.

15.1.2. Memory Tracer

Trace every memory access -- i.e., in text-formatted output, you would see records like R/W/M >address< >data<.

15.2. Instruction Trace Howto

15.2.1. Valgrind-itrace invoking and options

Some common options for valgrind-itrace are listed as follows:

  • --fnname=<fnuction-name>: Use this option to specify the function of interest for tracing. The default <fnuction-name> is _dl_runtime_resolve().
  • --trace-extent=calltree|function|all: This option specifies whether to trace the entire program (all); just the instructions in the function specified by --fnname (function), or all instructions from entry into the function until the function returns (calltree). The default is calltree.
  • --trace-instrs=yes|no: This option (default is 'yes') traces all executed instructions. Specifying 'no' does everything except writing out trace records. It's mainly used for debugging purposes.
  • --trace-mem=yes|no: This option records the size and address of almost every load and store made by the program. The default is "yes".
  • --readable=no|yes: Specifying --readable=no results in a binary-formatted trace, written to the file itrace_out.vgi. Specifying --readable=yes produces human readable text-formatted trace output, written to stdout. This option can sometimes be helpful in order to easily see the instructions being traced. Binary output is the default (--readable=no) as it is much faster (~300x) than producing text-formatted output.
  • --binary-outfile=<filename>: Name of binary output file where trace data is to be stored (used with --readable=no ). If not specified, the default output filename is itrace_out.vgi.

The Next three options can be used independently or in any combination.

  • --num-insns-before-start: Number of instructions to skip (in given fnname) before tracing starts.
  • --num-func-calls-before-start: Number of times the given fnname is called before tracing starts.
  • --num-K-insns-to-collect: Total number of k-instructions (units in 1,000's of instructions) to record.

15.2.2. Instruction Trace Text Output Format

  • H valgrind-itrace

    Indicates the start of the trace, possibly with additional data in no specific format.

  • J aaaa xxxx [; symbol]

    Instruction-with-address record. aaaa is the address of the instruction, xxxx is a byte dump of the instruction itself. All values are in hex. A symbol name associated with the address may be provided, if instruction on this address is the first instruction of the function or symbol. Note that "J" does not imply that a branch occurred, it merely indicates that the record includes the address of the instruction executed.

  • I xxxx

    Instruction record for an instruction that immediately follows the previous instruction. The address can be determined from the length of the preceding instruction.

  • G

    Indicates a gap in the trace. This will happen, for instance, when valgrind simulates an int 80 (on x86) or sc (on ppc) instruction, or when a branch occurs to code not being traced.

  • R aaaaaaaa rrrr

    W aaaaaaaa wwwwwwww

    M aaaaaaaa mmmmmmmm

    Indicates that the previous instruction caused a read of the bytes rrrr, or a write of bytes wwwwwwwww, or a modify of bytes mmmmmmmm, at address aaaaaaaa. The length of the read, write or modify is indicated by the number of bytes shown. R and W records occur in order.

    Modify means load and store data at the same address, for example, incl (%ecx) on x86, this instruction modifies (%ecx).

    load/store means load and store data at different address, for example, pushl (%edx) on x86, this instruction loads (%edx), and store -4(%esp). There are both R and W record after I record.

15.2.3. Instruction Trace Output Example

Here is an example of text output when valgrind-itrace trace itrace/tests/hello_world:

[qiyao@GreenHouse valgrind-3.2.0-itrace]$ valgrind --tool=itrace --tool=itrace --fnname=main --trace-extent=function --readable=yes ./itrace/tests/read_twice

==25514== valgrind-itrace, Instruction and memory tracer..
==25514== Copyright (C) 2002-2006, and GNU GPL'd
==25514== Using LibVEX rev 1606, a library for dynamic binary translation.
==25514== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==25514== Using valgrind-3.2.0, a dynamic binary instrumentation framework.
==25514== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==25514== For more details, rerun with: -v
==25514==
H valgrind-itrace
G
J 0x100004CC FBE1FFF8 ;main
W 0x7FF0004F8 000000800139EB48
I F821FFB1
W 0x7FF0004B0 00000007FF000500
I 7C3F0B78
I 38000000
I 901F0030
W 0x7FF0004E0 00000000
I 801F0030
R 0x7FF0004E0 00000000
I 901F0034
W 0x7FF0004E4 00000000
I 38000001
I 901F0030
W 0x7FF0004E0 00000001
I 801F0030
R 0x7FF0004E0 00000001
I 901F0034
W 0x7FF0004E4 00000001
I 38000000
I 7C030378
I E8210000
R 0x7FF0004B0 00000007FF000500
I EBE1FFF8
R 0x7FF0004F8 000000800139EB48
I 4E800020
==25514==
==25514==