我在运行项目时遇到了段错误。每次我在gdb中运行程序时,段错误都会消失。这种行为不是随机的:每次我在shell中运行它都会出现段错误,每次我在gdb中运行它时,段错误都会消失。 (我确实使用-g重新编译)。
所以在我开始在代码中的任何地方疯狂地添加printfs之前,我想知道一些事情:
我不知道测试是否可以编写脚本,因为我的应用程序是交互式的,并且在特定的用户输入上崩溃。
我没有在此处粘贴代码,因为它太长了。但如果有人有兴趣帮忙,这里是: https://github.com/rahmu/Agros
答案 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
重新编译肯定会影响结果。如果编译器使用一些伪随机遗传算法来优化东西或类似东西,那么重新编译可能会改变结果。
解决问题的最佳方式是什么?
一盎司的预防值得大量治疗;了解未定义行为的常见原因并养成良好的习惯以避免编写它们。一旦发现存在问题,静态分析代码通常是个好主意;通过并证明自己并证明索引将保持在边界内,数据将适合其数组,无效指针将不会被解除引用等。