From c7365eb2fa996e72c5ea7f4e20222d6b48b9c6e0 Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Thu, 17 Nov 2016 12:38:09 -0800 Subject: Improve dlerror_concurrent test Add a test to check if result is thread-local, not only buffer. Test: run bionic-unit-tests Change-Id: Ia95f88c0d76aa86f7f439836393abd67a57dd396 --- tests/dlfcn_test.cpp | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'tests/dlfcn_test.cpp') diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp index 5908fc3ab..4d8e69794 100644 --- a/tests/dlfcn_test.cpp +++ b/tests/dlfcn_test.cpp @@ -25,6 +25,7 @@ #include "private/ScopeGuard.h" #include +#include #include "gtest_globals.h" #include "dlfcn_symlink_support.h" @@ -754,24 +755,45 @@ TEST(dlfcn, dlopen_failure) { #endif } -static void* ConcurrentDlErrorFn(void*) { - dlopen("/child/thread", RTLD_NOW); - return reinterpret_cast(strdup(dlerror())); +static void ConcurrentDlErrorFn(std::string& error) { + ASSERT_TRUE(dlerror() == nullptr); + + void* handle = dlopen("/child/thread", RTLD_NOW); + ASSERT_TRUE(handle == nullptr); + + const char* err = dlerror(); + ASSERT_TRUE(err != nullptr); + + error = err; } -TEST(dlfcn, dlerror_concurrent) { - dlopen("/main/thread", RTLD_NOW); +TEST(dlfcn, dlerror_concurrent_buffer) { + void* handle = dlopen("/main/thread", RTLD_NOW); + ASSERT_TRUE(handle == nullptr); const char* main_thread_error = dlerror(); + ASSERT_TRUE(main_thread_error != nullptr); ASSERT_SUBSTR("/main/thread", main_thread_error); - pthread_t t; - ASSERT_EQ(0, pthread_create(&t, nullptr, ConcurrentDlErrorFn, nullptr)); - void* result; - ASSERT_EQ(0, pthread_join(t, &result)); - char* child_thread_error = static_cast(result); - ASSERT_SUBSTR("/child/thread", child_thread_error); - free(child_thread_error); + std::string child_thread_error; + std::thread t(ConcurrentDlErrorFn, std::ref(child_thread_error)); + t.join(); + ASSERT_SUBSTR("/child/thread", child_thread_error.c_str()); + // Check that main thread local buffer was not modified. + ASSERT_SUBSTR("/main/thread", main_thread_error); +} + +TEST(dlfcn, dlerror_concurrent) { + void* handle = dlopen("/main/thread", RTLD_NOW); + ASSERT_TRUE(handle == nullptr); + + std::string child_thread_error; + std::thread t(ConcurrentDlErrorFn, std::ref(child_thread_error)); + t.join(); + ASSERT_SUBSTR("/child/thread", child_thread_error.c_str()); + + const char* main_thread_error = dlerror(); + ASSERT_TRUE(main_thread_error != nullptr); ASSERT_SUBSTR("/main/thread", main_thread_error); } -- cgit v1.2.3