aboutsummaryrefslogtreecommitdiff
path: root/tests/dlfcn_test.cpp
diff options
context:
space:
mode:
authorDimitry Ivanov <dimitry@google.com>2016-11-17 12:38:09 -0800
committerDimitry Ivanov <dimitry@google.com>2016-11-17 14:23:24 -0800
commitc7365eb2fa996e72c5ea7f4e20222d6b48b9c6e0 (patch)
tree96bf78a1a50323dde10b2329b88ffa88f15029ab /tests/dlfcn_test.cpp
parent3613c20c59f931caa7d5411e4350306a4d6ad1e0 (diff)
downloadbionic-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.cpp46
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);
}