diff options
Diffstat (limited to 'source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp')
| -rw-r--r-- | source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp | 76 |
1 files changed, 49 insertions, 27 deletions
diff --git a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp index a4d60303877e0..3903280918cc8 100644 --- a/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp +++ b/source/Plugins/Process/Windows/Common/TargetThreadWindows.cpp @@ -16,10 +16,10 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" +#include "Plugins/Process/Utility/UnwindLLDB.h" #include "ProcessWindows.h" #include "ProcessWindowsLog.h" #include "TargetThreadWindows.h" -#include "UnwindLLDB.h" #if defined(_WIN64) #include "x64/RegisterContextWindows_x64.h" @@ -33,7 +33,7 @@ using namespace lldb_private; TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread) : Thread(process, thread.GetNativeThread().GetThreadId()), - m_host_thread(thread) {} + m_thread_reg_ctx_sp(), m_host_thread(thread) {} TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); } @@ -49,40 +49,53 @@ void TargetThreadWindows::DidStop() {} RegisterContextSP TargetThreadWindows::GetRegisterContext() { if (!m_reg_context_sp) - m_reg_context_sp = CreateRegisterContextForFrameIndex(0); + m_reg_context_sp = CreateRegisterContextForFrame(nullptr); return m_reg_context_sp; } RegisterContextSP TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) { - return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex()); -} - -RegisterContextSP -TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) { - if (!m_reg_context_sp) { - ArchSpec arch = HostInfo::GetArchitecture(); - switch (arch.GetMachine()) { - case llvm::Triple::x86: + RegisterContextSP reg_ctx_sp; + uint32_t concrete_frame_idx = 0; + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); + + if (frame) + concrete_frame_idx = frame->GetConcreteFrameIndex(); + + if (concrete_frame_idx == 0) { + if (!m_thread_reg_ctx_sp) { + ArchSpec arch = HostInfo::GetArchitecture(); + switch (arch.GetMachine()) { + case llvm::Triple::x86: #if defined(_WIN64) -// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 + // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64 + LLDB_LOG(log, "This is a Wow64 process, we should create a " + "RegisterContextWindows_Wow64, but we don't."); #else - m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx)); + m_thread_reg_ctx_sp.reset( + new RegisterContextWindows_x86(*this, concrete_frame_idx)); #endif - break; - case llvm::Triple::x86_64: + break; + case llvm::Triple::x86_64: #if defined(_WIN64) - m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx)); + m_thread_reg_ctx_sp.reset( + new RegisterContextWindows_x64(*this, concrete_frame_idx)); #else -// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug -// this. + LLDB_LOG(log, "LLDB is 32-bit, but the target process is 64-bit."); #endif - default: - break; + default: + break; + } } + reg_ctx_sp = m_thread_reg_ctx_sp; + } else { + Unwind *unwinder = GetUnwinder(); + if (unwinder != nullptr) + reg_ctx_sp = unwinder->CreateRegisterContextForFrame(frame); } - return m_reg_context_sp; + + return reg_ctx_sp; } bool TargetThreadWindows::CalculateStopInfo() { @@ -93,16 +106,16 @@ bool TargetThreadWindows::CalculateStopInfo() { Unwind *TargetThreadWindows::GetUnwinder() { // FIXME: Implement an unwinder based on the Windows unwinder exposed through // DIA SDK. - if (m_unwinder_ap.get() == NULL) + if (!m_unwinder_ap) m_unwinder_ap.reset(new UnwindLLDB(*this)); 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 +131,17 @@ 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(); } |
