Author: mamai
Date: Tue Apr 19 08:21:46 2016
New Revision: 266733

URL: http://llvm.org/viewvc/llvm-project?rev=266733&view=rev
Log:
LLDB: Fixed two race conditions when stopping private state thread

When stopping the private state thread, there was a race condition between the 
time the thread exits (resetting the HostThread object) and the time a Join was 
attempted, especially in the case of a timeout.

The previous workaround of copying the HostThread object is not enough, since 
on a Reset the internal thread stuff gets nulled out regardless of which 
HostThread object actually has Reset called on it, resulting in an attempt to 
dereference a null pointer on the subsequent call to Join from the copy as well.

Additionally, there was a race between the detach (called when stopping the 
process) and the stop itself, causing the stop to time out because it was 
waiting for the private state thread to see the stop state, but it had exited 
immediately after entering the detached state.

Patch by cameron314

Differential Revision: http://reviews.llvm.org/D19122

Modified:
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/source/Target/Process.cpp

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=266733&r1=266732&r2=266733&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Tue Apr 19 08:21:46 2016
@@ -3310,7 +3310,10 @@ protected:
     bool
     PrivateStateThreadIsValid () const
     {
-        return m_private_state_thread.IsJoinable();
+        lldb::StateType state = m_private_state.GetValue();
+        return state != lldb::eStateDetached &&
+               state != lldb::eStateExited &&
+               m_private_state_thread.IsJoinable();
     }
     
     void

Modified: lldb/trunk/source/Target/Process.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=266733&r1=266732&r2=266733&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Tue Apr 19 08:21:46 2016
@@ -4112,11 +4112,8 @@ Process::ControlPrivateStateThread (uint
     if (log)
         log->Printf ("Process::%s (signal = %d)", __FUNCTION__, signal);
 
-    // Signal the private state thread. First we should copy this is case the
-    // thread starts exiting since the private state thread will NULL this out
-    // when it exits
-    HostThread private_state_thread(m_private_state_thread);
-    if (private_state_thread.IsJoinable())
+    // Signal the private state thread
+    if (PrivateStateThreadIsValid())
     {
         TimeValue timeout_time;
         bool timed_out;
@@ -4134,7 +4131,7 @@ Process::ControlPrivateStateThread (uint
         {
             if (timed_out)
             {
-                Error error = private_state_thread.Cancel();
+                Error error = m_private_state_thread.Cancel();
                 if (log)
                     log->Printf ("Timed out responding to the control event, 
cancel got error: \"%s\".", error.AsCString());
             }
@@ -4145,7 +4142,7 @@ Process::ControlPrivateStateThread (uint
             }
 
             thread_result_t result = NULL;
-            private_state_thread.Join(&result);
+            m_private_state_thread.Join(&result);
             m_private_state_thread.Reset();
         }
     }
@@ -4449,7 +4446,6 @@ Process::RunPrivateStateThread (bool is_
     if (!is_secondary_thread)
         m_public_run_lock.SetStopped();
     m_private_state_control_wait.SetValue (true, eBroadcastAlways);
-    m_private_state_thread.Reset();
     return NULL;
 }
 


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to