如何调试内存随机改变的问题

Nan*_*iao 4 c memory debugging solaris

我的应用程序是一个在 Solaris 上运行的多线程程序。

最近,我发现它可能会崩溃,原因是指针数组中的一个成员从有效值更改为NULL,所以在访问它时,它崩溃了。

由于出现比例很低,近2个月只出现了两次,而且数组中变化的成员并不相同。我找不到重复的步骤,并且在检查代码后,没有得到任何有价值的线索。

任何人都可以就如何调试内存随机更改问题提供一些建议吗?

Jer*_*ner 5

由于您无法重现崩溃,因此调试它并不容易。

但是,您可以做一些事情:

  1. 仔细检查代码并列出代码中写入该变量的所有位置,特别是可以向其写入 NULL 的位置。其中之一很可能就是你的罪魁祸首。

  2. 尝试开发某种折磨测试,使故障更有可能发生(例如,以最高速度运行模拟或随机事务)。如果您可以通过这种方式重现崩溃,您的情况将会好得多,因为您可以分析崩溃的实际原因,而不仅仅是猜测。

  3. 如果可能,请在 valgrind 或 purify 或类似命令下运行该程序。如果他们发出任何警告,请找出导致这些警告的原因并修复它;例如,您的程序可能正在访问已释放的内存,这在大多数情况下似乎都可以工作(如果空闲内存在访问时尚未被重用),但偶尔会失败(当某些东西重用它时) )

  4. 在代码中添加像 Electric Fence 这样的内存检查器,或者只是将 free() 替换为自定义版本,该版本会用随机垃圾覆盖可用内存,希望这将使崩溃更有可能发生。

  5. 使用不同的编译器(尤其是新的/奇特的编译器,例如启用了静态分析器的 clang++)重新编译您的程序,并修复它们警告的任何内容。这可能会指出您的问题。

  6. 在不同的硬件和操作系统下运行程序;有时,一个操作系统下的一个不起眼的问题在另一个操作系统上会产生非常明显的症状。

  7. 检查已知发生崩溃的各种机器。他们有什么共同点吗?那些没有崩溃的机器呢?他们有什么不同吗?

第 2 步确实是最重要的一步,因为即使您认为已经解决了问题,也无法证明这一点,除非您可以在旧代码中重现崩溃,并且无法用修复的代码重现崩溃。由于无法重现错误,您只能猜测特定的代码更改是否确实有帮助。