Memory leaks valgrind在dlopen中报告内存泄漏?

Memory leaks valgrind在dlopen中报告内存泄漏?,memory-leaks,valgrind,dlopen,Memory Leaks,Valgrind,Dlopen,最近我一直在用valgrind调试一些应用程序,我从dlopen收到了非常奇怪的报告 ==1987== 32 bytes in 1 blocks are still reachable in loss record 1 of 2 ==1987== at 0x4C24477: calloc (vg_replace_malloc.c:418) ==1987== by 0x570F31F: _dlerror_run (dlerror.c:142) ==1987== by 0x570E

最近我一直在用valgrind调试一些应用程序,我从
dlopen
收到了非常奇怪的报告

==1987== 32 bytes in 1 blocks are still reachable in loss record 1 of 2
==1987==    at 0x4C24477: calloc (vg_replace_malloc.c:418)
==1987==    by 0x570F31F: _dlerror_run (dlerror.c:142)
==1987==    by 0x570EEE0: dlopen@@GLIBC_2.2.5 (dlopen.c:88)
        <my call to dlopen>
==1987==
==1987== 264 bytes in 1 blocks are still reachable in loss record 2 of 2
==1987==    at 0x4C25153: malloc (vg_replace_malloc.c:195)
==1987==    by 0x400CD44: _dl_map_object_deps (dl-deps.c:506)
==1987==    by 0x4012DA2: dl_open_worker (dl-open.c:326)
==1987==    by 0x400E385: _dl_catch_error (dl-error.c:178)
==1987==    by 0x40126C6: _dl_open (dl-open.c:615)
==1987==    by 0x570EF65: dlopen_doit (dlopen.c:67)
==1987==    by 0x400E385: _dl_catch_error (dl-error.c:178)
==1987==    by 0x570F2AB: _dlerror_run (dlerror.c:164)
==1987==    by 0x570EEE0: dlopen@@GLIBC_2.2.5 (dlopen.c:88)
        <my call to dlopen>
==1987==1个块中的32个字节仍然可以在丢失记录1(共2个)中访问
==1987==at 0x4C24477:calloc(vg\U replace\U malloc.c:418)
==1987==0x570F31F:_-dlerror_-run(dlerror.c:142)
==1987==0x570EEE0:dlopen@@GLIBC_2.2.5(dlopen.c:88)
==1987==
==1987==1个块中的264个字节仍然可以在丢失记录2(共2个)中访问
==1987==0x4C25153:malloc(vg_替换_malloc.c:195)
==1987==0x400CD44:_dl_map_object_deps(dl deps.c:506)
==1987==由0x4012DA2:dl_open_worker(dl open.c:326)创建
==1987==0x400E385:_dl_catch_错误(dl error.c:178)
==1987==0x40126C6:_dl_open(dl open.c:615)
1987年通过0x570EF65:dlopen_doit(dlopen.c:67)
==1987==0x400E385:_dl_catch_错误(dl error.c:178)
==1987==0x570F2AB:_-dlerror_-run(dlerror.c:164)
==1987==0x570EEE0:dlopen@@GLIBC_2.2.5(dlopen.c:88)

这看起来像是为
dlerror
初始化的错误消息,但查看手册页,它没有说明如何清除此错误。你知道如何正确地解决这个问题吗?

我自己也在各种libs中看到过,不管是否使用dlopen。我只是假设是libs中的一些神奇的实现欺骗了valgrind——或者——这些libs实际上存在内存泄漏,在这种情况下,我在我的应用程序中无能为力。

能够用一些“hello world”代码重现这个问题,这些代码甚至不调用加载对象中的任何符号。

我想这是libc或valgrind中的一个bug。 可在Ubuntu 9.04和Scientific Linux 5.3上复制(分别为20和32字节)

编辑(由Calmarius编写):

这段琐碎的代码再现了问题:

#include <dlfcn.h>

int main()
{
    void* handle = 0;

    handle = dlopen("libm.so", RTLD_NOW);
    dlclose(handle);    

    return 0;
}
即使是最新的valgrind 3.11也可以在Ubuntu 14.04上重现这一点


已报告上游错误:

此抑制效果更好:

{
   Ignore dlopen bug.
   Memcheck:Leak
   ...
   fun:_dl_open
   ...
}

(请注意,“…”是抑制的一部分,应该按字面意思输入。)

是的,当然,我仔细检查了是否正确调用了dlclose——但只有在dlopen返回某个内容时!=NULL,我怀疑这是因为dlopen确实返回0。一位朋友指出这是Valgrind中的一个bug。请参阅附件中的valgrind抑制文件。我发现,如果您使用pthread_exit(NULL)结束代码,valgrind将不会报告此泄漏,即使您根本没有使用pthreads。也许这可以帮助别人。它可能比编写valgrind抑制文件更简单。我假设对pthread_exit的调用会清理用于存储错误文本的线程本地存储(因此它是多线程安全的——您只需在对dlopen和dlerror的调用之间建立线程关联即可)。-1因为粘贴已消失。(否则,我会把它编辑成答案…)
{
   Ignore dlopen bug.
   Memcheck:Leak
   ...
   fun:_dl_open
   ...
}