1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* this program is used to check that static C++ destructors are 30 * properly called when dlclose() is called. We do this by using 31 * a helper C++ shared library. 32 * 33 * See libdlclosetest1.cpp for details. 34 */ 35 #include <dlfcn.h> 36 #include <stdio.h> 37 38 static int 39 check_library(const char* libname) 40 { 41 void* lib = dlopen(libname, RTLD_NOW); 42 int* to_x; 43 void (*set_y)(int *); 44 int y = 0; 45 46 if (lib == NULL) { 47 fprintf(stderr, "Could not load shared library %s: %s\n", libname, dlerror()); 48 return 1; 49 } 50 51 fprintf(stderr, "%s loaded.\n", libname); 52 53 to_x = dlsym(lib, "x"); 54 if (to_x == NULL) { 55 fprintf(stderr, "Could not access global DLL variable (x) in %s: %s\n", libname, dlerror()); 56 return 10; 57 } 58 59 if (*to_x != 1) { 60 fprintf(stderr, "Constructor was not run on dlopen(\"%s\") !\n", libname); 61 return 11; 62 } 63 64 set_y = dlsym(lib, "set_y"); 65 if (set_y == NULL) { 66 fprintf(stderr, "Could not access global DLL function (set_y) in %s: %s\n", libname, dlerror()); 67 return 12; 68 } 69 70 y = 0; 71 (*set_y)(&y); 72 73 if (dlclose(lib) < 0) { 74 fprintf(stderr, "Could not unload shared library %s: %s\n", libname, dlerror()); 75 return 2; 76 } 77 78 fprintf(stderr, "%s unloaded.\n", libname); 79 if (y != 2) { 80 fprintf(stderr, "Static destructors was not called on dlclose()!\n"); 81 return 2; 82 } 83 return 0; 84 } 85 86 int main(void) 87 { 88 /* Testing static C++ construction/destruction */ 89 if (check_library("libdlclosetest1.so")) 90 return 1; 91 if (check_library("libdlclosetest2.so")) 92 return 2; 93 return 0; 94 } 95