GDB,在多个位置设置断点

11

我在一个 .h 文件中设置了一个断点,该文件具有一个小方法的实现。

(gdb) break SmallVector.h:141

这是我从gdb得到的:

Breakpoint 5 at 0x416312: SmallVector.h:141. (38 locations)

为什么断点设置在38个位置而不是一个位置?

我对调试和C++并不陌生,但不幸的是我从未像现在这样使用过复杂的东西(编译器)。所以我以前从未遇到过这样的情况。

感谢任何帮助。


2
如果一个小函数在许多地方被内联,就可能会发生这种情况。 - Iwillnotexist Idonotexist
只是出于好奇,即使我没有告诉编译器将一个方法inline,它仍然可以根据其所进行的分析来实现。我的理解正确吗? - flashburn
1
是的。inline关键字只是一个提示;编译器很少认真考虑它。 - Iwillnotexist Idonotexist
2个回答

14

有几种方式可以发生这种情况。

一种主要的方式,如您所发现的,是内联函数。某些编译器(例如gcc)将生成有关其已完成的内联的调试信息。gdb看到此信息并尝试在每个内联位置设置断点。

另一种典型的方式是使用模板。每个模板实例化将具有相同的位置,因此break file:line将在每个实例化中导致断点。

还有一种方式,如果您使用break function并且有多个同名函数,则会发生这种情况。在这里,经常使新用户感到困惑的一个场景是,在幕后,编译器经常会发出多个构造函数的副本(查找“in charge constructor”以获取详细信息)。

最后一种可能的方式是编译器进行其他类型的优化,例如部分内联。这些很少见。


1
每当我在具有模板实现的头文件中添加断点时,就会发生这种情况。
答案是每次有内联函数调用时,断点将设置在该位置,这经常发生在头文件中的模板实现中 :)
要强制函数成为内联函数,您必须为编译器指定一个__attribute__函数标志!例如
#include <iostream>
using std::cout;
using std::endl;

__attribute__ ((always_inline))
inline void function() {
    cout << "Hello World" << endl;
}

int main() {
    cout << "Hello World" << endl;

    return 0;

}

感谢 @IwillnotexistIdonotexist 提供的贡献。


建议扩展此答案以解释为什么会发生这种情况。 - user4581301
我有与评论相同的话要说。我应该加进去吗? - Curious
是的。回答应该尽可能完整,而不会变得过于学究。如果您从评论中借鉴,请注明评论者。顺便说一句,不是给你打负评,我只是想给你一个改进答案的机会。 - user4581301
我给你点了赞,但是请详细阐述一下你的回答。你不需要引用我的话;这个问题很明显,包括你和我在内的许多人都会想到、说出并且写出完全相同的答案。 - Iwillnotexist Idonotexist

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