* elf/dl-load.c (_dl_init_paths): Don't use strdupa in function
[kopensolaris-gnu/glibc.git] / elf / loadtest.c
index 209f420..863dc53 100644 (file)
@@ -2,12 +2,13 @@
 #include <dlfcn.h>
 #include <errno.h>
 #include <error.h>
+#include <mcheck.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 
 /* How many load/unload operations do we do.  */
-#define TEST_ROUNDS    100
+#define TEST_ROUNDS    1000
 
 
 static struct
@@ -21,6 +22,9 @@ static struct
   { "testobj1.so", NULL },
   { "testobj2.so", NULL },
   { "testobj3.so", NULL },
+  { "testobj4.so", NULL },
+  { "testobj5.so", NULL },
+  { "testobj6.so", NULL },
 };
 #define NOBJS  (sizeof (testobjs) / sizeof (testobjs[0]))
 
@@ -47,18 +51,51 @@ static const struct
   { "obj3func1", 2, RTLD_LAZY | RTLD_GLOBAL },
   { "obj3func1", 2, RTLD_NOW },
   { "obj3func2", 2, RTLD_NOW | RTLD_GLOBAL },
+  { "obj4func2", 3, RTLD_LAZY },
+  { "obj4func1", 3, RTLD_LAZY | RTLD_GLOBAL },
+  { "obj4func1", 3, RTLD_NOW },
+  { "obj4func2", 3, RTLD_NOW | RTLD_GLOBAL },
+  { "obj5func2", 4, RTLD_LAZY },
+  { "obj5func1", 4, RTLD_LAZY | RTLD_GLOBAL },
+  { "obj5func1", 4, RTLD_NOW },
+  { "obj5func2", 4, RTLD_NOW | RTLD_GLOBAL },
+  { "obj6func2", 5, RTLD_LAZY },
+  { "obj6func1", 5, RTLD_LAZY | RTLD_GLOBAL },
+  { "obj6func1", 5, RTLD_NOW },
+  { "obj6func2", 5, RTLD_NOW | RTLD_GLOBAL },
 };
 #define NTESTS (sizeof (tests) / sizeof (tests[0]))
 
 
+#include <include/link.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)
+
+
 int
-main (void)
+main (int argc, char *argv[])
 {
+  int debug = argc > 1 && argv[1][0] != '\0';
   int count = TEST_ROUNDS;
+  int result = 0;
+  struct link_map *map;
+
+  mtrace ();
 
   /* Just a seed.  */
   srandom (TEST_ROUNDS);
 
+  if (debug)
+    {
+      puts ("in the beginning");
+      OUT;
+    }
+
   while (count--)
     {
       int nr = random () % NTESTS;
@@ -87,26 +124,57 @@ main (void)
 
          fct (10);
 
-         printf ("successfully loaded `%s'\n", testobjs[index].name);
+         printf ("successfully loaded `%s', handle %p\n",
+                 testobjs[index].name, testobjs[index].handle);
        }
       else
        {
-         dlclose (testobjs[index].handle);
-         testobjs[index].handle = NULL;
+         if (dlclose (testobjs[index].handle) != 0)
+           {
+             printf ("failed to close %s\n", testobjs[index].name);
+             result = 1;
+           }
+         else
+           printf ("successfully unloaded `%s', handle %p\n",
+                   testobjs[index].name, testobjs[index].handle);
 
-         printf ("successfully unloaded `%s'\n", testobjs[index].name);
+         testobjs[index].handle = NULL;
        }
+
+      if (debug)
+       OUT;
     }
 
   /* Unload all loaded modules.  */
-  for (count = 0; count < NOBJS; ++count)
+  for (count = 0; count < (int) NOBJS; ++count)
     if (testobjs[count].handle != NULL)
-      dlclose (testobjs[count].handle);
-
-  return 0;
+      {
+       printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
+               testobjs[count].name,
+               ((struct link_map*)testobjs[count].handle)->l_initfini,
+               ((struct link_map*)testobjs[count].handle)->l_versions);
+
+       if (dlclose (testobjs[count].handle) != 0)
+         {
+           printf ("failed to close %s\n", testobjs[count].name);
+           result = 1;
+         }
+      }
+
+  /* Check whether all files are unloaded.  */
+  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);
+       result = 1;
+      }
+
+  return result;
 }
 
 
+extern int foo (int a);
 int
 foo (int a)
 {