gdb rbreak和命令(或dprintf行为)?


gdb rbreak and commands (or dprintf behavior)?

以http://shanekirk.com/2017/08/gdb-tips-and-tricks-2-setting-breakpoints-with-regular-expressions/中的示例为例-当我使用rbreak时,得到的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(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

现在,我想要的基本上是类似于dprintf的行为:击中其中一个断点后,我只想打印出函数名称,然后先打印出continue(基本上是函数调用跟踪)

但是,按照我理解gdb的方式-为了做到这一点,我将首先发出rbreak [regex],然后得到一堆断点,然后为每个必须手动键入的断点:

1
2
3
4
commands [number-of-breakpoint]
print"[name of function]"
continue
end

...这很快就变得很繁琐,尤其是如果您遇到的断点比上面示例中的4个断点多(例如数百个)。

现在,如果我可以使用" regex dprintf"或rdprintf之类的东西,那就太酷了:

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

...但是据我所知,没有这样的命令...

或者,如果发出rbreak TestFixture.h:.之后,我可以将这些断点的commands定位为:

1
2
3
4
commands 1-4
print $__breakname__
continue
end

...但是再次,我认为这也不存在...

因此,有没有一种方法可以使用gdb提供这种功能调用跟踪打印输出-无需我手动输入断点名称及其命令,就像rbreak允许您使用一个命令设置多个断点一样?

编辑:刚刚发现在应用程序中进行的所有函数调用的列表-record function-call-history /ilc可能很有趣,但是似乎没有一种方法可以限制要跟踪的函数的范围,例如使用正则表达式...


好的,可以通过上面的链接找到https://stackoverflow.com/a/39124320/277826-事实证明,您可以为rbreak找到的多个断点发出command; 并打印功能名称,只需使用backtrace 1

1
2
3
4
5
6
7
8
(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

...或使用python,在bt 0处打印框架及其父框架的名称:

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

...甚至更好,python打印bt 0函数名称和参数,以及父名称:

1
2
3
4
5
6
7
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

...它会打印类似:

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

...这似乎很好用; 不过,如果还有其他选择,我很想知道。