183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner/* 283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * Copyright (C) 2008 The Android Open Source Project 383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * All rights reserved. 483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * 583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * Redistribution and use in source and binary forms, with or without 683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * modification, are permitted provided that the following conditions 783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * are met: 883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * * Redistributions of source code must retain the above copyright 983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * notice, this list of conditions and the following disclaimer. 1083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * * Redistributions in binary form must reproduce the above copyright 1183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * notice, this list of conditions and the following disclaimer in 1283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * the documentation and/or other materials provided with the 1383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * distribution. 1483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * 1583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * SUCH DAMAGE. 2783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner */ 2883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 2983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner/* this program is used to check that static C++ destructors are 3083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * properly called when dlclose() is called. We do this by using 3183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * a helper C++ shared library. 3283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * 3383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner * See libdlclosetest1.cpp for details. 3483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner */ 3583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <dlfcn.h> 3683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner#include <stdio.h> 3783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 38133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerstatic int 39133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnercheck_library(const char* libname) 4083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner{ 41133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner void* lib = dlopen(libname, RTLD_NOW); 4283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner int* to_x; 4383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner void (*set_y)(int *); 4483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner int y = 0; 4583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 4683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (lib == NULL) { 47133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not load shared library %s: %s\n", libname, dlerror()); 4883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 1; 4983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 5083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 51133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "%s loaded.\n", libname); 5283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 5383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner to_x = dlsym(lib, "x"); 54133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (to_x == NULL) { 55133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not access global DLL variable (x) in %s: %s\n", libname, dlerror()); 5683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 10; 5783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 5883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 5983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (*to_x != 1) { 60133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Constructor was not run on dlopen(\"%s\") !\n", libname); 6183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 11; 6283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 6383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 6483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner set_y = dlsym(lib, "set_y"); 6583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (set_y == NULL) { 66133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not access global DLL function (set_y) in %s: %s\n", libname, dlerror()); 6783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 12; 6883b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 6983b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 7083b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner y = 0; 7183b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner (*set_y)(&y); 7283b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 7383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner if (dlclose(lib) < 0) { 74133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "Could not unload shared library %s: %s\n", libname, dlerror()); 7583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 2; 7683b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner } 7783b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 78133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner fprintf(stderr, "%s unloaded.\n", libname); 797f101d6dd0e9da88ffed3aef0686758950285b3dDavid 'Digit' Turner if (y != 2) { 807f101d6dd0e9da88ffed3aef0686758950285b3dDavid 'Digit' Turner fprintf(stderr, "Static destructors was not called on dlclose()!\n"); 817f101d6dd0e9da88ffed3aef0686758950285b3dDavid 'Digit' Turner return 2; 827f101d6dd0e9da88ffed3aef0686758950285b3dDavid 'Digit' Turner } 83133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 0; 84133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner} 8583b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner 86133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turnerint main(void) 87133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner{ 88133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner /* Testing static C++ construction/destruction */ 89133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (check_library("libdlclosetest1.so")) 90133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 1; 91133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner if (check_library("libdlclosetest2.so")) 92133a37ede3e955093c6004d94496e2cdc2cc1264David 'Digit' Turner return 2; 9383b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner return 0; 9483b47ccbc4066ef19f5d95261d8a892567a7f0a7David 'Digit' Turner} 95