Browse Source

libdl: add option for controlling dl_cleanup

When debugging memory leaks with Valgrind, it is required that
dynamically loaded shared objects are not unloaded when a process exits,
otherwise symbols from those files aren't correctly resolved in
allocation traces. This patch adds the LDSO_NO_CLEANUP configuration
option to control this behaviour.

Signed-off-by: Richard Braun <rbraun@sceen.net>
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Richard Braun 13 years ago
parent
commit
3d5cec4ff7
3 changed files with 19 additions and 1 deletions
  1. 12 0
      extra/Configs/Config.in
  2. 5 1
      ldso/libdl/Makefile.in
  3. 2 0
      ldso/libdl/libdl.c

+ 12 - 0
extra/Configs/Config.in

@@ -417,6 +417,18 @@ config LDSO_SEARCH_INTERP_PATH
 
 	  If unsure, simply say Y here.
 
+config LDSO_NO_CLEANUP
+	bool "Disable automatic unloading of dynamically loaded shared objects"
+	depends on HAVE_SHARED
+	default n
+	help
+	  If you need complete allocation traces when debugging memory leaks
+	  using Valgrind in a process that dynamically loads shared objects,
+	  then answer Y here. Unlike glibc, uClibc unloads all dynamically
+	  loaded shared objects when a process exits, which prevents Valgrind
+	  from correctly resolving the symbols from the unloaded shared objects.
+	  Unless you know you need this, you should answer N.
+
 config UCLIBC_CTOR_DTOR
 	bool "Support global constructors and destructors"
 	default y

+ 5 - 1
ldso/libdl/Makefile.in

@@ -20,7 +20,11 @@ endif
 CFLAGS-libdl.c := -DLDSO_ELFINTERP=\"$(TARGET_ARCH)/elfinterp.c\"
 
 LDFLAGS-$(UCLIBC_FORMAT_DSBT_ELF)-libdl.so := -Wl,--dsbt-index=3
-LDFLAGS-libdl.so := $(LDFLAGS) -Wl,-fini,dl_cleanup
+LDFLAGS-libdl.so := $(LDFLAGS)
+
+ifeq ($(LDSO_NO_CLEANUP),)
+LDFLAGS-libdl.so += -Wl,-fini,dl_cleanup
+endif
 
 LIBS-libdl.so := $(LIBS) $(ldso)
 

+ 2 - 0
ldso/libdl/libdl.c

@@ -260,6 +260,7 @@ remove_slotinfo(size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 }
 #endif
 
+#ifndef __LDSO_NO_CLEANUP__
 void dl_cleanup(void) __attribute__ ((destructor));
 void dl_cleanup(void)
 {
@@ -270,6 +271,7 @@ void dl_cleanup(void)
 		do_dlclose(h, 1);
 	}
 }
+#endif
 
 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
 	struct elf_resolve *map)