如何根据 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 - callgrind Profiler:如何知道哪个函数需要更多时间
使用 mpirun 时,如何使分析器(valgrind、perf、pprof)拾取/使用带有调试符号的本地版本库?
使用 Valgrind 工具如何检测尝试访问 0x0 地址的对象?