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