我只是花了一些时间来追查一个归结为以下问题的错误。代码错误地覆盖了堆栈,我认为它覆盖了函数调用的返回地址。返回后,程序将崩溃并且堆栈将被破坏。在 valgrind 中运行程序会返回一个错误,例如:
vex x86->IR: unhandled instruction bytes: 0xEA 0x3 0x0 0x0
==9222== valgrind: Unrecognised instruction at address 0x4e925a8.
我认为这是因为返回跳转到一个随机位置,其中包含无效的 x86 操作码的内容。 (虽然我有点怀疑这个地址 0x4e925a8 碰巧在一个可执行页面中。我想如果不是这种情况,valgrind 会抛出一个不同的错误。)
我确信问题出在堆栈覆盖类型上,并且我已经修复了它。现在我正在考虑如何更有效地捕捉这样的错误。显然,如果我重写堆栈上的数据,valgrind 无法警告我,但是当有人重写堆栈上的返回地址时,它可能会捕获。原则上,它可以检测“push EIP”之类的事情何时发生(因此它可以标记返回地址在堆栈中的位置)。
我想知道是否有人知道 Valgrind 或其他任何东西是否可以做到这一点?如果没有,您能否评论有关有效调试此类错误的其他建议。
最佳答案
通常,Valgrind 对堆栈和全局变量溢出的检测弱到不存在。可以说,Valgrind 是该工作的错误工具。
如果您使用受支持的平台之一,请使用 -fmudflap
构建并与 -lmudflap
链接对于这些类型的错误,将为您提供更好的结果。其他文档 here .
更新日期:
自这个答案以来的 6 年里发生了很大变化。在 Linux 上,查找堆栈(和堆)溢出的工具是 AddressSanitizer ,由最新版本的 GCC 和 Clang 支持。
关于stack-overflow - 如何使用 Valgrind 调试堆栈覆盖错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5813444/