This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
On Thu, Oct 19, 2000 at 11:32:10AM -0700, Ulrich Drepper wrote:
> "H . J . Lu" <hjl@lucon.org> writes:
>
> > I don't think they are the same list. One is map->l_initfini and
> > the other is map->l_searchlist.r_list. Ulrich, are they the same list?
>
> I will look at this when I have the time.
>
Here is a testcase based on Allen's report.
H.J.
---
2000-10-19 H.J. Lu <hjl@gnu.org>
* elf/Makefile (distribute): Add neededtest.c, neededobj1.c,
neededobj2.c and neededobj3.c.
(tests): Add neededtest.
(modules-names): Add neededobj1, neededobj2 and neededobj3.
($(objpfx)neededobj1.so): New target.
($(objpfx)neededobj2.so): Likewise.
($(objpfx)neededobj3.so): Likewise.
($(objpfx)neededtest): Likewise.
($(objpfx)neededtest.out): Likewise.
* elf/neededtest.c: New. Based on the bug report from
"Allen Bauer" <kylix_rd@hotmail.com>.
* elf/neededobj1.c: Likewise.
* elf/neededobj2.c: Likewise.
* elf/neededobj3.c: Likewise.
Index: elf/Makefile
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/Makefile,v
retrieving revision 1.1.1.19
diff -u -p -r1.1.1.19 Makefile
--- elf/Makefile 2000/10/19 02:39:01 1.1.1.19
+++ elf/Makefile 2000/10/19 19:26:48
@@ -53,7 +53,8 @@ distribute := $(rtld-routines:=.c) dynam
nodlopenmod.c nodelete.c nodelmod1.c nodelmod2.c \
nodelmod3.c nodelmod4.c nodlopen.c dl-osinfo.h \
reldepmod1.c reldepmod2.c reldepmod3.c reldepmod4.c \
- nextmod1.c nextmod2.c
+ nextmod1.c nextmod2.c \
+ neededtest.c neededobj1.c neededobj2.c neededobj3.c
include ../Makeconfig
@@ -95,7 +96,7 @@ ifeq (yes,$(build-shared))
tests = loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
constload1 order $(tests-vis-$(have-protected)) noload filter unload \
reldep reldep2 reldep3 next $(tests-nodelete-$(have-z-nodelete)) \
- $(tests-nodlopen-$(have-z-nodlopen))
+ $(tests-nodlopen-$(have-z-nodlopen)) neededtest
tests-vis-yes = vismain
tests-nodelete-yes = nodelete
tests-nodlopen-yes = nodlopen
@@ -105,7 +106,8 @@ modules-names = testobj1 testobj2 testob
dep1 dep2 dep3 dep4 $(modules-vis-$(have-protected)) \
$(modules-nodelete-$(have-z-nodelete)) \
$(modules-nodlopen-$(have-z-nodlopen)) filtmod1 filtmod2 \
- reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2
+ reldepmod1 reldepmod2 reldepmod3 reldepmod4 nextmod1 nextmod2 \
+ neededobj1 neededobj2 neededobj3
modules-vis-yes = vismod1 vismod2 vismod3
modules-nodelete-yes = nodelmod1 nodelmod2 nodelmod3 nodelmod4
modules-nodlopen-yes = nodlopenmod
@@ -249,6 +251,10 @@ $(objpfx)dep4.so: $(objpfx)dep3.so
$(objpfx)nodelmod3.so: $(objpfx)nodelmod4.so
$(objpfx)nextmod1.so: $(libdl)
+$(objpfx)neededobj1.so: $(libdl)
+$(objpfx)neededobj2.so: $(objpfx)neededobj1.so $(libdl)
+$(objpfx)neededobj3.so: $(objpfx)neededobj1.so $(objpfx)neededobj2.so $(libdl)
+
# filtmod1.so has a special rule
$(filter-out $(objpfx)filtmod1.so, $(test-modules)): $(objpfx)%.so: $(objpfx)%.os
$(build-module)
@@ -257,6 +263,11 @@ $(objpfx)loadtest: $(libdl)
LDFLAGS-loadtest = -rdynamic
$(objpfx)loadtest.out: $(test-modules)
+
+$(objpfx)neededtest: $(libdl)
+
+$(objpfx)neededtest.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
+ $(objpfx)neededobj3.so
$(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
LDFLAGS-restest1 = -rdynamic
--- /dev/null Thu Aug 24 02:00:32 2000
+++ elf/neededobj1.c Thu Oct 19 12:13:23 2000
@@ -0,0 +1,3 @@
+void c_function(void)
+{
+}
--- /dev/null Thu Aug 24 02:00:32 2000
+++ elf/neededobj2.c Thu Oct 19 12:13:23 2000
@@ -0,0 +1,6 @@
+void c_function ();
+
+void b_function(void)
+{
+ c_function();
+}
--- /dev/null Thu Aug 24 02:00:32 2000
+++ elf/neededobj3.c Thu Oct 19 12:13:23 2000
@@ -0,0 +1,8 @@
+void b_function(void);
+void c_function(void);
+
+void a_function (void)
+{
+ b_function();
+ c_function();
+}
--- /dev/null Thu Aug 24 02:00:32 2000
+++ elf/neededtest.c Thu Oct 19 12:43:48 2000
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <link.h>
+
+static int
+check_loaded_objects(const char **loaded)
+{
+ struct link_map *lm;
+ int n;
+ int *found = NULL;
+ int error = 0;
+
+ for (n = 0; loaded [n]; n++);
+
+ if (n)
+ {
+ found = (int *) alloca (sizeof (int) * n);
+ memset (found, 0, sizeof (int) * n);
+ }
+
+ printf(" Name\n");
+ printf(" --------------------------------------------------------\n");
+ for (lm = _r_debug.r_map; lm; lm = lm->l_next)
+ {
+ if (lm->l_name && lm->l_name [0])
+ printf(" %s\n", lm->l_name);
+ if (lm->l_type == lt_loaded && lm->l_name)
+ {
+ int match = 0;
+ for (n = 0; loaded [n]; n++)
+ {
+ if (strcmp (basename (loaded [n]), basename (lm->l_name)) == 0)
+ {
+ found [n] = 1;
+ match = 1;
+ break;
+ }
+ }
+
+ if (!match)
+ {
+ error++;
+ printf ("ERROR: %s is not unloaded\n", lm->l_name);
+ }
+ }
+ }
+
+ for (n = 0; loaded [n]; n++)
+ {
+ if (!found [n])
+ {
+ error++;
+ printf ("ERROR: %s is not loaded\n", loaded [n]);
+ }
+ }
+
+ return error;
+}
+
+int
+main(void)
+{
+ void *obj2;
+ void *obj3;
+ const char *loaded [] = { NULL, NULL, NULL, NULL};
+ int error = 0;
+
+ printf("\nThis is what is in memory now:\n");
+ error += check_loaded_objects (loaded);
+ printf("Loading shared object neededobj3.so\n");
+ obj3 = dlopen("neededobj3.so", RTLD_LAZY);
+ if (!obj3)
+ {
+ printf("%s\n", dlerror());
+ exit(1);
+ }
+ printf("And this is what is now in memory\n");
+ loaded [0] = "neededobj1.so";
+ loaded [1] = "neededobj2.so";
+ loaded [2] = "neededobj3.so";
+ error += check_loaded_objects (loaded);
+ printf("Now loading shared object neededobj2.so\n");
+ obj2 = dlopen("neededobj2.so", RTLD_LAZY);
+ if (!obj2)
+ {
+ printf("%s\n", dlerror());
+ exit(1);
+ }
+ printf("Again, this is what is in memory\n");
+ error += check_loaded_objects (loaded);
+ printf("Closing neededobj2.so\n");
+ dlclose(obj2);
+ error += check_loaded_objects (loaded);
+ printf("Closing neededobj3.so\n");
+ dlclose(obj3);
+ loaded [0] = NULL;
+ error += check_loaded_objects (loaded);
+ if (error)
+ printf ("%d errors found\n", error);
+ return error;
+}
- References:
- Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)
- Re: Reference counting bug in ld-linux.so.2 (2.1.2, 2.1.3, 2.1.9x, et. al.)