[Lldb-commits] [lldb] r332670 - [Windows, Process] Fix an issue in windows thread handling that was causing LLDB to hang

Stella Stamenova via lldb-commits lldb-commits at lists.llvm.org
Thu May 17 14:34:24 PDT 2018


Author: stella.stamenova
Date: Thu May 17 14:34:24 2018
New Revision: 332670

URL: http://llvm.org/viewvc/llvm-project?rev=332670&view=rev
Log:
[Windows, Process] Fix an issue in windows thread handling that was causing LLDB to hang

Summary: The function ResumeThread on Windows returns a DWORD which is an unsigned int. In TargetThreadWindows::DoResume, there's code that determines how many times to call ResumeThread based on whether the return value is greater than 0. Since the function returns -1 (as an unsigned int) on failure, this was getting stuck in an infinite loop if ResumeThread failed for any reason. The correct thing to do is check whether the return value is -1 and then return the appropriate error instead of ignoring the return value.

Reviewers: asmith, zturner, labath

Reviewed By: zturner

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D47020

Modified:
    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.h

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp?rev=332670&r1=332669&r2=332670&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp Thu May 17 14:34:24 2018
@@ -349,13 +349,23 @@ Status ProcessWindows::DoResume() {
 
     LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
 
+    bool failed = false;
     for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
       auto thread = std::static_pointer_cast<TargetThreadWindows>(
           m_thread_list.GetThreadAtIndex(i));
-      thread->DoResume();
+      Status result = thread->DoResume();
+      if (result.Fail()) {
+        failed = true;
+        LLDB_LOG(log, "Trying to resume thread at index {0}, but failed with error {1}.", i, result);
+      }
     }
 
-    SetPrivateState(eStateRunning);
+    if (failed) {
+      error.SetErrorString("ProcessWindows::DoResume failed");
+      return error;
+    } else {
+      SetPrivateState(eStateRunning);
+    }
   } else {
     LLDB_LOG(log, "error: process %I64u is in state %u.  Returning...",
              m_session_data->m_debugger->GetProcess().GetProcessId(),

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp?rev=332670&r1=332669&r2=332670&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp Thu May 17 14:34:24 2018
@@ -98,11 +98,11 @@ Unwind *TargetThreadWindows::GetUnwinder
   return m_unwinder_ap.get();
 }
 
-bool TargetThreadWindows::DoResume() {
+Status TargetThreadWindows::DoResume() {
   StateType resume_state = GetTemporaryResumeState();
   StateType current_state = GetState();
   if (resume_state == current_state)
-    return true;
+    return Status();
 
   if (resume_state == eStateStepping) {
     uint32_t flags_index =
@@ -118,8 +118,16 @@ bool TargetThreadWindows::DoResume() {
     DWORD previous_suspend_count = 0;
     HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
     do {
+      // ResumeThread returns -1 on error, or the thread's *previous* suspend count on success.
+      // This means that the return value is 1 when the thread was restarted.
+      // Note that DWORD is an unsigned int, so we need to explicitly compare with -1.
       previous_suspend_count = ::ResumeThread(thread_handle);
-    } while (previous_suspend_count > 0);
+
+      if (previous_suspend_count == (DWORD)-1)
+        return Status(::GetLastError(), eErrorTypeWin32);
+
+    } while (previous_suspend_count > 1);
   }
-  return true;
+
+  return Status();
 }

Modified: lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.h?rev=332670&r1=332669&r2=332670&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.h (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Common/TargetThreadWindows.h Thu May 17 14:34:24 2018
@@ -37,7 +37,7 @@ public:
   bool CalculateStopInfo() override;
   Unwind *GetUnwinder() override;
 
-  bool DoResume();
+  Status DoResume();
 
   HostThread GetHostThread() const { return m_host_thread; }
 




More information about the lldb-commits mailing list