2012-09-27 39 views
9

我需要知道如何找出共享库中的内存泄漏,这些内存泄漏将被加载到发布二进制文件中。我的意思是我用-g选项构建的共享库,但加载共享库的二进制文件不是用-g选项构建的。valgrind - 在共享库中查找内存泄漏

我得到泄漏报告如下。

==739== at 0x4A05809: malloc (vg_replace_malloc.c:149) 
==739== by 0x84781B1: ??? 
==739== by 0x87507F5: ??? 
==739== by 0x874CF47: ??? 
==739== by 0x874E657: ??? 
==739== by 0x874F7C2: ??? 
==739== by 0x8779C0C: ??? 

请让我知道如何从共享库中获取泄漏的堆栈跟踪?

回答

6

假设泄漏确实来自您的共享库,那么我认为这个问题并不是主要可执行文件中缺少调试。

更可能是您的问题是,可执行文件在完成之前通过调用dlclose来卸载共享库。这意味着,当valgrind检查泄漏时,库的所有符号信息都不再加载。

如果您可以重建可执行文件,那么最简单的解决方案可能是暂时停止调用dlclose,以便库保持加载直到结束。

如果你不能做到这一点,那么请尝试使用LD_PRELOAD保持库加载,这样的:

LD_PRELOAD="/path/to/library.so" valgrind my-executable 

,希望这将欺骗动态链接到保持甚至它已被关闭后加载库。

+0

有一个补丁提供了一个选项来禁用卸载dlclose后的符号。该补丁的工作原理和我已经使用过很多次。但补丁是旧版本,我想现在它已经烂了。 https://bugs.kde.org/show_bug.cgi?id=79362 – k0n3ru

+0

@TomH:让我指出,“omit dlclose”解决方法可能会导致大量误报。如果堆栈中存在销毁堆中元素的对象,那么这些元素会在输出中显示为泄漏,因为dlclose会首先完成销毁。 – newhouse

+0

而第二个不工作,如果valgrind是64位,但你调试32 – newhouse

2

正如前面的答案所示,这是因为您在程序终止之前关闭了库,因此符号信息不可用于valgrind。

使用LD_PRELOAD不适用于我;我现在有两个版本;一个明确不会调用dlclose();在这个版本上,valgrind会正确地报告行号信息,就像您期望的动态链接一样。