1: #include <dlfcn.h>
2: #include <libintl.h>
3: #include <link.h>
4: #include <stdio.h>
5: #include <stdlib.h>
6: #include <string.h>
7:
8: #define MAPS ((struct link_map *) _r_debug.r_map)
9:
10: static int
11: check_loaded_objects (const char **loaded)
12: {
13: struct link_map *lm;
14: int n;
15: int *found = NULL;
16: int errors = 0;
17:
18: for (n = 0; loaded[n]; n++)
19: ;
20:
21: if (n)
22: {
23: found = (int *) alloca (sizeof (int) * n);
24: memset (found, 0, sizeof (int) * n);
25: }
26:
27: printf(" Name\n");
28: printf(" --------------------------------------------------------\n");
29: for (lm = MAPS; lm; lm = lm->l_next)
30: {
31: if (lm->l_name && lm->l_name[0])
32: printf(" %s, count = %d\n", lm->l_name, (int) lm->l_direct_opencount);
33: if (lm->l_type == lt_loaded && lm->l_name)
34: {
35: int match = 0;
36: for (n = 0; loaded[n] != NULL; n++)
37: {
38: if (strcmp (basename (loaded[n]), basename (lm->l_name)) == 0)
39: {
40: found[n] = 1;
41: match = 1;
42: break;
43: }
44: }
45:
46: if (match == 0)
47: {
48: ++errors;
49: printf ("ERRORS: %s is not unloaded\n", lm->l_name);
50: }
51: }
52: }
53:
54: for (n = 0; loaded[n] != NULL; n++)
55: {
56: if (found[n] == 0)
57: {
58: ++errors;
59: printf ("ERRORS: %s is not loaded\n", loaded[n]);
60: }
61: }
62:
63: return errors;
64: }
65:
66: int
67: main (void)
68: {
69: void *obj2;
70: void *obj3[2];
71: const char *loaded[] = { NULL, NULL, NULL, NULL };
72: int errors = 0;
73:
74: printf ("\nThis is what is in memory now:\n");
75: errors += check_loaded_objects (loaded);
76: printf ("\nLoading shared object neededobj2.so\n");
77: obj2 = dlopen ("neededobj2.so", RTLD_LAZY);
78: if (obj2 == NULL)
79: {
80: printf ("%s\n", dlerror ());
81: exit (1);
82: }
83: loaded[0] = "neededobj1.so";
84: loaded[1] = "neededobj2.so";
85: errors += check_loaded_objects (loaded);
86: printf ("\nLoading shared object neededobj3.so\n");
87: obj3[0] = dlopen( "neededobj3.so", RTLD_LAZY);
88: if (obj3[0] == NULL)
89: {
90: printf ("%s\n", dlerror ());
91: exit (1);
92: }
93: loaded[2] = "neededobj3.so";
94: errors += check_loaded_objects (loaded);
95: printf ("\nNow loading shared object neededobj3.so again\n");
96: obj3[1] = dlopen ("neededobj3.so", RTLD_LAZY);
97: if (obj3[1] == NULL)
98: {
99: printf ("%s\n", dlerror ());
100: exit (1);
101: }
102: errors += check_loaded_objects (loaded);
103: printf ("\nClosing neededobj3.so once\n");
104: dlclose (obj3[0]);
105: errors += check_loaded_objects (loaded);
106: printf ("\nClosing neededobj2.so\n");
107: dlclose (obj2);
108: errors += check_loaded_objects (loaded);
109: printf ("\nClosing neededobj3.so for the second time\n");
110: dlclose (obj3[1]);
111: loaded[0] = NULL;
112: loaded[1] = NULL;
113: loaded[2] = NULL;
114: errors += check_loaded_objects (loaded);
115: if (errors != 0)
116: printf ("%d errors found\n", errors);
117: return errors;
118: }