1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include <dlfcn.h> 20 #include <libgen.h> 21 #include <limits.h> 22 #include <stdio.h> 23 #include <stdint.h> 24 25 #include <string> 26 27 TEST(atexit, dlclose) { 28 std::string atexit_call_sequence; 29 bool valid_this_in_static_dtor = false; 30 void* handle = dlopen("libtest_atexit.so", RTLD_NOW); 31 ASSERT_TRUE(handle != NULL); 32 33 void* sym = dlsym(handle, "register_atexit"); 34 ASSERT_TRUE(sym != NULL); 35 reinterpret_cast<void (*)(std::string*, bool*)>(sym)(&atexit_call_sequence, &valid_this_in_static_dtor); 36 37 ASSERT_EQ(0, dlclose(handle)); 38 // this test verifies atexit call from atexit handler. as well as the order of calls 39 ASSERT_EQ("Humpty Dumpty sat on a wall", atexit_call_sequence); 40 ASSERT_TRUE(valid_this_in_static_dtor); 41 } 42 43 class TestMainStaticDtorClass { 44 public: 45 TestMainStaticDtorClass() { 46 expected_this = this; 47 } 48 49 ~TestMainStaticDtorClass() { 50 if (this != expected_this) { 51 fprintf(stderr, "\nerror: static d-tor called with incorrect this pointer: %p, expected: %p\n", this, expected_this); 52 } else { 53 fprintf(stderr, "6"); 54 } 55 } 56 private: 57 static const TestMainStaticDtorClass* expected_this; 58 }; 59 60 const TestMainStaticDtorClass* TestMainStaticDtorClass::expected_this = NULL; 61 62 static void atexit_func5() { 63 fprintf(stderr, "5"); 64 } 65 66 static void atexit_func4() { 67 fprintf(stderr, "4"); 68 } 69 70 static void atexit_func3() { 71 fprintf(stderr, "3"); 72 atexit(atexit_func4); 73 } 74 75 static void atexit_func2() { 76 fprintf(stderr, "2"); 77 } 78 79 static void atexit_func1() { 80 fprintf(stderr, "1"); 81 } 82 83 static void atexit_main() { 84 // This should result in "123456" output to stderr 85 static TestMainStaticDtorClass static_obj; 86 atexit(atexit_func5); 87 atexit(atexit_func3); 88 atexit(atexit_func2); 89 atexit(atexit_func1); 90 exit(0); 91 } 92 93 TEST(atexit, exit) { 94 ASSERT_EXIT(atexit_main(), testing::ExitedWithCode(0), "123456"); 95 } 96 97