(linenum→info "unix/slp.c:2238")

glibc/2.7/elf/loadtest.c

    1: #include <assert.h>
    2: #include <dlfcn.h>
    3: #include <errno.h>
    4: #include <error.h>
    5: #include <mcheck.h>
    6: #include <stdio.h>
    7: #include <stdlib.h>
    8: #include <string.h>
    9: 
   10: 
   11: /* How many load/unload operations do we do.  */
   12: #define TEST_ROUNDS     1000
   13: 
   14: 
   15: static struct
   16: {
   17:   /* Name of the module.  */
   18:   const char *name;
   19:   /* The handle.  */
   20:   void *handle;
   21: } testobjs[] =
   22: {
   23:   { "testobj1.so", NULL },
   24:   { "testobj2.so", NULL },
   25:   { "testobj3.so", NULL },
   26:   { "testobj4.so", NULL },
   27:   { "testobj5.so", NULL },
   28:   { "testobj6.so", NULL },
   29: };
   30: #define NOBJS   (sizeof (testobjs) / sizeof (testobjs[0]))
   31: 
   32: 
   33: static const struct
   34: {
   35:   /* Name of a function to call.  */
   36:   const char *fname;
   37:   /* Index in status and handle array.  */
   38:   int index;
   39:   /* Options while loading the module.  */
   40:   int options;
   41: } tests[] =
   42: {
   43:   { "obj1func2", 0, RTLD_LAZY },
   44:   { "obj1func1", 0, RTLD_LAZY | RTLD_GLOBAL },
   45:   { "obj1func1", 0, RTLD_NOW, },
   46:   { "obj1func2", 0, RTLD_NOW | RTLD_GLOBAL },
   47:   { "obj2func2", 1, RTLD_LAZY },
   48:   { "obj2func1", 1, RTLD_LAZY | RTLD_GLOBAL, },
   49:   { "obj2func1", 1, RTLD_NOW, },
   50:   { "obj2func2", 1, RTLD_NOW | RTLD_GLOBAL },
   51:   { "obj3func2", 2, RTLD_LAZY },
   52:   { "obj3func1", 2, RTLD_LAZY | RTLD_GLOBAL },
   53:   { "obj3func1", 2, RTLD_NOW },
   54:   { "obj3func2", 2, RTLD_NOW | RTLD_GLOBAL },
   55:   { "obj4func2", 3, RTLD_LAZY },
   56:   { "obj4func1", 3, RTLD_LAZY | RTLD_GLOBAL },
   57:   { "obj4func1", 3, RTLD_NOW },
   58:   { "obj4func2", 3, RTLD_NOW | RTLD_GLOBAL },
   59:   { "obj5func2", 4, RTLD_LAZY },
   60:   { "obj5func1", 4, RTLD_LAZY | RTLD_GLOBAL },
   61:   { "obj5func1", 4, RTLD_NOW },
   62:   { "obj5func2", 4, RTLD_NOW | RTLD_GLOBAL },
   63:   { "obj6func2", 5, RTLD_LAZY },
   64:   { "obj6func1", 5, RTLD_LAZY | RTLD_GLOBAL },
   65:   { "obj6func1", 5, RTLD_NOW },
   66:   { "obj6func2", 5, RTLD_NOW | RTLD_GLOBAL },
   67: };
   68: #define NTESTS  (sizeof (tests) / sizeof (tests[0]))
   69: 
   70: 
   71: #include <include/link.h>
   72: 
   73: #define MAPS ((struct link_map *) _r_debug.r_map)
   74: 
   75: #define OUT \
   76:   for (map = MAPS; map != NULL; map = map->l_next)                    \
   77:     if (map->l_type == lt_loaded)                                             \
   78:       printf ("name = \"%s\", direct_opencount = %d\n",                       \
   79:               map->l_name, (int) map->l_direct_opencount);                   \
   80:   fflush (stdout)
   81: 
   82: 
   83: int
   84: main (int argc, char *argv[])
   85: {
   86:   int debug = argc > 1 && argv[1][0] != '\0';
   87:   int count = TEST_ROUNDS;
   88:   int result = 0;
   89:   struct link_map *map;
   90: 
   91:   mtrace ();
   92: 
   93:   /* Just a seed.  */
   94:   srandom (TEST_ROUNDS);
   95: 
   96:   if (debug)
   97:     {
   98:       puts ("in the beginning");
   99:       OUT;
  100:     }
  101: 
  102:   while (count--)
  103:     {
  104:       int nr = random () % NTESTS;
  105:       int index = tests[nr].index;
  106: 
  107:       printf ("%4d: %4d: ", count + 1, nr);
  108:       fflush (stdout);
  109: 
  110:       if (testobjs[index].handle == NULL)
  111:         {
  112:           int (*fct) (int);
  113: 
  114:           /* Load the object.  */
  115:           testobjs[index].handle = dlopen (testobjs[index].name,
  116:                                            tests[nr].options);
  117:           if (testobjs[index].handle == NULL)
  118:             error (EXIT_FAILURE, 0, "cannot load `%s': %s",
  119:                    testobjs[index].name, dlerror ());
  120: 
  121:           /* Test the function call.  */
  122:           fct = dlsym (testobjs[index].handle, tests[nr].fname);
  123:           if (fct == NULL)
  124:             error (EXIT_FAILURE, 0,
  125:                    "cannot get function `%s' from shared object `%s': %s",
  126:                    tests[nr].fname, testobjs[index].name, dlerror ());
  127: 
  128:           fct (10);
  129: 
  130:           printf ("successfully loaded `%s', handle %p\n",
  131:                   testobjs[index].name, testobjs[index].handle);
  132:         }
  133:       else
  134:         {
  135:           if (dlclose (testobjs[index].handle) != 0)
  136:             {
  137:               printf ("failed to close %s\n", testobjs[index].name);
  138:               result = 1;
  139:             }
  140:           else
  141:             printf ("successfully unloaded `%s', handle %p\n",
  142:                     testobjs[index].name, testobjs[index].handle);
  143: 
  144:           testobjs[index].handle = NULL;
  145: 
  146:           if (testobjs[0].handle == NULL
  147:               && testobjs[1].handle == NULL
  148:               && testobjs[5].handle == NULL)
  149:             {
  150:               /* In this case none of the objects above should be
  151:                  present.  */
  152:               for (map = MAPS; map != NULL; map = map->l_next)
  153:                 if (map->l_type == lt_loaded
  154:                     && (strstr (map->l_name, testobjs[0].name) != NULL
  155:                         || strstr (map->l_name, testobjs[1].name) != NULL
  156:                         || strstr (map->l_name, testobjs[5].name) != NULL))
  157:                   {
  158:                     printf ("`%s' is still loaded\n", map->l_name);
  159:                     result = 1;
  160:                   }
  161:             }
  162:         }
  163: 
  164:       if (debug)
  165:         OUT;
  166:     }
  167: 
  168:   /* Unload all loaded modules.  */
  169:   for (count = 0; count < (int) NOBJS; ++count)
  170:     if (testobjs[count].handle != NULL)
  171:       {
  172:         printf ("\nclose: %s: l_initfini = %p, l_versions = %p\n",
  173:                 testobjs[count].name,
  174:                 ((struct link_map *) testobjs[count].handle)->l_initfini,
  175:                 ((struct link_map *) testobjs[count].handle)->l_versions);
  176: 
  177:         if (dlclose (testobjs[count].handle) != 0)
  178:           {
  179:             printf ("failed to close %s\n", testobjs[count].name);
  180:             result = 1;
  181:           }
  182:       }
  183: 
  184:   /* Check whether all files are unloaded.  */
  185:   for (map = MAPS; map != NULL; map = map->l_next)
  186:     if (map->l_type == lt_loaded)
  187:       {
  188:         printf ("name = \"%s\", direct_opencount = %d\n",
  189:                 map->l_name, (int) map->l_direct_opencount);
  190:         result = 1;
  191:       }
  192: 
  193:   return result;
  194: }
  195: 
  196: 
  197: extern int foo (int a);
  198: int
  199: foo (int a)
  200: {
  201:   return a - 1;
  202: }
Syntax (Markdown)