如何解释GDB回溯?

时间:2012-06-02 02:58:18

标签: c++ gdb segmentation-fault

0x004069f1 in Space::setPosition (this=0x77733cee, x=-65, y=-49) at space.h:44    
0x00402679 in Checkers::make_move (this=0x28cbb8, move=...) at checkers.cc:351
0x00403fd2 in main_savitch_14::game::make_computer_move (this=0x28cbb8) at game.cc:153
0x00403b70 in main_savitch_14::game::play (this=0x28cbb8) at game.cc:33
0x004015fb in _fu0___ZSt4cout () at checkers.cc:96
0x004042a7 in main () at main.cc:34

你好,我正在编写一个类的游戏,我遇到了一个段错误。检查器块保持在二维阵列中,因此对于阵列,违规位似乎是无效的x / y。移动作为字符串传递,它们被转换为整数,因此x和y在某种程度上是ASCII NULL。我注意到在函数调用make_move中它表示move = ...

为什么说move = ...?还有,解决段错误的任何其他快速提示?我是GDB的新手。

2 个答案:

答案 0 :(得分:5)

基本上,回溯是导致崩溃的调用的痕迹。在这种情况下:

名为game::play的{​​{1}}名为game::make_computer_move,名为Checkers::make_move,名为Space::setPosition,在文件space.h的第44行崩溃。

看一下这个回溯,看起来你已经将-65-49传递给了Space::setPosition,如果它们恰好是无效的坐标(肯定看起来对我是否定为可疑,所有)。然后你应该查看调用函数,看看他们为什么拥有他们所做的值并纠正它们。

我建议在代码中使用assert来强制执行合同,几乎任何时候你都可以说"这个参数或变量应该只有符合某些标准的值#34;那么你应该断言是这种情况。

一个常见的例子是,如果我有一个函数,它接受一个不允许NULL的指针(或更可能是智能指针)。我将拥有函数assert(p);的第一行。如果NULL指针通过,我马上就知道并且可以进行调查。

最后,在崩溃时在gdb中运行应用程序。键入up以检查调用堆栈帧并查看变量的外观:(通常可以在控制台中编写print x之类的内容)。同样,如果您需要,down将向下移动调用堆栈。

对于SEGFAULT,我建议在valgrind中运行该应用程序。如果使用调试信息-g进行编译,那么它通常可以告诉您导致错误的代码行(甚至可以捕获由于不幸原因而立即崩溃的错误)。

答案 1 :(得分:1)

我不允许发表评论,而只是想回答最近在该问题上试图找到变量变为何处的任何人(-65,-49)。如果遇到段错误,则可以获取核心转储。 Here是确保您可以设置gdb以获得核心转储的一个很好的来源。然后,您可以使用gdb打开核心文件:

gdb -c myCoreFile

然后在您要进入的函数调用上设置一个断点:

b MyClass::myFunctionCall

然后逐步执行下一步或逐步执行代码行:

step

next

当您位于代码中要评估变量的位置时,可以打印该变量:

p myVariable 

或者您可以打印所有参数:

info args

我希望这可以帮助想要调试的其他人!