GDB 断点无法触发模板函数

5

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

  1. break fileName:functionName => 对于非模板函数(特定于一个函数),此方法有效。
  2. rbreak fileName:. => 在给定文件中所有函数处设置断点,但似乎对于模板函数无效。
  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
  • 一种选择是使用rbreak filename:。
  • 运行一次代码,然后
  • 不退出GDB再次运行代码。这次它会识别函数并使断点生效。

请帮忙提供一个合适的解决方案,或者让我知道是否有遗漏的地方吗? 非常感谢任何帮助/建议,这将大大简化我的调试过程。

先行致谢!


2个回答

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;
}

当我们编译并在gdb中调试时,除了main函数外,gdb将看到三个其他的函数:tripleInputdoubleInput<int>doubleInput<double>。如果您在gdb中输入break tripleInput,则会在tripleInput函数中添加断点,但是如果您只写break doubleInput,gdb会说该函数未定义。

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

我不知道是否可能执行break doubleInput<*>这样的操作,但从文档中查看,似乎不可能。


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


编辑

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

rbreak doubleInput*

或者甚至是文件中所有函数都采用

rbreak main.cpp:.*

能否在一个给定的文件中在所有函数(模板函数和非模板函数)上设置断点?如果有很多函数,那么通过GDB为每个函数编写break doubleInput<double>指令将会很麻烦。 - CutePoison
原来 gdb 不仅可以使用 "rbreak" 命令向文件中的所有函数和模板实例添加断点,还可以添加更多其他方式。我已经编辑了答案。 - darcamo
我认为最后一个示例忘记了一个 .(因此它将匹配 doubleInpudoubleInputttt,这是一个正则表达式)。 - user202729
实际上我尝试了rbreak,但它没有起作用,稍后会想办法解决。 - user202729

0

break doubleInput<*> 不起作用, 但是 rbreak doubleInput<.*> 将在从模板生成的所有函数上设置断点。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接