GDB 断点不命中模板函数

Cut*_*son 5 c++ templates gdb breakpoints

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

  1. break fileName:functionName => 适用于非模板化函数(特定于一个函数)
  2. rbreak 文件名:. => 在给定文件中的所有函数处设置断点,但它似乎不适用于模板函数
  3. 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
Run Code Online (Sandbox Code Playgroud)
  • 一种选择是使用 rbreak filename:.
  • 运行代码一次,并且
  • 再次运行代码而不退出 GDB。这次它识别了函数和断点工作。

您能否帮忙提出一个正确的解决方案,或者如果我遗漏了什么,请告诉我?任何帮助/建议都将受到高度赞赏,并大大简化我的调试。

预先非常感谢!

dar*_*amo 11

问题很可能是您尝试在 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;
}
Run Code Online (Sandbox Code Playgroud)

当我们编译它并在 gdb 中调试时,gdb 将看到三个函数(除了main):tripleInputdoubleInput<int>doubleInput<double>。如果你用gdb编写,函数break tripleInput中会添加断点tripleInput,但如果你只写break doubleInputgdb,会说函数未定义。

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

我不知道是否可以做诸如 之类的事情break doubleInput<*>,但从文档中看,这似乎不可能。


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


编辑

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

rbreak doubleInput*
Run Code Online (Sandbox Code Playgroud)

甚至在文件中的所有函数中

rbreak main.cpp:.*
Run Code Online (Sandbox Code Playgroud)