我有一个多线程的C程序,在程序的特定点始终会发生分段错误。当我使用gdb调试运行时,没有显示错误。你能想到为什么只有在不使用调试器时才会发生这种错误吗?不能使用调试器找到问题真是太烦人了!
我有一个多线程的C程序,在程序的特定点始终会发生分段错误。当我使用gdb调试运行时,没有显示错误。你能想到为什么只有在不使用调试器时才会发生这种错误吗?不能使用调试器找到问题真是太烦人了!
经典的Heisenbug。来自维基百科:
时间也可以是Heisenbugs的一个因素。在调试器的控制下执行程序可能会改变程序的执行时间与正常执行相比。当程序被单步源行在调试器中减速时,例如存在竞态条件等时间敏感的错误可能无法再现。特别是当行为涉及与调试器不受控制的实体的交互时,例如调试两台计算机之间的网络数据包处理且只有一台计算机处于调试器控制之下。
调试器可能会改变时间,并隐藏竞态条件。
在Linux上,GDB还会禁用地址空间随机化,而您的崩溃可能与地址空间布局有关。尝试(gdb) set disable-randomization off
。
最后,ulimit -c unlimited
和事后调试(Robie已经建议)可能有效。
通过调试它,您正在更改其运行环境。听起来您正在处理某种竞争条件,并且通过调试它,事物被略微不同地安排,因此您不会遇到该问题。或者,事物以稍微不同的方式存储,因此不会发生这种情况。您能否在代码中添加一些调试输出以帮助解决问题?那可能会对其影响较小,并允许您找到问题。
我之前也遇到过这个问题!这是一种竞争条件,当我用调试器逐步执行代码时,我所在的线程速度足够慢,无法触发竞争条件。非常糟糕。
gcc
,请尝试使用-Wall
选项获取所有警告。如果您使用像Eclipse这样的IDE,则会自动执行此操作。
ulimit -c unlimited
,然后在程序发生错误退出时使用gdb myprogram core
命令。这样,gdb 就能够对你的段错误进行死后调试了。 - Robie Basak