I'm trying to track down an issue where Valgrind can't resolve symbols of functions that pass through certain libraries. I get output like this:
==83597== 920 bytes in 1 blocks are possibly lost in loss record 750 of 864
==83597== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==83597== by 0x548EF93: myproject_malloc (mysourcefile.c:48)
==83597== by 0x4F13FD5: ??? (in /path/to/project/library-version.so)
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so)
==83597== by 0x4F536CA: ??? (in /path/to/project/library-version.so)
==83597== by 0x54542FF: ??? (in /path/to/project/library-version.so)
One of the functions inside library-version.so
is do_init()
. library-version.so
is loaded via LD_PRELOAD
. I've found that when I run my program under gdb, if I try to put a break point at do_init
as soon as I start the program, it complains that it can't find the symbol, but if I put a breakpoint at main
and wait until it hits that, then it works.
For example:
(gdb) break do_init
Function "do_init" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) break main
Breakpoint 1 at 0x400b50: file runner.c, line 13.
(gdb) run
... a bunch of output from the stuff in LD_PRELOAD ...
Breakpoint 1, main (argc=1, argv=0x7fffffffe028) at myprogram.c:13
13 return do_some_stuff();
(gdb) break do_init
Breakpoint 2 at 0x7ffff7658de0: file my/library/initializer.c, line 25.
So this leads me to two questions:
It seem that
do_init
is getting pulled in by the dynamic linker. How can I find out what step of the initialization process that happens at? There are many libraries used in this project that define functions with__attribute__((constructor))
and they get glued together with a linker script.Why doesn't Valgrind see the symbols loaded by the dynamic linker like GDB does? I'm 99% sure that nothing is being
dlclose
'd, and I thought that anything underLD_PRELOAD
would remain visible to Valgrind no matter what.