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" 7const char* dllName = "libdlopen_ns_dso.so"; 8const char* dllName2 = "libdlopen_dso.so"; 9const char* errPath_ns = "/src/common"; 10const char* ndk_so = "libdlopen_ns_dso_ndk.so"; 11const char* system_so = "libdlopen_ns_dso_sys.so"; 12typedef void*(*CALL_DLOPEN_PTR)(const char *); 13 14// Test whether it is ok for main to dlopen ndk so. 15void 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. 25void 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. 42void 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. 61void 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. 86void 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. 115void 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 144void dlopen_seperated(char * dllPath_ns) 145{ 146 Dl_namespace dlns_default; 147 dlns_get(NULL, &dlns_default); 148 Dl_namespace dlns1; 149 dlns_init(&dlns1, "ns_for_no_seperated"); 150 dlns_create2(&dlns1, errPath_ns, 0); 151 dlns_inherit(&dlns1, &dlns_default, "libc++.so"); 152 void* handle = NULL; 153 // current ns can't load this so. 154 handle = dlopen_ns(&dlns1, dllName, RTLD_NOW); 155 if(handle) 156 t_error("dlopen_ns(ns=%s, name=%s) failed : %s \n", dlns1.name, dllName, dlerror()); 157 158 // current ns can load the so by absolute path. 159 char absolute_path_1[512]; 160 snprintf(absolute_path_1, sizeof(absolute_path_1), "%s/%s", dllPath_ns, dllName); 161 handle = dlopen_ns(&dlns1, absolute_path_1, RTLD_NOW); 162 if (!handle) 163 t_error("%s can load %s by absolute path but failed : %s \n", dlns1.name, absolute_path_1, dlerror()); 164 165 if(dlclose(handle)) 166 t_error("dlclose %s failed : %s \n", absolute_path_1, dlerror()); 167 168 // current ns can't load the so by absolute path if it has inaccessible dependent so. 169 char absolute_path_2[512]; 170 snprintf(absolute_path_2, sizeof(absolute_path_2), "%s/%s", dllPath_ns, SO_HAS_DEPENDENCES); 171 handle = dlopen_ns(&dlns1, absolute_path_2, RTLD_NOW); 172 if (handle) 173 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()); 174} 175 176void dlopen_inherit(char* dllPath_ns) 177{ 178 Dl_namespace dlns_default; 179 dlns_get(NULL, &dlns_default); 180 Dl_namespace inherit_A, inherit_B; 181 dlns_init(&inherit_A, "inherir_error_lib_A"); 182 dlns_init(&inherit_B, "inherir_error_lib_B"); 183 dlns_create2(&inherit_A, NULL, 0); 184 dlns_create2(&inherit_B, dllPath_ns, 0); 185 dlns_inherit(&inherit_B, &dlns_default, "libc++.so"); 186 187 // inherit_A can't load the so because search path is NULL. 188 void* handle1 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 189 if(handle1){ 190 t_error("dlopen_ns_by_ini_no_inherit handle %s should not open successfully \n", dllName); 191 dlclose(handle1); 192 } 193 194 // inherit_A can load the so by inherit_B. 195 dlns_inherit(&inherit_A, &inherit_B, dllName); 196 void* handle2 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 197 if(!handle2) 198 t_error("dlopen_ns_by_dlns_inherir handle get error %s open failed : %s \n", dllName, dlerror()); 199 200 if(dlclose(handle2)) 201 t_error("dlclose_by_dlns_inherir handle %s close failed : %s\n", dllName, dlerror()); 202 203 // inherit_A can't load the so by inherit ns if the so isn't in shared libs. 204 dlns_inherit(&inherit_A, &inherit_B, dllName2); 205 void* handle3 = dlopen_ns(&inherit_A, dllName, RTLD_LAZY); 206 if(handle3){ 207 t_error("dlopen_ns_by_ini_no_inherit handle2 %s should not open successfully \n", dllName); 208 dlclose(handle3); 209 } 210} 211 212void dlopen_inherit_check_can_pass(char* dllPath_ns) 213{ 214 Dl_namespace dlns_default; 215 dlns_get(NULL, &dlns_default); 216 Dl_namespace transitivity_A, transitivity_B, transitivity_C; 217 dlns_init(&transitivity_A, "transitivity_A"); 218 dlns_init(&transitivity_B, "transitivity_B"); 219 dlns_init(&transitivity_C, "transitivity_C"); 220 dlns_create2(&transitivity_A, NULL, 0); 221 dlns_create2(&transitivity_B, NULL, 0); 222 dlns_create2(&transitivity_C, dllPath_ns, 0); 223 dlns_inherit(&transitivity_A, &transitivity_B, NULL); 224 dlns_inherit(&transitivity_B, &transitivity_C, dllName); 225 dlns_inherit(&transitivity_C, &dlns_default, "libc++.so"); 226 227 void* handleB = dlopen_ns(&transitivity_B, dllName, RTLD_LAZY); 228 if(!handleB) 229 t_error("dlopen_ns_by_inherit_transitivity handleB get error %s open failed : %s \n", dllName, dlerror()); 230 231 void* handleC = dlopen_ns(&transitivity_C, dllName, RTLD_LAZY); 232 if(!handleC) 233 t_error("dlopen_ns_by_inherit_transitivity handleC get error %s open failed : %s \n", dllName, dlerror()); 234 235 if(dlclose(handleC)) 236 t_error("dlclose_by_inherit_transitivity handleC %s close failed : %s\n", dllName, dlerror()); 237 if(dlclose(handleB)) 238 t_error("dlclose_by_inherit_transitivity handleB %s close failed : %s\n", dllName, dlerror()); 239 240 // transitivity_A can't load so because inherit can't pass. 241 void* handleA = dlopen_ns(&transitivity_A, dllName, RTLD_LAZY); 242 if(handleA){ 243 t_error("dlopen_ns_by_inherit_transitivity handleA %s should not open successfully \n", dllName); 244 dlclose(handleA); 245 } 246} 247 248void dlopen_test_dlns_create2() 249{ 250 Dl_namespace dlns; 251 dlns_init(&dlns, "ns_for_create2"); 252 // ns_for_create2 doesn't exist, it will use default ns to search so. 253 void* handle = dlopen_ns(&dlns, dllName, RTLD_LAZY); 254 if(!handle) 255 t_error("dlopen_ns %s use a non-existent ns failed: %s\n", dllName, dlerror()); 256 257 if(dlclose(handle)) 258 t_error("dlclose %s failed : %s \n", dllName, dlerror()); 259 260 // 0: ns_for_create2 doesn't inherit default ns. 261 dlns_create2(&dlns, errPath_ns, 0); 262 void* handle2 = dlopen_ns(&dlns, dllName, RTLD_LAZY); 263 if(handle2) 264 t_error("%s namespace can't see %s but dlopen succee.\n", "ns_for_create2", dllName); 265} 266 267int main(int argc, char *argv[]) 268{ 269 char buf[512],path[512]; 270 char* i; 271 //带so的路径 272 if (!t_pathrel(buf, sizeof buf, argv[0], "libdlopen_ns_dso.so")) { 273 t_error("failed to obtain relative path to libdlopen_ns_dso.so\n"); 274 return 1; 275 } 276 //包含so的路径 277 if (!t_pathrel(path, sizeof path, argv[0], "")) { 278 t_error("failed to obtain relative path to path\n"); 279 return 1; 280 } 281 path[strlen (path) -1 ] ='\0'; 282 main_dlopen_ndk_so(); 283 system_so_dlopen_ndk_so(); 284 ndk_so_dlopen_default_ns_so(); 285 dlopen_same_so_twice_by_same_ns(path); 286 dlopen_same_so_by_different_ns(path); 287 dlopen_same_so_by_different_inherit_ns(path); 288 dlopen_seperated(path); 289 dlopen_test_dlns_create2(); 290 dlopen_inherit(path); 291 dlopen_inherit_check_can_pass(path); 292 293 return t_status; 294}