Counting machine instructions using gdb

Try this:

set pagination off
set $count = 0
while $pc != 0xyourstoppingaddress
  stepi
  set $count++
end
print $count

Then go get a cup of coffee. Or a long lunch.


If you actually want a cycle count (maybe as an approximation of instruction count with known IPC), and you're running on bare metal ARM, you might be able to read the cycle counter, see for example Cycle counter on ARM Cortex M4 (or M3)?


In your scenario, I would try Process Record and Replay to obtain the elapsed instruction count (available since GDB 7.0 and improved afterwards):

  1. Start measurement: record btrace (or record full if the former is not available).
  2. continue execution (until a breakpoint, or use next or other commands to step through).
  3. Obtain measurement: info record
  4. Clear recorded results: record stop (recommended as the buffer is of limited size).

Example:

(gdb) record btrace
(gdb) frame
#0  __sanitizer::InitTlsSize () at .../lib/sanitizer_common/sanitizer_linux_libcdep.cc:220
220       void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
(gdb) info record
Active record target: record-btrace
Recording format: Branch Trace Store.
Buffer size: 64kB.
Recorded 0 instructions in 0 functions (0 gaps) for thread 1 (Thread 0xf7c92300 (LWP 20579)).
(gdb) next
226       ...
(gdb) info record
Active record target: record-btrace
Recording format: Branch Trace Store.
Buffer size: 64kB.
Recorded 2859 instructions in 145 functions (0 gaps) for thread 1 (Thread 0xf7c92300 (LWP 20579)).

Limitations:

  • The record buffer has a limited size (this can be increased with set record btrace pt buffer-size <size> for the BTS format above, see the documentation for other types).
  • With record full, not all instructions can be captured. Notably, SSE and AVX instructions are unsupported and will cause gdb to pause execution.
  • There is some overhead while recording every instruction (especially with the full format). Though it should not be as bad as the gdb step approach described in other answers (which has to go through ptrace every time).

This is actually only a slight improvement of the usability of Mark's solution.

We can define a function do_count:

define do_count
set $count=0
while ($pc != $arg0)
stepi
set $count=$count+1
end
print $count
end

and then this function can be reused for counting the number of steps over and over again:

set pagination off
do_count 0xaddress1
do_count 0xaddress2

One can even put this definition into .gdbinit (on Linux, on Windows it should be called gdb.ini) in the home-folder, so it becomes available automatically after the start of the gdb (use show user to see, whether the function was loaded).

Tags:

X86

Gdb

Trace