diff options
author | Greg Clayton <gclayton@apple.com> | 2015-06-01 23:14:09 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2015-06-01 23:14:09 +0000 |
commit | 81e2b6bbe78ec34f197809d9eaa3bdd05619149d (patch) | |
tree | 0fd52d8f2eebd9e17f73538ed1d869779db42a57 /lldb/source/Target/Process.cpp | |
parent | 72b8f74813192fc4305b4b346e0e13769caf9686 (diff) | |
download | bcm5719-llvm-81e2b6bbe78ec34f197809d9eaa3bdd05619149d.tar.gz bcm5719-llvm-81e2b6bbe78ec34f197809d9eaa3bdd05619149d.zip |
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.
llvm-svn: 238794
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r-- | lldb/source/Target/Process.cpp | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 88a07b9613d..cc3b8761f0a 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -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, const char *cstr) 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(); |