Reputation: 22650
Is there a way, to record the execution of a particular function (or the entire program) in terms of the executed source code lines?
Consdier I set a breakpoint in gdb
to function foo
, and then repetedly call step
, and it will tell me something like this:
(gdb) break foo
Thread 1 "main" hit Breakpoint 1, foo () at foo.cpp:10
(gdb) step
foo () at foo.cpp:12
(gdb) step
foo () at foo.cpp:13
(gdb) step
foo () at foo.cpp:12
(gdb) step
foo () at foo.cpp:14
Then I repeat that until foo
is no longer in the output of bt
. This gives me a trace of execution (foo.cpp:10->12->13->12->14), that is particularly useful to compare long control flows.
Is there a way to do this with gdb
or is there another tool that does this? I am only interested in deterministic traces, not sampling. Ideally this could also be done for stepi
(on instruction level) / next
(without entering subroutines).
Upvotes: 3
Views: 855
Reputation: 22650
Based on this similar question, I was able to put together a quick python script for my purpose. Fortunately with less required bug-workarounds:
import sys
import gdb
import os
import re
def in_frames(needle):
""" Check if the passed frame is still on the current stack """
hay = gdb.newest_frame()
while hay:
if hay == needle:
return True
hay = hay.older()
return False
# Use this to reduce any kind of unwanted noise
def filter_step(output):
output = re.sub(r'^.*No such file or directory\.\n', r'', output, flags=re.M)
output = re.sub(r'^\d+\s+in\s+.*\n', r'', output, flags=re.M)
return output
def step_trace(filename=None, step="step"):
counter = 0
if filename:
output = ""
frame = gdb.newest_frame()
print("Stepping until end of {} @ {}:{}".format(frame.name(), frame.function().symtab, frame.function().line))
while in_frames(frame):
counter += 1
if filename:
output += filter_step(gdb.execute(step, to_string=True))
else:
gdb.execute(step)
if filename:
with open(filename, "w") as file:
file.write(output)
print("Done stepping through {} lines.".format(counter))
To output a trace to a file
(gdb) source step_trace.py
(gdb) python step_trace("filename.log")
or directly
(gdb) source step_trace.py
(gdb) python step_trace()
Upvotes: 4