繁体   English   中英

如何在所有模板 function 实例化中的 label 上设置 gdb 断点

[英]How to set a gdb breakpoint on a label in all template function instantiations

假设我有以下 C++:

template <int I> int bar(int i) {
  ++i;
label1:
  return I * i;
}
int main(int argc, char **) { return bar<2>(argc); }

是否可以在label1上为 bar 的所有实例设置 gdb 断点? 在上面,这很容易——只有一个实例化。 在我的实际用例中,有大量分布在代码库中。

换句话说,在我的 gdb 命令文件中,有没有办法避免需要先验地了解 bar 的每个模板实例化? 在我的实际用例中,我的目标是在标签处发出一些关于程序 state 的信息(不用担心,没有程序受到goto的伤害)。

我知道我可以在 label 上为bar的特定实例设置断点,如下所示:

break -function bar<2> -label label1

我也知道rbreak可以用来中断所有模板函数的入口,但显然没有-label选项。 我不想打破入口点——只是标签。 我还查看了是否可以将rbreakuntil label1结合使用,但这没有用。

我考虑过的另外两种方法是:

  1. grep 用于标签(或者甚至可能只是特殊形成的注释),发出行号并使用此信息来填充/生成我的 gdb 命令文件,其中包含源文件和行号断点。 这肯定会起作用,但有点希望避免“生成”我的命令文件的需要。
  2. 由于我打算实现一些 gdb Python 漂亮的打印机,也许我可以从 python 中解析源代码以获取行号并随后设置断点。 I'm just learning the Python API and it wasn't immediately obvious how to get the equivalent of list from within the gdb python package.

有什么建议么?

这个答案显示了如何迭代程序中的所有全局符号。

对于您的测试程序,它产生:

bar<2>(int) True
main(int, char**) True

从这里,您可以轻松找到bar<>()的所有实例,并使用Python 断点 API在它们上设置断点。

(gdb) py
>gdb.Breakpoint(function='bar<2>(int)', label='label1')
Breakpoint 1 at 0x1158: file t.cc, line 3.

使用function='bar<2>'也可以。

根据Employed Russian 的建议,我想出了以下 gdb python 脚本:

import re


class Custombreakpoint(gdb.Breakpoint):
    def __init__(self, function, label):
        super().__init__(function=function, label=label, internal=True)

    def stop(self):
        I = gdb.parse_and_eval("I")
        i = gdb.parse_and_eval("i")
        print(f"I = {I}, i = {i}")
        return False

pattern = re.compile('.*foo.*')
for sym in gdb.lookup_global_symbol('main').symtab.global_block():
    if sym.is_function:
        match = pattern.search(sym.name)
        if match:
            Custombreakpoint(function=match.string, label='label1')

gdb.execute('run')
gdb.execute('quit')

这会产生以下 output:

$ g++ -g ./test.cc && gdb --command=test.py ./a.out                                                                                                                                      
Reading symbols from ./a.out...                                                                                                                                                                                      
I = 2, i = 2                                                                                                                                                                                                         
I = 3, i = 2                                                                                                                                                                                                         
[Inferior 1 (process 17224) exited with code 012]

这将使我能够在我的实际用例中准确地做我想做的事情。 谢谢您的帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM