aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--elf/Makefile8
-rw-r--r--elf/neededtest.c22
-rw-r--r--elf/neededtest2.c116
-rw-r--r--elf/unload.c34
5 files changed, 175 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index ff7a80b2c0..3057fe7711 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2000-10-23 Ulrich Drepper <drepper@redhat.com>
+ * elf/unload.c: Generate more debugging output.
+
+ * elf/neededtest.c: Make it more complicated.
+ * elf/neededtest2.c: New file.
+ * elf/Makefile: Add rules to build and run neededtest2.
+
* elf/dl-sym.c (_dl_sym): Use exact check for caller PC in range
of DSO address space.
(_dl_vsym): Likewise.
diff --git a/elf/Makefile b/elf/Makefile
index 06ff79d30a..ad89103808 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -97,7 +97,8 @@ 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)) neededtest unload2 lateglobal
+ $(tests-nodlopen-$(have-z-nodlopen)) neededtest neededtest2 \
+ unload2 lateglobal
tests-vis-yes = vismain
tests-nodelete-yes = nodelete
tests-nodlopen-yes = nodlopen
@@ -268,10 +269,13 @@ LDFLAGS-loadtest = -rdynamic
$(objpfx)loadtest.out: $(test-modules)
$(objpfx)neededtest: $(libdl)
-
$(objpfx)neededtest.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
$(objpfx)neededobj3.so
+$(objpfx)neededtest2: $(libdl)
+$(objpfx)neededtest2.out: $(objpfx)neededobj1.so $(objpfx)neededobj2.so \
+ $(objpfx)neededobj3.so
+
$(objpfx)restest1: $(objpfx)testobj1.so $(objpfx)testobj1_1.so $(libdl)
LDFLAGS-restest1 = -rdynamic
diff --git a/elf/neededtest.c b/elf/neededtest.c
index 98f69a3185..a33d243651 100644
--- a/elf/neededtest.c
+++ b/elf/neededtest.c
@@ -64,7 +64,7 @@ check_loaded_objects (const char **loaded)
int
main (void)
{
- void *obj2;
+ void *obj2[2];
void *obj3;
const char *loaded[] = { NULL, NULL, NULL, NULL };
int errors = 0;
@@ -84,7 +84,16 @@ main (void)
loaded[2] = "neededobj3.so";
errors += check_loaded_objects (loaded);
printf ("Now loading shared object neededobj2.so\n");
- obj2 = dlopen ("neededobj2.so", RTLD_LAZY);
+ obj2[0] = dlopen ("neededobj2.so", RTLD_LAZY);
+ if (obj2 == NULL)
+ {
+ printf ("%s\n", dlerror ());
+ exit (1);
+ }
+ printf ("After loading neededobj2.so once\n");
+ errors += check_loaded_objects (loaded);
+ printf ("And loading shared object neededobj2.so again\n");
+ obj2[1] = dlopen ("neededobj2.so", RTLD_LAZY);
if (obj2 == NULL)
{
printf ("%s\n", dlerror ());
@@ -92,12 +101,17 @@ main (void)
}
printf ("Again, this is what is in memory\n");
errors += check_loaded_objects (loaded);
- printf ("Closing neededobj2.so\n");
- dlclose (obj2);
+ printf ("Closing neededobj2.so for the first time\n");
+ dlclose (obj2[0]);
errors += check_loaded_objects (loaded);
printf ("Closing neededobj3.so\n");
dlclose (obj3);
+ loaded[2] = NULL;
+ errors += check_loaded_objects (loaded);
+ printf ("Closing neededobj2.so for the second time\n");
+ dlclose (obj2[1]);
loaded[0] = NULL;
+ loaded[1] = NULL;
errors += check_loaded_objects (loaded);
if (errors != 0)
printf ("%d errors found\n", errors);
diff --git a/elf/neededtest2.c b/elf/neededtest2.c
new file mode 100644
index 0000000000..cf111bc303
--- /dev/null
+++ b/elf/neededtest2.c
@@ -0,0 +1,116 @@
+#include <dlfcn.h>
+#include <libintl.h>
+#include <link.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int
+check_loaded_objects (const char **loaded)
+{
+ struct link_map *lm;
+ int n;
+ int *found = NULL;
+ int errors = 0;
+
+ for (n = 0; loaded[n]; n++)
+ /* NOTHING */;
+
+ 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, count = %d\n", lm->l_name, (int) lm->l_opencount);
+ if (lm->l_type == lt_loaded && lm->l_name)
+ {
+ int match = 0;
+ for (n = 0; loaded[n] != NULL; n++)
+ {
+ if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
+ {
+ found[n] = 1;
+ match = 1;
+ break;
+ }
+ }
+
+ if (match == 0)
+ {
+ ++errors;
+ printf ("ERRORS: %s is not unloaded\n", lm->l_name);
+ }
+ }
+ }
+
+ for (n = 0; loaded[n] != NULL; n++)
+ {
+ if (found[n] == 0)
+ {
+ ++errors;
+ printf ("ERRORS: %s is not loaded\n", loaded[n]);
+ }
+ }
+
+ return errors;
+}
+
+int
+main (void)
+{
+ void *obj2;
+ void *obj3[2];
+ const char *loaded[] = { NULL, NULL, NULL, NULL };
+ int errors = 0;
+
+ printf ("\nThis is what is in memory now:\n");
+ errors += check_loaded_objects (loaded);
+ printf ("\nLoading shared object neededobj2.so\n");
+ obj2 = dlopen ("neededobj2.so", RTLD_LAZY);
+ if (obj2 == NULL)
+ {
+ printf ("%s\n", dlerror ());
+ exit (1);
+ }
+ loaded[0] = "neededobj1.so";
+ loaded[1] = "neededobj2.so";
+ errors += check_loaded_objects (loaded);
+ printf ("\nLoading shared object neededobj3.so\n");
+ obj3[0] = dlopen( "neededobj3.so", RTLD_LAZY);
+ if (obj3[0] == NULL)
+ {
+ printf ("%s\n", dlerror ());
+ exit (1);
+ }
+ loaded[2] = "neededobj3.so";
+ errors += check_loaded_objects (loaded);
+ printf ("\nNow loading shared object neededobj3.so again\n");
+ obj3[1] = dlopen ("neededobj3.so", RTLD_LAZY);
+ if (obj3[1] == NULL)
+ {
+ printf ("%s\n", dlerror ());
+ exit (1);
+ }
+ errors += check_loaded_objects (loaded);
+ printf ("\nClosing neededobj3.so once\n");
+ dlclose (obj3[0]);
+ errors += check_loaded_objects (loaded);
+ printf ("\nClosing neededobj2.so\n");
+ dlclose (obj2);
+ errors += check_loaded_objects (loaded);
+ printf ("\nClosing neededobj3.so for the second time\n");
+ dlclose (obj3[1]);
+ loaded[0] = NULL;
+ loaded[1] = NULL;
+ loaded[2] = NULL;
+ errors += check_loaded_objects (loaded);
+ if (errors != 0)
+ printf ("%d errors found\n", errors);
+ return errors;
+}
diff --git a/elf/unload.c b/elf/unload.c
index 2789abd5bb..4fd82b7e3a 100644
--- a/elf/unload.c
+++ b/elf/unload.c
@@ -4,10 +4,18 @@
require it for glibc. */
#include <dlfcn.h>
+#include <link.h>
#include <mcheck.h>
#include <stdio.h>
#include <stdlib.h>
+#define OUT \
+ for (map = _r_debug.r_map; map != NULL; map = map->l_next) \
+ if (map->l_type == lt_loaded) \
+ printf ("name = \"%s\", opencount = %d\n", \
+ map->l_name, (int) map->l_opencount); \
+ fflush (stdout)
+
typedef struct
{
void *next;
@@ -20,46 +28,62 @@ main (void)
strct *testdat;
int ret;
int result = 0;
+ struct link_map *map;
mtrace ();
+ puts ("\nBefore");
+ OUT;
+
sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
if (sohandle == NULL)
{
- printf ("first dlopen failed: %s\n", dlerror ());
+ printf ("*** first dlopen failed: %s\n", dlerror ());
exit (1);
}
+ puts ("\nAfter loading unloadmod.so");
+ OUT;
+
testdat = dlsym (sohandle, "testdat");
testdat->next = (void *) -1;
ret = dlclose (sohandle);
if (ret != 0)
{
- puts ("first dlclose failed");
+ puts ("*** first dlclose failed");
result = 1;
}
+ puts ("\nAfter closing unloadmod.so");
+ OUT;
+
sohandle = dlopen ("unloadmod.so", RTLD_NOW | RTLD_GLOBAL);
if (sohandle == NULL)
{
- printf ("second dlopen failed: %s\n", dlerror ());
+ printf ("*** second dlopen failed: %s\n", dlerror ());
exit (1);
}
+ puts ("\nAfter loading unloadmod.so the second time");
+ OUT;
+
testdat = dlsym (sohandle, "testdat");
if (testdat->next == (void *) -1)
{
- puts ("testdat->next == (void *) -1");
+ puts ("*** testdat->next == (void *) -1");
result = 1;
}
ret = dlclose (sohandle);
if (ret != 0)
{
- puts ("second dlclose failed");
+ puts ("*** second dlclose failed");
result = 1;
}
+ puts ("\nAfter closing unloadmod.so again");
+ OUT;
+
return result;
}