19

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?

Anteru
  • 19,042
  • 12
  • 77
  • 121
  • yes, of course, I double-checked that dlclose is properly called -- but only if dlopen returns something != NULL, and I suspect this is from cases where dlopen _does_ return 0 – Anteru Oct 09 '09 at 09:55

3 Answers3

14

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

Calmarius
  • 18,570
  • 18
  • 110
  • 157
Aram Verstegen
  • 2,407
  • 1
  • 17
  • 15
  • A friend pointed out it's a bug in Valgrind. https://issues.asterisk.org/view.php?id=16007 See attached valgrind suppression file. – Aram Verstegen Dec 09 '09 at 14:52
  • 5
    I found out valgrind will not report this leak if you end your code with pthread_exit(NULL), even if you aren't using pthreads at all. Maybe this can help someone. It might be less cumbersome than writing a valgrind suppression file. – Aram Verstegen Dec 09 '09 at 16:21
  • I assume that the call to pthread_exit cleans up the thread local storage that is used to store the error text (so that it is multi-thread safe -- you simply need thread affinity between the calls to dlopen and dlerror). – KayEss Dec 13 '09 at 09:09
  • 3
    -1 because the paste is gone. (Otherwise, I would have edited it into the answer …) – SamB Sep 15 '13 at 21:41
  • The problem is reproducible also with Ubuntu 20.04.4 LTS and valgrind-3.15.0. – Johannes Overmann Nov 22 '22 at 13:27
4

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.)

StellarVortex
  • 576
  • 4
  • 19
1

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.

James Morris
  • 4,867
  • 3
  • 32
  • 51