@@ -587,25 +587,32 @@ class ThreadLocalRegistryImpl {
587587 // thread's ID.
588588 typedef std::map<DWORD, ThreadLocalValues> ThreadIdToThreadLocals;
589589
590- // Holds the thread id and thread handle that we pass from
591- // StartWatcherThreadFor to WatcherThreadFunc.
592- typedef std::pair<DWORD, HANDLE> ThreadIdAndHandle;
590+ struct WatcherThreadParams {
591+ DWORD thread_id;
592+ HANDLE handle;
593+ Notification has_initialized;
594+ };
593595
594596 static void StartWatcherThreadFor (DWORD thread_id) {
595597 // The returned handle will be kept in thread_map and closed by
596598 // watcher_thread in WatcherThreadFunc.
597599 HANDLE thread =
598600 ::OpenThread (SYNCHRONIZE | THREAD_QUERY_INFORMATION, FALSE , thread_id);
599601 GTEST_CHECK_ (thread != nullptr );
602+
603+ WatcherThreadParams* watcher_thread_params = new WatcherThreadParams;
604+ watcher_thread_params->thread_id = thread_id;
605+ watcher_thread_params->handle = thread;
606+
600607 // We need to pass a valid thread ID pointer into CreateThread for it
601608 // to work correctly under Win98.
602609 DWORD watcher_thread_id;
603- HANDLE watcher_thread = :: CreateThread (
604- nullptr , // Default security.
605- 0 , // Default stack size
606- &ThreadLocalRegistryImpl::WatcherThreadFunc,
607- reinterpret_cast <LPVOID>(new ThreadIdAndHandle (thread_id, thread) ),
608- CREATE_SUSPENDED, &watcher_thread_id);
610+ HANDLE watcher_thread =
611+ ::CreateThread ( nullptr , // Default security.
612+ 0 , // Default stack size
613+ &ThreadLocalRegistryImpl::WatcherThreadFunc,
614+ reinterpret_cast <LPVOID>(watcher_thread_params ),
615+ CREATE_SUSPENDED, &watcher_thread_id);
609616 GTEST_CHECK_ (watcher_thread != nullptr )
610617 << " CreateThread failed with error " << ::GetLastError () << " ." ;
611618 // Give the watcher thread the same priority as ours to avoid being
@@ -614,17 +621,25 @@ class ThreadLocalRegistryImpl {
614621 ::GetThreadPriority (::GetCurrentThread()));
615622 ::ResumeThread (watcher_thread);
616623 ::CloseHandle (watcher_thread);
624+
625+ // Wait for the watcher thread to start to avoid race conditions.
626+ // One specific race condition that can happen is that we have returned
627+ // from main and have started to tear down, the newly spawned watcher
628+ // thread may access already-freed variables, like global shared_ptrs.
629+ watcher_thread_params->has_initialized.WaitForNotification();
617630 }
618631
619632 // Monitors exit from a given thread and notifies those
620633 // ThreadIdToThreadLocals about thread termination.
621634 static DWORD WINAPI WatcherThreadFunc (LPVOID param) {
622- const ThreadIdAndHandle* tah =
623- reinterpret_cast <const ThreadIdAndHandle*>(param);
624- GTEST_CHECK_ (::WaitForSingleObject (tah->second , INFINITE) == WAIT_OBJECT_0);
625- OnThreadExit (tah->first );
626- ::CloseHandle (tah->second);
627- delete tah;
635+ WatcherThreadParams* watcher_thread_params =
636+ reinterpret_cast <WatcherThreadParams*>(param);
637+ watcher_thread_params->has_initialized .Notify ();
638+ GTEST_CHECK_ (::WaitForSingleObject (watcher_thread_params->handle ,
639+ INFINITE) == WAIT_OBJECT_0);
640+ OnThreadExit (watcher_thread_params->thread_id );
641+ ::CloseHandle (watcher_thread_params->handle);
642+ delete watcher_thread_params;
628643 return 0 ;
629644 }
630645
@@ -1033,12 +1048,12 @@ GTestLog::~GTestLog() {
10331048 }
10341049}
10351050
1051+ #if GTEST_HAS_STREAM_REDIRECTION
1052+
10361053// Disable Microsoft deprecation warnings for POSIX functions called from
10371054// this class (creat, dup, dup2, and close)
10381055GTEST_DISABLE_MSC_DEPRECATED_PUSH_ ()
10391056
1040- #if GTEST_HAS_STREAM_REDIRECTION
1041-
10421057namespace {
10431058
10441059#if defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_IOS)
@@ -1333,8 +1348,8 @@ bool ParseInt32(const Message& src_text, const char* str, int32_t* value) {
13331348 ) {
13341349 Message msg;
13351350 msg << " WARNING: " << src_text
1336- << " is expected to be a 32-bit integer, but actually"
1337- << " has value " << str << " , which overflows.\n " ;
1351+ << " is expected to be a 32-bit integer, but actually" << " has value "
1352+ << str << " , which overflows.\n " ;
13381353 printf (" %s" , msg.GetString ().c_str ());
13391354 fflush (stdout);
13401355 return false ;
0 commit comments