Author: zturner
Date: Thu Sep 17 15:18:50 2015
New Revision: 247929

URL: http://llvm.org/viewvc/llvm-project?rev=247929&view=rev
Log:
Fix a race condition when terminating inferiors on Windows.

If a breakpoint was hit in the inferior after shutdown had
started but before it was complete, it would cause an unclean
terminate of the inferior, leading to various problems the most
visible of which is that handles to the inferior executable would
remain locked, and the test suite would fail to run subsequent
tests because it could not recompile the inferior.

This fixes a major source of flakiness in the test suite.

Modified:
    lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
    lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.h

Modified: lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp?rev=247929&r1=247928&r2=247929&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp Thu Sep 
17 15:18:50 2015
@@ -63,6 +63,7 @@ DebuggerThread::DebuggerThread(DebugDele
     : m_debug_delegate(debug_delegate)
     , m_image_file(nullptr)
     , m_debugging_ended_event(nullptr)
+    , m_is_shutting_down(false)
     , m_pid_to_detach(0)
     , m_detached(false)
 {
@@ -194,6 +195,11 @@ DebuggerThread::StopDebugging(bool termi
         "StopDebugging('%s') called (inferior=%I64u).",
         (terminate ? "true" : "false"), pid);
 
+    // Set m_is_shutting_down to true if it was false.  Return if it was 
already true.
+    bool expected = false;
+    if (!m_is_shutting_down.compare_exchange_strong(expected, true))
+        return error;
+
     // Make a copy of the process, since the termination sequence will reset
     // DebuggerThread's internal copy and it needs to remain open for the Wait 
operation.
     HostProcess process_copy = m_process;
@@ -298,6 +304,14 @@ DebuggerThread::DebugLoop()
             {
                 case EXCEPTION_DEBUG_EVENT:
                 {
+                    if (m_is_shutting_down)
+                    {
+                        // Don't perform any blocking operations while we're 
shutting down.  That will
+                        // cause TerminateProcess -> WaitForSingleObject to 
time out.
+                        continue_status = DBG_EXCEPTION_NOT_HANDLED;
+                        break;
+                    }
+
                     ExceptionResult status = 
HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
 
                     if (status == ExceptionResult::MaskException)

Modified: lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.h?rev=247929&r1=247928&r2=247929&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.h Thu Sep 17 
15:18:50 2015
@@ -86,6 +86,8 @@ class DebuggerThread : public std::enabl
                                     // exits the debugger loop and is detached 
from the inferior.
 
     std::atomic<DWORD> m_pid_to_detach;  // Signals the loop to detach from 
the process (specified by pid).
+    std::atomic<bool> m_is_shutting_down;   // Signals the debug loop to stop 
processing certain types of
+                                            // events that block shutdown.
     bool m_detached;  // Indicates we've detached from the inferior process 
and the debug loop can exit.
 
     static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);


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

Reply via email to