sanitizer_linux_test.cc revision 6fb47af2d2d305adbfc3d41bea589d1527a364a9
1//===-- sanitizer_linux_test.cc -------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Tests for sanitizer_linux.h 11// 12//===----------------------------------------------------------------------===// 13 14#ifdef __linux__ 15 16#include "sanitizer_common/sanitizer_linux.h" 17#include "gtest/gtest.h" 18 19#include "sanitizer_common/sanitizer_common.h" 20 21#include <pthread.h> 22#include <sched.h> 23 24#include <set> 25 26namespace __sanitizer { 27// In a single-threaded process, ThreadLister should produce the TID (which 28// coincides with the PID) of the current task. 29TEST(SanitizerLinux, ThreadListerSingleThread) { 30 pid_t pid = getpid(); 31 ThreadLister thread_lister(pid); 32 EXPECT_FALSE(thread_lister.error()); 33 EXPECT_EQ(thread_lister.GetNextTID(), pid); 34 EXPECT_FALSE(thread_lister.error()); 35 EXPECT_LT(thread_lister.GetNextTID(), 0); 36 EXPECT_FALSE(thread_lister.error()); 37} 38 39static pthread_cond_t thread_exit_cond = PTHREAD_COND_INITIALIZER; 40static pthread_mutex_t thread_exit_mutex = PTHREAD_MUTEX_INITIALIZER; 41static pthread_cond_t tid_reported_cond = PTHREAD_COND_INITIALIZER; 42static pthread_mutex_t tid_reported_mutex = PTHREAD_MUTEX_INITIALIZER; 43static bool thread_exit; 44 45void *TIDReporterThread(void *tid_storage) { 46 pthread_mutex_lock(&tid_reported_mutex); 47 *(pid_t *)tid_storage = GetTid(); 48 pthread_cond_broadcast(&tid_reported_cond); 49 pthread_mutex_unlock(&tid_reported_mutex); 50 51 pthread_mutex_lock(&thread_exit_mutex); 52 while (!thread_exit) 53 pthread_cond_wait(&thread_exit_cond, &thread_exit_mutex); 54 pthread_mutex_unlock(&thread_exit_mutex); 55 return NULL; 56} 57 58// In a process with multiple threads, ThreadLister should produce their TIDs 59// in some order. 60// Calling ThreadLister::Reset() should not change this. 61TEST(SanitizerLinux, ThreadListerMultiThreaded) { 62 const uptr kThreadCount = 20; // does not include the main thread 63 pthread_t thread_ids[kThreadCount]; 64 pid_t thread_tids[kThreadCount]; 65 pid_t pid = getpid(); 66 pid_t self_tid = GetTid(); 67 thread_exit = false; 68 pthread_mutex_lock(&tid_reported_mutex); 69 for (uptr i = 0; i < kThreadCount; i++) { 70 int pthread_create_result; 71 thread_tids[i] = -1; 72 pthread_create_result = pthread_create(&thread_ids[i], NULL, 73 TIDReporterThread, 74 &thread_tids[i]); 75 ASSERT_EQ(pthread_create_result, 0); 76 while (thread_tids[i] == -1) 77 pthread_cond_wait(&tid_reported_cond, &tid_reported_mutex); 78 } 79 pthread_mutex_unlock(&tid_reported_mutex); 80 std::set<pid_t> reported_tids(thread_tids, thread_tids + kThreadCount); 81 reported_tids.insert(self_tid); 82 83 ThreadLister thread_lister(pid); 84 // There's a Reset() call between the first and second iteration. 85 for (uptr i = 0; i < 2; i++) { 86 std::set<pid_t> listed_tids; 87 88 EXPECT_FALSE(thread_lister.error()); 89 for (uptr i = 0; i < kThreadCount + 1; i++) { 90 pid_t tid = thread_lister.GetNextTID(); 91 EXPECT_GE(tid, 0); 92 EXPECT_FALSE(thread_lister.error()); 93 listed_tids.insert(tid); 94 } 95 pid_t tid = thread_lister.GetNextTID(); 96 EXPECT_LT(tid, 0); 97 EXPECT_FALSE(thread_lister.error()); 98 99 EXPECT_EQ(listed_tids, reported_tids); 100 thread_lister.Reset(); 101 } 102 pthread_mutex_lock(&thread_exit_mutex); 103 thread_exit = true; 104 pthread_cond_broadcast(&thread_exit_cond); 105 pthread_mutex_unlock(&thread_exit_mutex); 106} 107} // namespace __sanitizer 108 109#endif // __linux__ 110