Memory leak reported by valgrind in dlopen?

2019-04-19 16:35发布

问题:

I've been debugging some app lately with valgrind, and I'm getting very weird reports from 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>

This looks like the error message that is initialized for dlerror, but looking at the man page, it doesn't say anything about how this should be cleared. Any idea how to correctly get rid of this?

回答1:

Was able to reproduce this issue with some 'hello world' code, which doesn't even call any symbols in the loaded object. http://pastebin.com/d690bea57

I assume it's a bug in libc or valgrind. Reproducible on Ubuntu 9.04 and Scientific Linux 5.3 (20 and 32 bytes respectively).

EDIT (by Calmarius):

This trivial code reproduces the problem:

#include <dlfcn.h>

int main()
{
    void* handle = 0;

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

    return 0;
}

When compiled with this command:

gcc -Wl,--no-as-needed -g -o stuff  main.c -ldl -lpthread

Even the latest valgrind 3.11 can reproduce this on Ubuntu 14.04

Upstream bug has been reported: https://bugs.kde.org/show_bug.cgi?id=358980



回答2:

This suppression is better:

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

(Note that the "..." is part of the suppression and should be entered literally.)



回答3:

I've seen this myself in all sorts of libs, using dlopen or not. I just assumed it was some magic implementation within the libs which tricked valgrind - or - these libs actually do have memory leaks in which case there's nothing I can do within my app.