summaryrefslogtreecommitdiff
path: root/libunwindstack/tests/MapInfoTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libunwindstack/tests/MapInfoTest.cpp')
-rw-r--r--libunwindstack/tests/MapInfoTest.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/libunwindstack/tests/MapInfoTest.cpp b/libunwindstack/tests/MapInfoTest.cpp
index 59aa79e..055e965 100644
--- a/libunwindstack/tests/MapInfoTest.cpp
+++ b/libunwindstack/tests/MapInfoTest.cpp
@@ -16,6 +16,8 @@
#include <stdint.h>
+#include <thread>
+
#include <gtest/gtest.h>
#include <unwindstack/MapInfo.h>
@@ -72,4 +74,45 @@ TEST(MapInfoTest, get_function_name) {
EXPECT_EQ(1000UL, offset);
}
+TEST(MapInfoTest, multiple_thread_get_elf_fields) {
+ MapInfo map_info(nullptr, nullptr, 0, 0, 0, 0, "");
+
+ static constexpr size_t kNumConcurrentThreads = 100;
+ MapInfo::ElfFields* fields[kNumConcurrentThreads];
+ Elf* elfs[kNumConcurrentThreads];
+ uint64_t offsets[kNumConcurrentThreads];
+
+ std::atomic_bool wait;
+ wait = true;
+ // Create all of the threads and have them do the call at the same time
+ // to make it likely that a race will occur.
+ std::vector<std::thread*> threads;
+ for (size_t i = 0; i < kNumConcurrentThreads; i++) {
+ std::thread* thread = new std::thread([&]() {
+ while (wait)
+ ;
+ fields[i] = &map_info.GetElfFields();
+ elfs[i] = fields[i]->elf_.get();
+ offsets[i] = fields[i]->elf_offset_;
+ });
+ threads.push_back(thread);
+ }
+
+ // Set them all going and wait for the threads to finish.
+ wait = false;
+ for (auto thread : threads) {
+ thread->join();
+ delete thread;
+ }
+
+ // Now verify that all of them are exactly the same and valid.
+ for (size_t i = 0; i < kNumConcurrentThreads; i++) {
+ EXPECT_EQ(fields[0], fields[i]) << "Thread " << i << " mismatched.";
+ EXPECT_EQ(elfs[0], elfs[i]) << "Thread " << i << " mismatched.";
+ EXPECT_EQ(offsets[0], offsets[i]) << "Thread " << i << " mismatched.";
+ EXPECT_EQ(nullptr, elfs[i]);
+ EXPECT_EQ(0u, offsets[i]);
+ }
+}
+
} // namespace unwindstack