C语言 使用GDB运行时致命错误消失

sshcrbum  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(115)

我有一个程序,它在测试用例中产生了一个致命错误,我可以通过阅读日志和致命错误的堆栈跟踪来定位问题。结果是在空指针上有一个读操作。
但是当我尝试将GDB附加到它并在可疑代码周围设置断点时,空指针就是无法被观察到!程序运行平稳,没有任何错误。
这是一个单进程、单线程的程序,我以前没有经历过这种事情。为什么呢?
追加:我还尝试在致命触发器代码之前调用pause()系统调用,并期望在致命点之前使程序休眠,然后在运行中将GDB附加到它上,遗憾的是,没有发生致命错误。

ar5n3qh5

ar5n3qh51#

这只是猜测,没有看代码,但调试器有时会这样做:

  • 他们为你初始化某些东西
  • 操作的时间被改变

我没有GDB的报价,但我有一个关于Valgrind的报价(当然这两个做了非常不同的事情…)
我的程序通常会崩溃,但在Valgrind下不会,反之亦然。怎么回事?
当程序在Valgrind下运行时,其环境与本机运行时略有不同。例如,内存布局不同,线程调度的方式也不同。
GDB也是如此。
大多数情况下,这不会产生任何影响,但它可以,特别是如果您的程序有bug。
所以真正的问题可能在你的程序中。

dgsult0t

dgsult0t2#

可能会有几件事发生。应用程序的时间可以改变,所以如果它是一个多线程应用程序,例如,您可以首先设置就绪标志,然后将数据复制到缓冲区中,而无需附加调试器,其他线程可能会在缓冲区被填充或设置某些指针之前访问缓冲区。
也有可能某些应用程序具有反调试功能。也许在调试器中运行时,代码片段从未被触及。
分析它的一种方法是使用核心转储。你可以通过ulimit -c unlimited创建它,然后启动应用程序,当内核被转储时,你可以用gdb ./application ./core将它加载到gdb中。http://www.ffnn.nl/pages/articles/linux/gdb-gnu-debugger-intro.php

8cdiaqws

8cdiaqws3#

如果是对指针的无效读取,则可能出现不可预测的行为。既然你已经知道是什么引起了故障,你应该尽快排除它。一般来说,在处理错误的指针操作时要预料到意外情况。

相关问题