This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[PATCH] reldep fix


Hi!

As I already wrote in private, I don't understand the add_dependency change
you've made recently, removing it as done with this patch makes no tests
fail and it also fixes the attached testcase. Basically, if I dlopen some
libraries with dependencies and then dlclose them, eventhough there are no
relocation dependencies from main program or other libs which aren't
unloaded, some dependencies are stuck in and not unloaded forever (this is
because of add_dependency code which doesn't only bump opencount of one
library, but all other libs which it is dependent on (and this gets never
undone)).

2001-10-04  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-lookup.c (add_dependency): Only bump l_opencount of the
	dependency.
	* elf/Makefile (tests): Add reldep7.
	(reldep7, reldep7.out): New.
	* elf/reldep7.c: New test.

--- libc/elf/dl-lookup.c.jj	Mon Oct  1 12:25:13 2001
+++ libc/elf/dl-lookup.c	Thu Oct  4 20:28:56 2001
@@ -151,15 +151,8 @@ add_dependency (struct link_map *undef_m
       if (__builtin_expect (act < undef_map->l_reldepsmax, 1))
 	undef_map->l_reldeps[undef_map->l_reldepsact++] = map;
 
-      if (map->l_searchlist.r_list != NULL)
-	/* And increment the counter in the referenced object.  */
-	++map->l_opencount;
-      else
-	/* We have to bump the counts for all dependencies since so far
-	   this object was only a normal or transitive dependency.
-	   Now it might be closed with _dl_close() directly.  */
-	for (list = map->l_initfini; *list != NULL; ++list)
-	  ++(*list)->l_opencount;
+      /* And increment the counter in the referenced object.  */
+      ++map->l_opencount;
 
       /* Display information if we are debugging.  */
       if (__builtin_expect (_dl_debug_mask & DL_DEBUG_FILES, 0))
--- libc/elf/Makefile.jj	Thu Oct  4 18:24:08 2001
+++ libc/elf/Makefile	Thu Oct  4 20:01:20 2001
@@ -107,7 +107,7 @@ tests = loadtest restest1 preloadtest lo
 	reldep reldep2 reldep3 reldep4 $(tests-nodelete-$(have-z-nodelete)) \
 	$(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
 	neededtest3 neededtest4 unload2 lateglobal initfirst global \
-	restest2 next dblload dblunload reldep5 reldep6
+	restest2 next dblload dblunload reldep5 reldep6 reldep7
 test-srcs = tst-pathopt
 tests-vis-yes = vismain
 tests-nodelete-yes = nodelete
@@ -437,3 +437,6 @@ $(objpfx)reldep5.out: $(objpfx)reldepmod
 
 $(objpfx)reldep6: $(libdl)
 $(objpfx)reldep6.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so
+
+$(objpfx)reldep7: $(libdl)
+$(objpfx)reldep7.out: $(objpfx)reldep6mod3.so $(objpfx)reldep6mod4.so
--- libc/elf/reldep7.c.jj	Thu Oct  4 20:01:33 2001
+++ libc/elf/reldep7.c	Thu Oct  4 20:47:37 2001
@@ -0,0 +1,82 @@
+#include <dlfcn.h>
+#include <link.h>
+#include <mcheck.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef int (*fn)(void);
+
+int
+reldep6mod0_check (struct dl_phdr_info *info, size_t size, void *data)
+{
+  if (info->dlpi_name == NULL)
+    return 0;
+
+  if (memcmp (info->dlpi_name + strlen (info->dlpi_name)
+	      - (sizeof "reldep6mod0.so" - 1), "reldep6mod0.so",
+	      sizeof "reldep6mod0.so") == 0)
+    {
+      printf ("reldep6mod0.so was not unloaded\n");
+      exit (1);
+    }
+
+  return 0;
+}
+
+int
+main (void)
+{
+  void *h1;
+  void *h2;
+  fn **foopp;
+
+  mtrace ();
+
+  /* Open the two objects.  */
+  h1 = dlopen ("reldep6mod3.so", RTLD_LAZY);
+  if (h1 == NULL)
+    {
+      printf ("cannot open reldep6mod3.so: %s\n", dlerror ());
+      exit (1);
+    }
+
+  foopp = dlsym (h1, "foopp");
+  if (foopp == NULL)
+    {
+      printf ("cannot get address of \"foopp\": %s\n", dlerror ());
+      exit (1);
+    }
+  if ((**foopp) () != 20)
+    {
+      printf ("(**foopp)() did not return 20\n");
+      exit (1);
+    }
+
+  h2 = dlopen ("reldep6mod4.so", RTLD_LAZY);
+  if (h2 == NULL)
+    {
+      printf ("cannot open reldep6mod4.so: %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (dlclose (h1) != 0)
+    {
+      printf ("closing h1 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (dlclose (h2) != 0)
+    {
+      printf ("closing h1 failed: %s\n", dlerror ());
+      exit (1);
+    }
+
+  if (dl_iterate_phdr (reldep6mod0_check, NULL) < 0)
+    {
+      printf ("dl_iterate_phdr failed\n");
+      exit (1);
+    }
+
+  return 0;
+}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]