From 4571f31bd49e4951c9f1e0ff642c74fd79fe740a Mon Sep 17 00:00:00 2001 From: Dmitriy Ivanov Date: Fri, 15 Aug 2014 14:22:07 -0700 Subject: [PATCH] Add atexit test for attributed c-tor/d-tor 1. Add test for __attribute__((constructor/destructor)) and static constructor 2. Compile C++ testlibs with -std=gnu++11 Change-Id: I67f9308144a0c638a51f111fcba8e1933fe0ba41 --- tests/atexit_test.cpp | 23 +++++++++++++++++----- tests/libs/Android.mk | 1 + tests/libs/atexit_testlib.cpp | 37 ++++++++++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/tests/atexit_test.cpp b/tests/atexit_test.cpp index e01220e1b..e92889d1c 100644 --- a/tests/atexit_test.cpp +++ b/tests/atexit_test.cpp @@ -24,20 +24,33 @@ #include -TEST(atexit, dlclose) { +TEST(atexit, sofile) { std::string atexit_call_sequence; bool valid_this_in_static_dtor = false; + bool attr_dtor_called = false; + void* handle = dlopen("libtest_atexit.so", RTLD_NOW); - ASSERT_TRUE(handle != NULL); + ASSERT_TRUE(handle != nullptr); + + typedef int (*int_fn)(void); + int_fn get_cxx_ctor_called, get_attr_ctor_called; + get_cxx_ctor_called = reinterpret_cast(dlsym(handle, "get_cxx_ctor_called")); + get_attr_ctor_called = reinterpret_cast(dlsym(handle, "get_attr_ctor_called")); + ASSERT_TRUE(get_cxx_ctor_called != nullptr); + ASSERT_TRUE(get_attr_ctor_called != nullptr); + + ASSERT_EQ(1, get_cxx_ctor_called()); + ASSERT_EQ(1, get_attr_ctor_called()); void* sym = dlsym(handle, "register_atexit"); - ASSERT_TRUE(sym != NULL); - reinterpret_cast(sym)(&atexit_call_sequence, &valid_this_in_static_dtor); + ASSERT_TRUE(sym != nullptr); + reinterpret_cast(sym)(&atexit_call_sequence, &valid_this_in_static_dtor, &attr_dtor_called); ASSERT_EQ(0, dlclose(handle)); // this test verifies atexit call from atexit handler. as well as the order of calls ASSERT_EQ("Humpty Dumpty sat on a wall", atexit_call_sequence); ASSERT_TRUE(valid_this_in_static_dtor); + ASSERT_TRUE(attr_dtor_called); } class TestMainStaticDtorClass { @@ -57,7 +70,7 @@ class TestMainStaticDtorClass { static const TestMainStaticDtorClass* expected_this; }; -const TestMainStaticDtorClass* TestMainStaticDtorClass::expected_this = NULL; +const TestMainStaticDtorClass* TestMainStaticDtorClass::expected_this = nullptr; static void atexit_func5() { fprintf(stderr, "5"); diff --git a/tests/libs/Android.mk b/tests/libs/Android.mk index bca2047e2..65c341de8 100644 --- a/tests/libs/Android.mk +++ b/tests/libs/Android.mk @@ -17,6 +17,7 @@ LOCAL_PATH := $(call my-dir) TEST_PATH := $(LOCAL_PATH)/.. +common_cppflags += -std=gnu++11 # ----------------------------------------------------------------------------- # Library used by dlfcn tests. # ----------------------------------------------------------------------------- diff --git a/tests/libs/atexit_testlib.cpp b/tests/libs/atexit_testlib.cpp index d35f57b74..314e8de26 100644 --- a/tests/libs/atexit_testlib.cpp +++ b/tests/libs/atexit_testlib.cpp @@ -19,12 +19,19 @@ #include // use external control number from main test -static std::string* atexit_sequence = NULL; -static bool* atexit_valid_this_in_static_dtor = NULL; +static std::string* atexit_sequence = nullptr; +static bool* atexit_valid_this_in_static_dtor = nullptr; +static bool* atexit_attr_dtor_called = nullptr; + +static int cxx_ctor_called = 0; +static int attr_ctor_called = 0; static class AtExitStaticClass { public: - AtExitStaticClass() { expected_this = this; } + AtExitStaticClass() { + expected_this = this; + cxx_ctor_called = 1; + } ~AtExitStaticClass() { if (atexit_valid_this_in_static_dtor) { *atexit_valid_this_in_static_dtor = (expected_this == this); @@ -35,7 +42,7 @@ static class AtExitStaticClass { } static_obj; -const AtExitStaticClass* AtExitStaticClass::expected_this = NULL; +const AtExitStaticClass* AtExitStaticClass::expected_this = nullptr; // 4 static void atexit_handler_from_atexit_from_atexit2() { @@ -66,10 +73,30 @@ static void atexit_handler_regular() { *atexit_sequence += " a wall"; } -extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor) { +// attribute c-tor and d-tor +static void __attribute__((constructor)) atexit_attr_ctor() { + attr_ctor_called = 1; +} + +static void __attribute__((destructor)) atexit_attr_dtor() { + if (atexit_attr_dtor_called) { + *atexit_attr_dtor_called = true; + } +} + +extern "C" void register_atexit(std::string* sequence, bool* valid_this_in_static_dtor, bool* attr_dtor_called) { atexit_sequence = sequence; atexit_valid_this_in_static_dtor = valid_this_in_static_dtor; + atexit_attr_dtor_called = attr_dtor_called; atexit(atexit_handler_regular); atexit(atexit_handler_with_atexit); } +extern "C" int get_cxx_ctor_called() { + return cxx_ctor_called; +} + +extern "C" int get_attr_ctor_called() { + return attr_ctor_called; +} +