当前位置:  开发笔记 > 编程语言 > 正文

如何使用Valgrind调试堆栈覆盖错误?

如何解决《如何使用Valgrind调试堆栈覆盖错误?》经验,为你挑选了2个好方法。

我只是花了一些时间来追逐一个归结为以下的错误.代码错误地覆盖了堆栈,我认为它写了函数调用的返回地址.返回后,程序将崩溃并且堆栈将被破坏.在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或其他任何东西能否做到这一点?如果没有,您是否可以有效地评论有关此类调试错误的其他建议.



1> Employed Rus..:

通常,Valgrind检测堆栈和全局变量中的溢出对于不存在是弱的.可以说,Valgrind是这项工作的错误工具.

如果您使用的是受支持的平台之一,那么构建-fmudflap和链接-lmudflap将为这些类型的错误提供更好的结果.其他文档在这里.

Udpdate:

自这个答案以来的6年里,情况发生了很大的变化.在Linux上,查找堆栈(和堆)溢出工具是AddressSanitizer,由最新版本的GCC和Clang支持.



2> Jan Hudec..:

如果问题确定性地发生,你可以指出特定的功能,它的堆栈被粉碎(在一个可重复的测试用例中),你可以在gdb中:

    在进入该功能时休息

    找到存储返回地址的位置(它相对于%ebp(在x86上)(它保留%esp了函数入口的值),我不确定是否有任何偏移).

    将观察点添加到该地址.您必须watch使用计算出的数字而不是表达式发出命令,因为使用表达式gdb会尝试在每条指令后重新计算它而不是设置陷阱,这将非常慢.

    让函数运行完成.

我还没有使用gdb7中提供的python支持,但它应该允许自动执行此操作.

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有