如何根据 Valgrind 输出进一步调试

Posted

技术标签:

【中文标题】如何根据 Valgrind 输出进一步调试【英文标题】:How to debug further based on Valgrind output 【发布时间】:2012-05-04 17:07:06 【问题描述】:

我的 C/C++ 代码给出了段错误。它是在 RH Linux Enterprise 服务器上使用 gcc/g++ 编译的。我在可执行文件上使用了 Valgrind 内存检查器:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes

我将此作为 Valgrind 的输出消息之一:

==7053== Invalid read of size 1
==7053==    at 0xDBC96C: func1 (file1:4742)
==7053==    by 0xDB8769: func2 (file1.c:3478)
==7053==    by 0xDB167E: func3 (file1.c:2032)
==7053==    by 0xDB0378: func4 (file1.c:1542)
==7053==    by 0xDB97D8: func5 (file1.c:3697)
==7053==    by 0xDB17A7: func6 (file1.c:2120)
==7053==    by 0xDBD55E: func7 (file2.c:271) 

==7053==  Address 0x1bcaf2f0 is not stack'd, malloc'd or (recently) free'd 

我读到这意味着我的代码访问了一个不允许的无效内存位置。

我的问题:

    我如何找出哪些缓冲区内存访问无效,以及上面的哪些函数做到了。

    如何使用地址 0x1bcaf2f0,valgrind 说这个地址是无效的。如何在该地址找到符号(本质上是缓冲区名称)?内存映射文件,任何其他方式。

    是否有任何其他通用指针、valgrind 选项或其他用于使用 Valgrind 检测内存(堆/堆栈损坏)错误的工具?

【问题讨论】:

【参考方案1】:

广告 1:在您的示例中,它是 file1:4742 (1) 行中的 func1。以下函数是堆栈跟踪。分析该行应该会导致您访问无效的内存。

广告 2:尝试将其拆分为多个更简单的行,以防它过于复杂且不明显是哪个确切的调用导致了警告。

广告 3:memcheck 是用于检测堆内存错误的典型 valgrind 工具。但它对堆栈损坏无济于事。

【讨论】:

谢谢。关于如何在内存位置0x1bcaf2f0 跟踪变量的任何指针,如上面的 valgrind 输出所示? 特别是如果显示的地址来自动态分配的缓冲区? 什么有助于解决堆栈损坏?【参考方案2】:

如果你有 Valgrind 3.7.0,你可以使用嵌入式 gdbserver 使用 gdb 调试在 Valgrind 下运行的应用程序。

见http://www.valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

【讨论】:

以上是关于如何根据 Valgrind 输出进一步调试的主要内容,如果未能解决你的问题,请参考以下文章

Valgrind - 打开 Windows 内存转储

Valgrind - callgrind Profiler:如何知道哪个函数需要更多时间

使用 mpirun 时,如何使分析器(valgrind、perf、pprof)拾取/使用带有调试符号的本地版本库?

使用 Valgrind 工具如何检测尝试访问 0x0 地址的对象?

如何获取详细的 valgrind 核心或使用 gdb 将调试附加到核心在启动时转储的进程?

使用gdb进行调试时,请彻底退出valgrind