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
):tripleInput
、doubleInput<int>
和 doubleInput<double>
。如果您在 gdb 中写入 break tripleInput
,则会在 tripleInput
函数中添加断点,但如果您只编写 break doubleInput
,则 gdb 会说该函数未定义。
您需要编写break doubleInput<int>
或break doubleInput<double>
,但请注意,像这样添加断点只会在模板的特定实例中停止。这与在模板中的一行添加断点不同。在这种情况下,gdb 实际上添加了一个带有多个位置的断点。在使用这两种方法创建断点后尝试info breakpoints
以查看不同之处。
我不知道是否可以执行 break doubleInput<*>
之类的操作,但从文档中查看似乎是不可能的。
提示:在 gdb 部分中,TAB 将完成函数名称,包括模板实例。
编辑
我完全忘记了rbreak
。它可以在所有匹配正则表达式的函数上设置断点。这意味着我们可以轻松地在所有函数模板实例中添加断点
rbreak doubleInput*
甚至在一个文件中的所有函数中都带有
rbreak main.cpp:.*
【讨论】:
是否可以在给定文件中的所有函数(模板函数和非模板函数)处设置断点。如果我们有很多函数,那么通过 GDB 为每个函数编写一个 break doubleInputrbreak
命令向模板的所有实例以及文件中的所有函数等添加断点。我已经编辑了答案。
我认为最后一个例子忘记了.
(所以它也会匹配doubleInpu
和doubleInputttt
,它是一个正则表达式)
其实我试过rbreak,不行,以后再解决。以上是关于GDB 断点不会命中模板函数的主要内容,如果未能解决你的问题,请参考以下文章
"当前不会命中断点,没有与此行关联的可执行代码"可能和"断点位置不准确"有关