GDB 断点不会命中模板函数

Posted

技术标签:

【中文标题】GDB 断点不会命中模板函数【英文标题】:GDB breakpoints do not hit template functions 【发布时间】:2020-05-04 20:13:28 【问题描述】:

我正在尝试通过 GDB 在 C++ 中的模板函数中设置断点 我尝试了三种可能的方法。

    break fileName:functionName => 适用于非模板 函数(特定于一个函数) rbreak 文件名:。 => 给定文件中所有函数的断点,但似乎没有 为模板函数工作 break fileName:lineNumber => 适用于非模板函数和模板函数,但有问题 对我来说,我每次都必须修改这个行号。

总体目标是使用如下脚本通过 GDB 跟踪完整的代码流,但我的代码也有很多模板函数。 下面是示例 GDB 脚本

set logging on
b func2
commands
silent
bt 1
continue
end
b func1
commands
silent
bt 1
set logging off
continue
end
一种选择是使用 rbreak 文件名:。 运行一次代码,然后 在不退出 GDB 的情况下再次运行代码。这一次它认 函数和断点有效。

您能否帮助提出一个合适的解决方案,或者如果我遗漏了什么,请告诉我? 任何帮助/建议都非常感谢,并大大简化了我的调试。

提前非常感谢!!

【问题讨论】:

另见:debug c++ template with gdb - Stack Overflow 【参考方案1】:

问题很可能是您尝试在 gdb 中设置断点时使用的函数名。

gdb 使用的函数名不是源文件中的,而是二进制文件中的。模板函数实际上不是函数。它们只是“配方”,当您使用模板实际编译代码时,编译器将使用该配方为您实现一个功能(一个用于您实际使用的模板参数组合)。

考虑下面的代码

#include <iostream>

double tripleInput(double x)  return 3 * x; 

template <typename T>
inline T doubleInput(const T& x) 
    return 2 * x;



int main(int argc, char *argv[])

    std::cout << doubleInput(13) << std::endl;
    std::cout << doubleInput(1.72) << std::endl;

    std::cout << tripleInput(1.72) << std::endl;
    return 0;

当我们在 gdb 中编译和调试时,gdb 会看到三个函数(除了main):tripleInputdoubleInput&lt;int&gt;doubleInput&lt;double&gt;。如果您在 gdb 中写入 break tripleInput,则会在 tripleInput 函数中添加断点,但如果您只编写 break doubleInput,则 gdb 会说该函数未定义。

您需要编写break doubleInput&lt;int&gt;break doubleInput&lt;double&gt;,但请注意,像这样添加断点只会在模板的特定实例中停止。这与在模板中的一行添加断点不同。在这种情况下,gdb 实际上添加了一个带有多个位置的断点。在使用这两种方法创建断点后尝试info breakpoints 以查看不同之处。

我不知道是否可以执行 break doubleInput&lt;*&gt; 之类的操作,但从文档中查看似乎是不可能的。


提示:在 gdb 部分中,TAB 将完成函数名称,包括模板实例。


编辑

我完全忘记了rbreak。它可以在所有匹配正则表达式的函数上设置断点。这意味着我们可以轻松地在所有函数模板实例中添加断点

rbreak doubleInput*

甚至在一个文件中的所有函数中都带有

rbreak main.cpp:.*

【讨论】:

是否可以在给定文件中的所有函数(模板函数和非模板函数)处设置断点。如果我们有很多函数,那么通过 GDB 为每个函数编写一个 break doubleInput 指令会很麻烦。 事实证明,gdb 不仅可以使用rbreak 命令向模板的所有实例以及文件中的所有函数等添加断点。我已经编辑了答案。 我认为最后一个例子忘记了.(所以它也会匹配doubleInpudoubleInputttt,它是一个正则表达式) 其实我试过rbreak,不行,以后再解决。

以上是关于GDB 断点不会命中模板函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 GDB 调试模板

这是 ubuntu 16.04 中的 gdb 错误吗?

"当前不会命中断点,没有与此行关联的可执行代码"可能和"断点位置不准确"有关

成员函数的 C++ GDB 断点

使用 Netbeans/gdb 调试 C 会立即以 SIGSEGV 终止?

GDB 在函数结束处中断而不是指定断点