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]


Hi!

httpd -X -DHAVE_PHP4 crashes with current CVS glibc.
httpd basically dlopens a whole lot of modules, some of which contain many
dependencies, forks, dlcloses most of the stuff and dlopens everything
again. I've tracked the problem to the new dl-open.c code, where it assumes
that when opening new, all its freshly opened dependencies have l_opencount
0. But as the check is done after relocation processing, l_opencount might
be bumped because of relocation dependency. If this happens, dl_open_worker
adds new to the dependency's l_scope eventhough it was added there by
_dl_new_object when it was created (since new is that dependency's ultimate
loader). This is both inefficient (too long search scope) and causes the
crash (since code in dl-close.c only removes one copy from l_scope, one copy
will remain and thus l_scope[1] points to random garbage).
Here is one possible fix (for freshly loaded dependency last entry in
l_scope will be its ultimate loader and thus we can just compare that
against what we would add), another would be to alloca a old_opencount array
and save there l_opencount entries of each l_searchlist member before
relocating and check that instead of l_opencount later on when testing
whether it should be added to l_scope.
I'll try to cook up a testcase.

2001-09-27  Jakub Jelinek  <jakub@redhat.com>

	* elf/dl-open.c (dl_open_worker): If l_opencount of freshly loaded
	object has been bumped because of relocation dependency, avoid
	duplicates in l_scope.
	(show_scope): Fix typos.

--- libc/elf/dl-open.c.jj	Thu Sep 27 09:25:14 2001
+++ libc/elf/dl-open.c	Thu Sep 27 09:32:12 2001
@@ -316,6 +316,12 @@ dl_open_worker (void *a)
 	    ++runp;
 	  }
 
+	/* This can happen if imap was just loaded, but during relocation
+	   had l_opencount bumped because of relocation dependency.
+	   Avoid duplicates in l_scope.  */
+	if (__builtin_expect (runp [-1] == &new->l_searchlist, 0))
+	  continue;
+
 	if (__builtin_expect (cnt + 1 >= imap->l_scope_max, 0))
 	  {
 	    /* The 'r_scope' array is too small.  Allocate a new one
@@ -478,11 +484,11 @@ show_scope (struct link_map *new)
 
       for (cnt = 0; cnt < new->l_scope[scope_cnt]->r_nlist; ++cnt)
 	if (*new->l_scope[scope_cnt]->r_list[cnt]->l_name)
-	  _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name)
+	  _dl_printf (" %s", new->l_scope[scope_cnt]->r_list[cnt]->l_name);
 	else
-	  _dl_printf (" <main>", NULL);
+	  _dl_printf (" <main>");
 
-      _dl_printf ("\n", NULL);
+      _dl_printf ("\n");
     }
 }
 #endif

	Jakub


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