diff options
author | Dimitry Ivanov <dimitry@google.com> | 2016-11-17 12:38:09 -0800 |
---|---|---|
committer | Dimitry Ivanov <dimitry@google.com> | 2016-11-17 14:23:24 -0800 |
commit | c7365eb2fa996e72c5ea7f4e20222d6b48b9c6e0 (patch) | |
tree | 96bf78a1a50323dde10b2329b88ffa88f15029ab /tests/dlfcn_test.cpp | |
parent | 3613c20c59f931caa7d5411e4350306a4d6ad1e0 (diff) | |
download | bionic-c7365eb2fa996e72c5ea7f4e20222d6b48b9c6e0.tar.gz |
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
Diffstat (limited to 'tests/dlfcn_test.cpp')
-rw-r--r-- | tests/dlfcn_test.cpp | 46 |
1 files changed, 34 insertions, 12 deletions
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 <string> +#include <thread> #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<void*>(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<char*>(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); } |