0

我在大型软件中面临内存践踏问题。

有时会观察到 SIGSEGV/SIGABRT。原因主要是践踏用户或 malloc 空间内存。尝试使用 mprotect-ed 内存作为“诱饵”,但没有运气。实际上无法抓住践踏者。从核心文件分析看来,malloc 空间(当前块大小)也发生了损坏。损坏总是单字节的并且发生在任何地方(我的意思是这样的模式,我可以称之为溢出/下溢,比如 0xFF00FF00 被 0xFF003A00 损坏)

对可能的调查方式有什么建议吗??

PS -- 无法附加 valgrind。

提前致谢 。

4

3 回答 3

1

您可以尝试一些技巧。首先,检查堆的一致性,请参见此处

您可能还想编写一个钩子,将 DEDEDEDE 写入所有已释放的内存,请参阅此处编写一个钩子来做到这一点。

于 2012-08-06T14:15:32.943 回答
1

有许多具有各种形式的健全性检查的替代堆实现,您可以链接到您的系统来代替 libc 中的那个。常用技术包括:

  • 分配比请求更大的块,并在请求块的开头和结尾放置保护区
  • 每个分配一页,两边都有不可访问的页面(例如,任何访问时出现页面错误)
  • 跟踪分配的块以及释放的块
  • 在低优先级线程中遍历堆以寻找坏东西

几年前,我花了很长时间试图在嵌入式系统上找到这样的问题——在运行几天后报告的问题。从来没有让我桌子上的设备崩溃。我几乎尝试了书中的所有技巧——包括彻底的代码审计和 PCLinting 整个代码库。

我最终将原因归结为两个系统上 SDRAM 的错误速度等级。坠毁的那个比我桌子上的那个稍微边缘一点。最终用吹风机和一罐冷冻喷雾最终证明:/

如果你能得到一个被反复践踏的确认位置,你的下一个停靠点将是使用硬件辅助调试(现在大多数 CPU 都允许这样做)或基于 ICE 或 JTAG 的调试器。

于 2012-08-08T22:09:30.847 回答
0

如果由于某种奇迹,您可以以某种方式使相同的内存位置在连续运行(或至少 25% 的时间或其他时间)中损坏,您可以在该内存位置的 gdb 中使用数据断点。

如果这没有发生,您是否在不同的硬件上尝试过您的软件以排除硬件内存错误?虽然很少有这样的事情仍然会发生。

另一种选择是尝试预加载一个分配器,例如libumem谷歌的分配器,看看它是否可以检测到任何内存问题。

我知道您说过这不是一个选择,但是如果您可以以任何方式将问题缩小到一组较小的代码,valgrind那真的很好 - 它在多个场合都对我有帮助。

最后,如果这些选项都没有产生结果,你将不得不变得更重量级:

  • 如果您可以通过某种方式检查数据结构的健全性,请在代码中添加此类检查。
  • 开始删除代码,看看问题是否消失。
  • 从头开始重构或重写代码的可疑部分。
  • 对受影响区域中的任何/所有代码进行多人同行评审。最好一个人对代码非常熟悉,而另一个人具有领域知识但知道代码(因为当您不知道代码在说什么时,您在查看时会更容易看到错误)。
于 2012-08-07T13:46:20.493 回答