如何调试linux中的践踏问题

时间:2012-08-06 13:40:24

标签: c++ linux linux-kernel embedded-linux

我在大型软件中遇到内存踩踏问题。

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

有关可能的调查方式的任何建议吗?

P.S - 无法附加valgrind。

提前致谢。

3 个答案:

答案 0 :(得分:1)

你可以尝试一些技巧。首先,检查堆的一致性,参见here

您可能还想编写一个钩子,将DEDEDEDE写入所有释放的内存,在编写钩子时可以看here来做到这一点。

答案 1 :(得分:1)

有许多替代堆实现,其中包含各种形式的完整性检查,您可以使用libc链接系统。常用技术包括:

  • 分配比请求更大的块,并在所请求的块的开头和结尾周围放置保护区
  • 每次分配一页,任何一侧都有无法访问的页面(例如,任何访问时出现页面错误)
  • 跟踪已分配的块以及已解除分配的块
  • 在低优先级线程中寻找坏东西的堆
几年前,我花了很长时间试图在嵌入式系统上找到这样的问题 - 经过几天的正常运行后报告了这个问题。从未让我的桌子上的装置发生碰撞。我在本书中尝试了几乎所有技巧 - 包括彻底的代码审计和PCLinting整个代码库。

我最终在两个系统上追踪到导致错误的SDRAM速度等级的原因。坠毁的那个比我桌子上的那个略微边缘化。最终通过吹风机和一罐冷冻喷雾证明了这一点:/

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

答案 2 :(得分:0)

如果通过某种奇迹,你可以以某种方式使相同的内存位置在连续运行(或至少25%的时间或某些东西)中被破坏,你可以在该内存位置的gdb中使用数据断点。

如果没有发生这种情况,您是否在不同硬件上尝试过S / W以排除硬件内存错误?虽然罕见的事情仍然可能发生。

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

我知道你说这不是一个选项,但如果你能以任何方式将问题缩小到一小部分代码,valgrind真的那么好 - 它在很多场合帮助了我。 / p>

最后,如果这些选项都没有产生结果,那么你将不得不更加重视:

  • 如果您能以某种方式检查数据结构的完整性,请使用此类检查来丢弃您的代码。
  • 开始删除代码并查看问题是否消失。
  • 从头开始重构或重写代码的可疑部分。
  • 受影响区域内任何/所有代码的多人同行评审。最好一个人对代码有很好的了解,而另一个人有域知识,但不知道代码(因为当你不知道你认为代码是什么时,你会看到很多错误在您查看时更容易。)