1 #include <dlfcn.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include "test.h"
5
6 #define SO_HAS_DEPENDENCES "libdlopen_so_dep_dlopen_ns_dso.so"
7 const char* dllName = "libdlopen_ns_dso.so";
8 const char* dllName2 = "libdlopen_dso.so";
9 const char* errPath_ns = "/src/common";
10 const char* ndk_so = "libdlopen_ns_dso_ndk.so";
11 const char* system_so = "libdlopen_ns_dso_sys.so";
12 typedef void*(*CALL_DLOPEN_PTR)(const char *);
13
14 // Test whether it is ok for main to dlopen ndk so.
main_dlopen_ndk_so()15 void main_dlopen_ndk_so()
16 {
17 void *handle = dlopen(ndk_so, RTLD_NOW);
18 if (!handle)
19 t_error("main dlopen ndk so %s failed: %s\n", ndk_so, dlerror());
20 if (dlclose(handle))
21 t_error("dlclose %s failed : %s \n", ndk_so, dlerror());
22 }
23
24 // Test whether it is ok for system so to dlopen ndk so.
system_so_dlopen_ndk_so()25 void system_so_dlopen_ndk_so()
26 {
27 void *handle = dlopen(system_so, RTLD_NOW);
28 if (!handle) {
29 t_error("dlopen %s failed : %s \n", system_so, dlerror());
30 }
31 CALL_DLOPEN_PTR call_dlopen = dlsym(handle, "call_dlopen");
32 if (!call_dlopen) {
33 t_error("dlsym %s failed : %s \n", "call_dlopen", dlerror());
34 }
35 void *res = call_dlopen(ndk_so);
36 if (!res) {
37 t_error("default ns so(%s) can't dlopen ndk so(%s)", system_so, ndk_so);
38 }
39 }
40
41 // Test whether it is ok for ndk so to dlopen system so.
ndk_so_dlopen_default_ns_so()42 void ndk_so_dlopen_default_ns_so()
43 {
44 Dl_namespace dlns;
45 dlns_init(&dlns, "ndk");
46 void *handle = dlopen_ns(&dlns, ndk_so, RTLD_NOW);
47 if (!handle) {
48 t_error("dlopen_ns(ns=%s, so=%s) failed : %s \n", "ndk", ndk_so, dlerror());
49 }
50 CALL_DLOPEN_PTR call_dlopen = dlsym(handle, "call_dlopen");
51 if (!call_dlopen) {
52 t_error("dlsym %s failed : %s \n", "call_dlopen", dlerror());
53 }
54 void *res = call_dlopen(system_so);
55 if (!res) {
56 t_error("ndk so(%s) can't dlopen system so(%s)", ndk_so, system_so);
57 }
58 }
59
60 // Test whether dlopen same so twice by same ns to get same handle.
dlopen_same_so_twice_by_same_ns(char * dllPath_ns)61 void dlopen_same_so_twice_by_same_ns(char * dllPath_ns)
62 {
63 Dl_namespace dlns1;
64 dlns_init(&dlns1, "ns_for_dlopen_same_so_twice_by_same_ns");
65 dlns_create(&dlns1, dllPath_ns);
66
67 void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW);
68 if(!handle1)
69 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror());
70
71 void* handle2 = dlopen_ns(&dlns1, dllName, RTLD_NOW);
72 if(!handle2)
73 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror());
74
75 if (handle1 != handle2)
76 t_error("dlopen same so(%s) by same ns but handle is different %s \n", dllName);
77
78 if(dlclose(handle1))
79 t_error("dlclose %s failed : %s \n", dllName, dlerror());
80
81 if(dlclose(handle2))
82 t_error("dlclose %s failed : %s \n", dllName, dlerror());
83 }
84
85 // Test whether dlopen same so by different ns to get different handle.
dlopen_same_so_by_different_ns(char * dllPath_ns)86 void dlopen_same_so_by_different_ns(char * dllPath_ns)
87 {
88 Dl_namespace dlns1;
89 dlns_init(&dlns1, "ns_for_dlopen_same_so_by_different_ns_1");
90 dlns_create(&dlns1, dllPath_ns);
91
92 Dl_namespace dlns2;
93 dlns_init(&dlns2, "ns_for_dlopen_same_so_by_different_ns_2");
94 dlns_create(&dlns2, dllPath_ns);
95
96 void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW);
97 if(!handle1)
98 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror());
99
100 void* handle2 = dlopen_ns(&dlns2, dllName, RTLD_NOW);
101 if(!handle2)
102 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns2.name, dllName, dlerror());
103
104 if (handle1 == handle2)
105 t_error("dlopen same so(%s) by same ns but handle is different %s \n", dllName);
106
107 if(dlclose(handle1))
108 t_error("dlclose %s failed : %s \n", dllName, dlerror());
109
110 if(dlclose(handle2))
111 t_error("dlclose %s failed : %s \n", dllName, dlerror());
112 }
113
114 // Test whether dlopen same so by inherit ns to get same handle.
dlopen_same_so_by_different_inherit_ns(char * dllPath_ns)115 void dlopen_same_so_by_different_inherit_ns(char * dllPath_ns)
116 {
117 Dl_namespace dlns1;
118 dlns_init(&dlns1, "ns_for_dlopen_same_so_by_different_inherit_ns_1");
119 dlns_create(&dlns1, dllPath_ns);
120
121 Dl_namespace dlns2;
122 dlns_init(&dlns2, "ns_for_dlopen_same_so_by_different_inherit_ns_2");
123 dlns_create2(&dlns2, errPath_ns, 0);
124 dlns_inherit(&dlns2, &dlns1, dllName);
125
126 void* handle1 = dlopen_ns(&dlns1, dllName, RTLD_NOW);
127 if(!handle1)
128 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror());
129
130 void* handle2 = dlopen_ns(&dlns2, dllName, RTLD_NOW);
131 if(!handle2)
132 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns2.name, dllName, dlerror());
133
134 if (handle1 != handle2)
135 t_error("dlopen same so(%s) by inherit ns but handle is different %s \n", dllName);
136
137 if(dlclose(handle1))
138 t_error("dlclose %s failed : %s \n", dllName, dlerror());
139
140 if(dlclose(handle2))
141 t_error("dlclose %s failed : %s \n", dllName, dlerror());
142 }
143
dlopen_seperated(char * dllPath_ns)144 void dlopen_seperated(char * dllPath_ns)
145 {
146 Dl_namespace dlns1;
147 dlns_init(&dlns1, "ns_for_no_seperated");
148 dlns_create2(&dlns1, errPath_ns, 0);
149
150 void* handle = NULL;
151 // current ns can't load this so.
152 handle = dlopen_ns(&dlns1, dllName, RTLD_NOW);
153 if(handle)
154 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror());
155
156 // current ns can load the so by absolute path.
157 char absolute_path_1[512];
158 snprintf(absolute_path_1, sizeof(absolute_path_1), "%s/%s", dllPath_ns, dllName);
159 handle = dlopen_ns(&dlns1, absolute_path_1, RTLD_NOW);
160 if (!handle)
161 t_error("%s can load %s by absolute path but failed : %s \n", dlns1.name, absolute_path_1, dlerror());
162
163 if(dlclose(handle))
164 t_error("dlclose %s failed : %s \n", absolute_path_1, dlerror());
165
166 // current ns can't load the so by absolute path if it has inaccessible dependent so.
167 char absolute_path_2[512];
168 snprintf(absolute_path_2, sizeof(absolute_path_2), "%s/%s", dllPath_ns, SO_HAS_DEPENDENCES);
169 handle = dlopen_ns(&dlns1, absolute_path_2, RTLD_NOW);
170 if (handle)
171 t_error("%s can't load %s by absolute path because but it has inaccessible dependent so but succeed : %s \n", dlns1.name, absolute_path_2, dlerror());
172 }
173
dlopen_inherit(char * dllPath_ns)174 void dlopen_inherit(char* dllPath_ns)
175 {
176 Dl_namespace inherit_A, inherit_B;
177 dlns_init(&inherit_A, "inherir_error_lib_A");
178 dlns_init(&inherit_B, "inherir_error_lib_B");
179 dlns_create2(&inherit_A, NULL, 0);
180 dlns_create2(&inherit_B, dllPath_ns, 0);
181
182 // inherit_A can't load the so because search path is NULL.
183 void* handle1 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY);
184 if(handle1){
185 t_error("dlopen_ns_by_ini_no_inherit handle %s should not open successfully \n", dllName);
186 dlclose(handle1);
187 }
188
189 // inherit_A can load the so by inherit_B.
190 dlns_inherit(&inherit_A, &inherit_B, dllName);
191 void* handle2 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY);
192 if(!handle2)
193 t_error("dlopen_ns_by_dlns_inherir handle get error %s open failed : %s \n", dllName, dlerror());
194
195 if(dlclose(handle2))
196 t_error("dlclose_by_dlns_inherir handle %s close failed : %s\n", dllName, dlerror());
197
198 // inherit_A can't load the so by inherit ns if the so isn't in shared libs.
199 dlns_inherit(&inherit_A, &inherit_B, dllName2);
200 void* handle3 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY);
201 if(handle3){
202 t_error("dlopen_ns_by_ini_no_inherit handle2 %s should not open successfully \n", dllName);
203 dlclose(handle3);
204 }
205 }
206
dlopen_inherit_check_can_pass(char * dllPath_ns)207 void dlopen_inherit_check_can_pass(char* dllPath_ns)
208 {
209 Dl_namespace transitivity_A, transitivity_B, transitivity_C;
210 dlns_init(&transitivity_A, "transitivity_A");
211 dlns_init(&transitivity_B, "transitivity_B");
212 dlns_init(&transitivity_C, "transitivity_C");
213 dlns_create2(&transitivity_A, NULL, 0);
214 dlns_create2(&transitivity_B, NULL, 0);
215 dlns_create2(&transitivity_C, dllPath_ns, 0);
216 dlns_inherit(&transitivity_A, &transitivity_B, NULL);
217 dlns_inherit(&transitivity_B, &transitivity_C, dllName);
218
219 void* handleB = dlopen_ns(&transitivity_B, dllName, RTLD_LAZY);
220 if(!handleB)
221 t_error("dlopen_ns_by_inherit_transitivity handleB get error %s open failed : %s \n", dllName, dlerror());
222
223 void* handleC = dlopen_ns(&transitivity_C, dllName, RTLD_LAZY);
224 if(!handleC)
225 t_error("dlopen_ns_by_inherit_transitivity handleC get error %s open failed : %s \n", dllName, dlerror());
226
227 if(dlclose(handleC))
228 t_error("dlclose_by_inherit_transitivity handleC %s close failed : %s\n", dllName, dlerror());
229 if(dlclose(handleB))
230 t_error("dlclose_by_inherit_transitivity handleB %s close failed : %s\n", dllName, dlerror());
231
232 // transitivity_A can't load so because inherit can't pass.
233 void* handleA = dlopen_ns(&transitivity_A, dllName, RTLD_LAZY);
234 if(handleA){
235 t_error("dlopen_ns_by_inherit_transitivity handleA %s should not open successfully \n", dllName);
236 dlclose(handleA);
237 }
238 }
239
dlopen_test_dlns_create2()240 void dlopen_test_dlns_create2()
241 {
242 Dl_namespace dlns;
243 dlns_init(&dlns, "ns_for_create2");
244 // ns_for_create2 doesn't exist, it will use default ns to search so.
245 void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY);
246 if(!handle)
247 t_error("dlopen_ns %s use a non-existent ns failed: %s\n", dllName, dlerror());
248
249 if(dlclose(handle))
250 t_error("dlclose %s failed : %s \n", dllName, dlerror());
251
252 // 0: ns_for_create2 doesn't inherit default ns.
253 dlns_create2(&dlns, errPath_ns, 0);
254 void* handle2 = dlopen_ns(&dlns, dllName, RTLD_LAZY);
255 if(handle2)
256 t_error("%s namespace can't see %s but dlopen succee.\n", "ns_for_create2", dllName);
257 }
258
259
main(int argc,char * argv[])260 int main(int argc, char *argv[])
261 {
262 char buf[512],path[512];
263 char* i;
264 //带so的路径
265 if (!t_pathrel(buf, sizeof buf, argv[0], "libdlopen_ns_dso.so")) {
266 t_error("failed to obtain relative path to libdlopen_ns_dso.so\n");
267 return 1;
268 }
269 //包含so的路径
270 if (!t_pathrel(path, sizeof path, argv[0], "")) {
271 t_error("failed to obtain relative path to path\n");
272 return 1;
273 }
274 path[strlen (path) -1 ] ='\0';
275 main_dlopen_ndk_so();
276 system_so_dlopen_ndk_so();
277 ndk_so_dlopen_default_ns_so();
278 dlopen_same_so_twice_by_same_ns(path);
279 dlopen_same_so_by_different_ns(path);
280 dlopen_same_so_by_different_inherit_ns(path);
281 dlopen_seperated(path);
282 dlopen_test_dlns_create2();
283 dlopen_inherit(path);
284 dlopen_inherit_check_can_pass(path);
285
286
287 return t_status;
288 }