如何在 Linux 中调试践踏问题

how to debug trampling issues in linux

本文关键字:问题 调试 Linux      更新时间:2023-10-16

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

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

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

P.S - 无法连接瓦尔格林德。

提前谢谢.

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

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

有任意数量的替代堆实现,具有各种形式的健全性检查,您可以链接到您的系统而不是libc中的系统。 常用技术包括:

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

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

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

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

如果奇迹

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

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

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

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

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

级:
  • 如果可以以某种方式检查数据结构的健全性,请在代码中乱扔此类检查。
  • 开始删除代码,看看问题是否消失。
  • 从头开始重构或重写代码的可疑部分。
  • 对受影响区域的任何/所有代码进行多人同行评审。最好有一个人对代码很熟悉,而另一个人有领域知识但不了解代码(因为当你不知道你认为代码说了什么时,你在审查时更容易看到错误)。