| Summary: | Leaks from call_init (dl-init.c:74) | ||
|---|---|---|---|
| Product: | glibc | Reporter: | Paul Floyd <pjfloyd> |
| Component: | dynamic-link | Assignee: | Not yet assigned to anyone <unassigned> |
| Status: | RESOLVED MOVED | ||
| Severity: | normal | CC: | fw |
| Priority: | P2 | ||
| Version: | 2.40 | ||
| Target Milestone: | --- | ||
| Host: | Target: | ||
| Build: | Last reconfirmed: | 2024-12-25 00:00:00 | |
| Project(s) to access: | ssh public key: | ||
|
Description
Paul Floyd
2024-12-24 09:13:46 UTC
Please add a reproducer. The valgrind output is consistent with loading a shared object with dlopen, and the shared object has an ELF constructor that calls malloc (perhaps indirectly). From the Valgrind item git clone https://github.com/leshe4ka46/dlopen-leaks cd dlopen-leaks mkdir build cmake .. make cd .. ./build/dlopen_test There are quite a few dependencies, particularly Qt6. I don't get a leak on Fedora 41, also glibc 2.40. I'll try to see if I can get any more info about the callstack entries that seem to be stripped. (In reply to Paul Floyd from comment #2) > From the Valgrind item > > git clone https://github.com/leshe4ka46/dlopen-leaks > cd dlopen-leaks > mkdir build > cmake .. > make > cd .. > ./build/dlopen_test > > There are quite a few dependencies, particularly Qt6. > > I don't get a leak on Fedora 41, also glibc 2.40. > > I'll try to see if I can get any more info about the callstack entries that > seem to be stripped. The reproducer does not run under valgrind because it conflicts with Address Sanitizer. If you can reproduce it on Fedora 41, please run the reproducer under valgrind with: DEBUGINFOD_URLS=https://debuginfod.fedoraproject.org/ valgrind build/dlopen_test I forgot, you need to comment out asan:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index be1ab50..799b278 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@ endif()
project(dlopen_test CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -g -O0")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined")
+#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address,undefined")
I don't get the same problem with Fedora.v
Better results wiith "valgrind --leak-check=full --keep-debuginfo=yes ./build/dlopen_test"
==6339== 8 bytes in 1 blocks are definitely lost in loss record 1 of 15
==6339== at 0x48447A8: malloc (vg_replace_malloc.c:446)
==6339== by 0x96A0A35: gomp_malloc (alloc.c:38)
==6339== by 0x96B788F: gomp_init_num_threads (proc.c:91)
==6339== by 0x969F1BB: initialize_env (env.c:2218)
==6339== by 0x40045B6: call_init (dl-init.c:74)
==6339== by 0x40045B6: call_init (dl-init.c:26)
==6339== by 0x40046AC: _dl_init (dl-init.c:121)
==6339== by 0x40015C1: _dl_catch_exception (dl-catch.c:215)
==6339== by 0x400B4FB: dl_open_worker (dl-open.c:829)
==6339== by 0x4001522: _dl_catch_exception (dl-catch.c:241)
==6339== by 0x400B903: _dl_open (dl-open.c:905)
==6339== by 0x4CA3F13: dlopen_doit (dlopen.c:56)
==6339== by 0x4001522: _dl_catch_exception (dl-catch.c:241)
==6339==
==6339== 96 bytes in 1 blocks are definitely lost in loss record 10 of 15
==6339== at 0x484BC13: calloc (vg_replace_malloc.c:1675)
==6339== by 0x96A0A6D: gomp_malloc_cleared (alloc.c:47)
==6339== by 0x969F100: add_initial_icv_to_list (env.c:2159)
==6339== by 0x969F1D7: initialize_env (env.c:2224)
==6339== by 0x40045B6: call_init (dl-init.c:74)
==6339== by 0x40045B6: call_init (dl-init.c:26)
==6339== by 0x40046AC: _dl_init (dl-init.c:121)
==6339== by 0x40015C1: _dl_catch_exception (dl-catch.c:215)
==6339== by 0x400B4FB: dl_open_worker (dl-open.c:829)
==6339== by 0x4001522: _dl_catch_exception (dl-catch.c:241)
==6339== by 0x400B903: _dl_open (dl-open.c:905)
==6339== by 0x4CA3F13: dlopen_doit (dlopen.c:56)
==6339== by 0x4001522: _dl_catch_exception (dl-catch.c:241)
This is an allocation in libgomp for storing CPU affinity sets. The difference seems to be that dlclose on Fedora does not unload libgomp.so.1: libQt6Core.so.6 is marked NODELETE because it has a STB_GNU_UNIQUE symbol, it depends on libgomp.so.1, so libgomp.so.1 will stay around after that dlclose, too. NODELETE markings are logged by sufficiently new versions of glibc: LD_DEBUG=all build/dlopen_test </dev/null |& grep NODELETE You could report this as a GCC bug because libgomp could have an ELF destructor that frees the CPU set, or maybe a valgrind suppression file. Or maybe this allocation can be removed altogether because using a single global object as a scratch space does not look very thread-safe. Thanks for the quick answers. From what you say readelf -h --dyn-syms /usr/lib/libQt6Core.so.6 | grep UNIQUE should give something on Fedora. I get nothing on Arch. And indeed it does. 256 UNIQUE DEFAULT symbols. |