valgrind/callgrind 可以在发布的可执行 C++ 程序上工作吗?

Posted

技术标签:

【中文标题】valgrind/callgrind 可以在发布的可执行 C++ 程序上工作吗?【英文标题】:Can valgrind/callgrind work on a release executable C++ program? 【发布时间】:2014-07-11 15:09:56 【问题描述】:

我知道valgrind可以调用memcheck进行内存泄漏检查,在这种情况下编译的C++可执行程序必须包含调试信息。那么,如果我想使用 valgrind/callgrind 进行分析,可执行文件必须包含调试信息吗?我运行了一个小测试,似乎 valgrind/callgrind 可以在没有调试信息的情况下发布可执行程序。任何人都可以确认吗?

【问题讨论】:

是的,它们可以工作,但是你不会得到任何好的函数或文件名,或行号信息。 如果您的程序具有自定义堆或内存池管理,则在发布版本中使用 Valgrind 可能会发现更少或没有内存问题。 Valgrind 对你自己的 alloc/dealloc 机制一无所知。 【参考方案1】:

来自官方Valgrind文档链接,可以找到以下信息:

2.2.开始

首先,考虑重新编译您的应用程序和支持库是否有益启用调试信息(-g 选项) .

没有调试信息,最好的 Valgrind 工具将能够猜测一段特定代码属于哪个函数,这使得错误消息和分析输出几乎无用。使用 -g,您将获得直接指向相关源代码行的消息。

另一个选项,如果您使用 C++,您可能会考虑使用 -fno-inline。这样可以更容易地查看函数调用链,这有助于减少在大型 C++ 应用程序中导航时的混淆。例如,使用此选项时,使用 Memcheck 调试 OpenOffice.org 会更容易一些。您不必这样做,但这样做有助于 Valgrind 生成更准确、更少混乱的错误报告。如果您打算使用 GNU GDB 或其他一些调试工具来调试您的程序,那么您可能已经进行了这样的设置。

因此建议的步骤是使用 -g 选项重新编译您的程序,以从 Valgrind 获取最大信息。

【讨论】:

【参考方案2】:

根据 valgrind 手册:

http://valgrind.org/docs/manual/manual-core.html

如果您计划使用 Memcheck:在极少数情况下,编译器优化(在 -O2 及以上,有时是 -O1)会生成代码,使 Memcheck 错误地报告未初始化值错误或丢失未初始化值错误.我们已经详细研究过如何解决这个问题,但不幸的是,这样做会使本已很慢的工具进一步显着放缓。所以最好的解决方案是完全关闭优化。由于这通常会使事情变得难以控制,因此一个合理的折衷方案是使用 -O。这为您带来了更高优化级别的大部分好处,同时保持相对较小的 Memcheck 误报或误报的机会。此外,您应该使用 -Wall 编译代码,因为它可以识别 Valgrind 在更高优化级别可能遗漏的部分或全部问题。 (通常使用 -Wall 也是一个好主意。)所有其他工具(据我们所知)不受优化级别的影响,对于像 Cachegrind 这样的分析工具,最好在正常优化级别编译程序。

【讨论】:

以上是关于valgrind/callgrind 可以在发布的可执行 C++ 程序上工作吗?的主要内容,如果未能解决你的问题,请参考以下文章

valgrind / callgrind:什么是`_dl_runtime_resolve_xsave`

如何使用 KCachegrind 和 Callgrind 仅测量我的部分代码?

可视化每个线程正在运行的功能的工具

查找可能由线程锁定引起的性能问题(可能)

c++ - 分析以获取被调用函数的概述

可以在 TFS 2017 中执行发布期间更改变量的值