summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
diff options
context:
space:
mode:
authorAaron Smith <aaron.smith@microsoft.com>2019-08-13 22:18:01 +0000
committerAaron Smith <aaron.smith@microsoft.com>2019-08-13 22:18:01 +0000
commit5146a9ea5d8d3c91cee5d2d2ad4c50491e7a4c58 (patch)
tree35b54606f3f707ba55852b196d45161be9fd5a0a /lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
parentb809187a6b4229569f61d9dc3c59fd4ec0775448 (diff)
downloadbcm5719-llvm-5146a9ea5d8d3c91cee5d2d2ad4c50491e7a4c58.tar.gz
bcm5719-llvm-5146a9ea5d8d3c91cee5d2d2ad4c50491e7a4c58.zip
Initial support for native debugging of x86/x64 Windows processes
Summary: Thanks to Hui Huang and the reviewers for all the help with this patch. Reviewers: labath, Hui, jfb, clayborg, amccarth Reviewed By: labath Subscribers: amccarth, compnerd, dexonsmith, mgorny, jfb, teemperor, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D63165 llvm-svn: 368759
Diffstat (limited to 'lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp')
-rw-r--r--lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp149
1 files changed, 149 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
new file mode 100644
index 00000000000..6fd72d675fb
--- /dev/null
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
@@ -0,0 +1,149 @@
+//===-- NativeThreadWindows.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "NativeThreadWindows.h"
+#include "NativeProcessWindows.h"
+
+#include "lldb/Host/HostThread.h"
+#include "lldb/Host/Windows/HostThreadWindows.h"
+#include "lldb/Host/windows/windows.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/State.h"
+
+#include "lldb/lldb-forward.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+NativeThreadWindows::NativeThreadWindows(NativeProcessWindows &process,
+ const HostThread &thread)
+ : NativeThreadProtocol(process, thread.GetNativeThread().GetThreadId()),
+ m_stop_info(), m_stop_description(), m_host_thread(thread) {
+ m_reg_context_up =
+ (NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
+ process.GetArchitecture(), *this));
+}
+
+Status NativeThreadWindows::DoStop() {
+ if (m_state != eStateStopped) {
+ DWORD previous_suspend_count =
+ ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
+ if (previous_suspend_count == (DWORD)-1)
+ return Status(::GetLastError(), eErrorTypeWin32);
+
+ m_state = eStateStopped;
+ }
+ return Status();
+}
+
+Status NativeThreadWindows::DoResume(lldb::StateType resume_state) {
+ StateType current_state = GetState();
+ if (resume_state == current_state)
+ return Status();
+
+ if (resume_state == eStateStepping) {
+ uint32_t flags_index =
+ GetRegisterContext().ConvertRegisterKindToRegisterNumber(
+ eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
+ uint64_t flags_value =
+ GetRegisterContext().ReadRegisterAsUnsigned(flags_index, 0);
+ flags_value |= 0x100; // Set the trap flag on the CPU
+ GetRegisterContext().WriteRegisterFromUnsigned(flags_index, flags_value);
+ }
+
+ if (resume_state == eStateStepping || resume_state == eStateRunning) {
+ 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);
+
+ if (previous_suspend_count == (DWORD)-1)
+ return Status(::GetLastError(), eErrorTypeWin32);
+
+ } while (previous_suspend_count > 1);
+ m_state = eStateRunning;
+ }
+
+ return Status();
+}
+
+std::string NativeThreadWindows::GetName() {
+ if (!m_name.empty())
+ return m_name;
+
+ // Name is not a property of the Windows thread. Create one with the
+ // process's.
+ NativeProcessProtocol &process = GetProcess();
+ ProcessInstanceInfo process_info;
+ if (Host::GetProcessInfo(process.GetID(), process_info)) {
+ std::string process_name(process_info.GetName());
+ m_name = process_name;
+ }
+ return m_name;
+}
+
+void NativeThreadWindows::SetStopReason(ThreadStopInfo stop_info,
+ std::string description) {
+ m_state = eStateStopped;
+ m_stop_info = stop_info;
+ m_stop_description = description;
+}
+
+bool NativeThreadWindows::GetStopReason(ThreadStopInfo &stop_info,
+ std::string &description) {
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
+
+ switch (m_state) {
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ case eStateUnloaded:
+ stop_info = m_stop_info;
+ description = m_stop_description;
+ return true;
+
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ if (log) {
+ log->Printf("NativeThreadWindows::%s tid %" PRIu64
+ " in state %s cannot answer stop reason",
+ __FUNCTION__, GetID(), StateAsCString(m_state));
+ }
+ return false;
+ }
+ llvm_unreachable("unhandled StateType!");
+}
+
+Status NativeThreadWindows::SetWatchpoint(lldb::addr_t addr, size_t size,
+ uint32_t watch_flags, bool hardware) {
+ return Status("unimplemented.");
+}
+
+Status NativeThreadWindows::RemoveWatchpoint(lldb::addr_t addr) {
+ return Status("unimplemented");
+}
+
+Status NativeThreadWindows::SetHardwareBreakpoint(lldb::addr_t addr,
+ size_t size) {
+ return Status("unimplemented.");
+}
+
+Status NativeThreadWindows::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+ return Status("unimplemented.");
+}
OpenPOWER on IntegriCloud