2

Taking the example from http://shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/ - when I use rbreak, I get something like:

(gdb) rb TestFixture.h:.
Breakpoint 1 at 0x4008b6: file TestFixture.h, line 5.
void TestFixture::setUp();
Breakpoint 2 at 0x4008d4: file TestFixture.h, line 6.
void TestFixture::tearDown();
Breakpoint 3 at 0x4008f2: file TestFixture.h, line 7.
void TestFixture::testA();
Breakpoint 4 at 0x400910: file TestFixture.h, line 8.
void TestFixture::testB();
(gdb) info breakpoints
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00000000004008b6 in TestFixture::setUp() at TestFixture.h:5
2       breakpoint     keep y   0x00000000004008d4 in TestFixture::tearDown() at TestFixture.h:6
3       breakpoint     keep y   0x00000000004008f2 in TestFixture::testA() at TestFixture.h:7
4       breakpoint     keep y   0x0000000000400910 in TestFixture::testB() at TestFixture.h:8

Now, what I want is basically a dprintf-like behavior: once one of this breakpoints is hit, I just want the function name printed out, and then continue (basically, a function call trace)

However, the way I understand gdb - in order to do that, I would issue a rbreak [regex] first, then I get a bunch of breakpoints, then for each and every one of those I'd had to type manually:

commands [number-of-breakpoint]
print "[name of function]"
continue
end

... which quickly becomes a chore, especially if you end up with a lot more breakpoints than the 4 in the above example (say hundreds).

Now, it would be rather cool, if I could use something like "regex dprintf", or rdprintf, as in:

rdprintf TestFixture.h:., "%s\n", $__breakname__

... but as far as I know, there is no such command...

Or, if after issuing a rbreak TestFixture.h:., I could target the commands for those breakpoints as:

commands 1-4
print $__breakname__
continue
end

... but again, I think this does not exist either...

So is there a way to use gdb to provide this kind of a function call trace printout - without me manually typing the names of breakpoints and their commands, similar to how rbreak allows you to set multiple breakpoints with one command?


EDIT: just found List of all function calls made in an application - record function-call-history /ilc might be interesting, but there doesn't seem to be a way to limit the scope of what functions to trace, say with a regex...

sdaau
  • 36,975
  • 46
  • 198
  • 278

1 Answers1

1

Ok, via the link above, found https://stackoverflow.com/a/39124320/277826 - turns out, you can issue command for multiple breakpoints, as found by rbreak; and to print the name of the function, just use backtrace 1:

(gdb) command 1-36
Type commands for breakpoint(s) 1-36, one per line.
End with a line saying just "end".
>silent
>bt 1
>continue
>end
(gdb) r

... or with python, printing the frame at bt 0 and its parent's frame name:

command 1-36
silent
python print("{} <- {}".format( gdb.execute("bt 0", False, True).strip(), gdb.newest_frame().older().name() ))
continue
end

... or even better, python printing bt 0 function name and args, and parent name:

command 1-36
silent
python nf = gdb.newest_frame(); nfb = nf.block()
python nfargs = [ "{}={}".format(sym, nf.read_var(sym, nfb)) for sym in nfb if sym.is_argument ]
python print("#0 {}({}) <- {}".format(nf.name(), ",".join(nfargs), nf.older().name() ))
continue
end

... which would print something like:

#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=808) <- FindLiveStrip::GrabToggles
#0 Searcher::FlagFromCmd(this=0x7fffffffaed8,cmd=807) <- FindLiveStrip::ToggleChanged

... and this seems to work fine; though if there are other options, I'd love to know about them.

sdaau
  • 36,975
  • 46
  • 198
  • 278