6

valgrind 找不到任何有用的东西。我很困惑。

症状:

  1. 我的数据被 malloc() 调用损坏了
  2. 我的函数的返回地址被错误替换

PS:代码没有段错误

目前,我通过mmap()+替换所有 malloc() 取得了一些进展mprotect()

4

6 回答 6

7

您可能正在覆盖堆栈,或者您可能正在覆盖堆。

您可以尝试将标志添加-fstack-protector-all到您的 GCC 命令行选项中,以要求将一些堆栈粉碎报告内置到程序中。这可能会导致它更快地失败。

另一种可能性是查看dmesg输出中报告的地址,看看您是否无法追踪被破坏的函数/内存:

[68303.941351] broken[13301]: segfault at 7f0061616161 ip 000000000040053d sp 00007fffd4ad3980 error 4 in broken[400000+1000]

readelf -s将转储符号表,我们可以查找触发问题的函数:

$ readelf -s broken | grep 4005
40: 00000000004005e0     0 FUNC    LOCAL  DEFAULT   13 __do_global_ctors_aux
47: 0000000000400540     2 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini
57: 0000000000400550   137 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
63: 0000000000400515    42 FUNC    GLOBAL DEFAULT   13 main

main例程是在使用坏指针时执行的例程:

#include <string.h>

void f(const char *s) {
    char buf[4];
    strcpy(buf, s);
    return;
}

int main(int argc, char* argv[]) {
    f("aaaa");
    f("aaaaaaaaaaaaaaaaaaaa");
    return 0;
}

main试图返回 C 库退出时,它使用了存储在堆栈帧中的错误指针。所以看看由 调用的函数main,并且(在这种微不足道的情况下很容易)f显然是在堆栈框架上乱涂乱画的虫子。

如果您要覆盖堆,那么也许您可以尝试使用电栅栏。缺点非常陡峭(大量内存使用),但这可能正是您发现问题所需要的。

于 2011-02-21T10:40:35.953 回答
2

您还可以尝试 IBM Rational Purify 的试用版——这是一个很好的工具,可以检测缓冲区溢出、内存泄漏和任何其他内存损坏错误。按照此链接下载http://www-01.ibm.com/software/awdtools/purify/unix/

于 2011-02-21T12:12:59.537 回答
2
  1. 修复所有悬空指针,所有缓冲区溢出
  2. 仅在真正需要的地方使用指针

请参阅以下链接::哪些 C/C++ 工具可以检查缓冲区溢出?

于 2011-02-21T10:15:14.883 回答
2

Valgrind memcheck 不太擅长检测缓冲区溢出。但是你可以尝试一个可能的补丁

于 2011-02-21T10:23:48.907 回答
0

你是在什么环境下开发的?

如果您在 Windows 上开发,请尝试这篇文章http://msdn.microsoft.com/en-us/library/cc500347.aspx

于 2011-02-21T10:25:20.637 回答
0

在 Linux 上帮不了你。但是您说您没有使用任何字符串函数,这表明您的应用程序可能相当可移植。它在Windows下会失败吗?

如果是这样,我们的CheckPointer工具也许能够找到问题所在。它比 Valgrind 更仔细地检查程序如何使用指针,因为它可以看到代码中的结构和声明,并且它了解各种存储用途(堆栈帧与堆)。Valgrind 只能看到机器指令,无法判断堆栈帧何时超出范围。

于 2011-07-08T23:01:32.320 回答