Author: gclayton
Date: Mon Jun  1 18:14:09 2015
New Revision: 238794

URL: http://llvm.org/viewvc/llvm-project?rev=238794&view=rev
Log:
Fix a race condition where 2 threads might try to call Process::SetExitStatus() 
at the same time. 

The problem was the mutex was only protecting the setting of m_exit_string and 
m_exit_string, but this function relies on the m_private_state being set to 
eStateExited in order to prevent more than 1 client setting the exit status. We 
want to only allow the first caller to succeed.

On MacOSX we have a thread that reaps the process we are debugging, and we also 
have a thread that monitors the debugserver process. When a process exists, the 
ProcessGDBRemote::AsyncThread() would set the exit status to the correct value 
and then another thread would reap the debugserver process and they would often 
both end up in Process::SetExitStatus() at the same time. With the mutex at the 
top we allow all variables to be set and the m_private_state to be set to 
eStateExited _before_ the other thread (debugserver reaped) can try to set th 
exist status to -1 and "lost connection to debugserver" being set as the exit 
status.

This was probably an issue for lldb-server as well and could very well cleanup 
some tests that might have been expecting a specific exit status from the 
process being debugged.


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

Modified: lldb/trunk/source/Target/Process.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=238794&r1=238793&r2=238794&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Mon Jun  1 18:14:09 2015
@@ -1429,6 +1429,9 @@ Process::GetExitDescription ()
 bool
 Process::SetExitStatus (int status, const char *cstr)
 {
+    // Use a mutex to protect setting the exit status.
+    Mutex::Locker locker (m_exit_status_mutex);
+
     Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | 
LIBLLDB_LOG_PROCESS));
     if (log)
         log->Printf("Process::SetExitStatus (status=%i (0x%8.8x), 
description=%s%s%s)", 
@@ -1444,17 +1447,12 @@ Process::SetExitStatus (int status, cons
             log->Printf("Process::SetExitStatus () ignoring exit status 
because state was already set to eStateExited");
         return false;
     }
-    
-    // use a mutex to protect the status and string during updating
-    {
-        Mutex::Locker locker (m_exit_status_mutex);
 
-        m_exit_status = status;
-        if (cstr)
-            m_exit_string = cstr;
-        else
-            m_exit_string.clear();
-    }
+    m_exit_status = status;
+    if (cstr)
+        m_exit_string = cstr;
+    else
+        m_exit_string.clear();
 
     // When we exit, we no longer need to the communication channel
     m_stdio_communication.StopReadThread();


_______________________________________________
lldb-commits mailing list
lldb-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to