无法在gdb中重现段错误

时间:2011-08-14 15:19:42

标签: c gdb

我在运行项目时遇到了段错误。每次我在gdb中运行程序时,段错误都会消失。这种行为不是随机的:每次我在shell中运行它都会出现段错误,每次我在gdb中运行它时,段错误都会消失。 (我确实使用-g重新编译)。

所以在我开始在代码中的任何地方疯狂地添加printfs之前,我想知道一些事情:

  • 这种行为常见吗?
  • 解决问题的最佳方法是什么?

我不知道测试是否可以编写脚本,因为我的应用程序是交互式的,并且在特定的用户输入上崩溃。

我没有在此处粘贴代码,因为它太长了。但如果有人有兴趣帮忙,这里是: https://github.com/rahmu/Agros

4 个答案:

答案 0 :(得分:15)

最简单的解决方法是捕获核心转储:

$ ulimit -c unlimited

然后运行你的程序。它将生成core文件

然后使用gdb:

$ gdb ./program core

gdb将加载,你可以运行一个回溯来查看究竟是什么操作引起了段错误。

答案 1 :(得分:0)

它是否进行核心转储?是这样在调试器中加载核心转储。否则,请更改代码以使其进行核心转储。

答案 2 :(得分:0)

我的猜测是,这是一个并发问题导致引用从方法调用中释放出来,假设它具有的指针将保持有效。 gdb可能掩盖这个的原因是因为GDB只允许2个线程实际并发运行。如果您运行的线程数超过2个,则只有2个线程会同时运行。 GDB也有性能命中,可能会掩盖这种特定情况。正如Ed所提到的那样,只需将应用程序转换为核心转储,就可以在GDB中打开核心并检查堆栈。

答案 3 :(得分:0)

  

这种行为常见吗?

是。未定义的行为是大多数这些问题的根源,根据定义,它是未定义的。使用-g重新编译肯定会影响结果。如果编译器使用一些伪随机遗传算法来优化东西或类似东西,那么重新编译可能会改变结果。

  

解决问题的最佳方式是什么?

一盎司的预防值得大量治疗;了解未定义行为的常见原因并养成良好的习惯以避免编写它们。一旦发现存在问题,静态分析代码通常是个好主意;通过并证明自己并证明索引将保持在边界内,数据将适合其数组,无效指针将不会被解除引用等。