LLDB  mainline
TargetThreadWindows.cpp
Go to the documentation of this file.
1 //===-- TargetThreadWindows.cpp--------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Host/HostInfo.h"
14 #include "lldb/Target/Unwind.h"
15 #include "lldb/Utility/Log.h"
16 #include "lldb/Utility/Logging.h"
17 #include "lldb/Utility/State.h"
18 
19 #include "ProcessWindows.h"
20 #include "ProcessWindowsLog.h"
21 #include "TargetThreadWindows.h"
22 
23 #if defined(__x86_64__) || defined(_M_AMD64)
25 #elif defined(__i386__) || defined(_M_IX86)
27 #elif defined(__aarch64__) || defined(_M_ARM64)
29 #elif defined(__arm__) || defined(_M_ARM)
31 #endif
32 
33 using namespace lldb;
34 using namespace lldb_private;
35 
36 TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
37  const HostThread &thread)
38  : Thread(process, thread.GetNativeThread().GetThreadId()),
39  m_thread_reg_ctx_sp(), m_host_thread(thread) {}
40 
42 
44  ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
46  GetRegisterContext()->InvalidateIfNeeded(false);
47 }
48 
50 
52 
54  if (!m_reg_context_sp)
56 
57  return m_reg_context_sp;
58 }
59 
60 RegisterContextSP
62  RegisterContextSP reg_ctx_sp;
63  uint32_t concrete_frame_idx = 0;
65 
66  if (frame)
67  concrete_frame_idx = frame->GetConcreteFrameIndex();
68 
69  if (concrete_frame_idx == 0) {
70  if (!m_thread_reg_ctx_sp) {
71  ArchSpec arch = HostInfo::GetArchitecture();
72  switch (arch.GetMachine()) {
73  case llvm::Triple::arm:
74  case llvm::Triple::thumb:
75 #if defined(__arm__) || defined(_M_ARM)
76  m_thread_reg_ctx_sp.reset(
77  new RegisterContextWindows_arm(*this, concrete_frame_idx));
78 #else
79  LLDB_LOG(log, "debugging foreign targets is currently unsupported");
80 #endif
81  break;
82 
83  case llvm::Triple::aarch64:
84 #if defined(__aarch64__) || defined(_M_ARM64)
85  m_thread_reg_ctx_sp.reset(
86  new RegisterContextWindows_arm64(*this, concrete_frame_idx));
87 #else
88  LLDB_LOG(log, "debugging foreign targets is currently unsupported");
89 #endif
90  break;
91 
92  case llvm::Triple::x86:
93 #if defined(__i386__) || defined(_M_IX86)
94  m_thread_reg_ctx_sp.reset(
95  new RegisterContextWindows_x86(*this, concrete_frame_idx));
96 #else
97  LLDB_LOG(log, "debugging foreign targets is currently unsupported");
98 #endif
99  break;
100 
101  case llvm::Triple::x86_64:
102 #if defined(__x86_64__) || defined(_M_AMD64)
103  m_thread_reg_ctx_sp.reset(
104  new RegisterContextWindows_x64(*this, concrete_frame_idx));
105 #else
106  LLDB_LOG(log, "debugging foreign targets is currently unsupported");
107 #endif
108  break;
109 
110  default:
111  break;
112  }
113  }
114  reg_ctx_sp = m_thread_reg_ctx_sp;
115  } else {
116  reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
117  }
118 
119  return reg_ctx_sp;
120 }
121 
124  return true;
125 }
126 
128  StateType resume_state = GetTemporaryResumeState();
129  StateType current_state = GetState();
130  if (resume_state == current_state)
131  return Status();
132 
133  if (resume_state == eStateStepping) {
135 
136  uint32_t flags_index =
137  GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
139  uint64_t flags_value =
140  GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
141  ProcessSP process = GetProcess();
142  const ArchSpec &arch = process->GetTarget().GetArchitecture();
143  switch (arch.GetMachine()) {
144  case llvm::Triple::x86:
145  case llvm::Triple::x86_64:
146  flags_value |= 0x100; // Set the trap flag on the CPU
147  break;
148  case llvm::Triple::aarch64:
149  case llvm::Triple::arm:
150  case llvm::Triple::thumb:
151  flags_value |= 0x200000; // The SS bit in PState
152  break;
153  default:
154  LLDB_LOG(log, "single stepping unsupported on this architecture");
155  break;
156  }
157  GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
158  }
159 
160  if (resume_state == eStateStepping || resume_state == eStateRunning) {
161  DWORD previous_suspend_count = 0;
162  HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
163  do {
164  // ResumeThread returns -1 on error, or the thread's *previous* suspend
165  // count on success. This means that the return value is 1 when the thread
166  // was restarted. Note that DWORD is an unsigned int, so we need to
167  // explicitly compare with -1.
168  previous_suspend_count = ::ResumeThread(thread_handle);
169 
170  if (previous_suspend_count == (DWORD)-1)
171  return Status(::GetLastError(), eErrorTypeWin32);
172 
173  } while (previous_suspend_count > 1);
174  }
175 
176  return Status();
177 }
lldb_private::TargetThreadWindows::CalculateStopInfo
bool CalculateStopInfo() override
Definition: TargetThreadWindows.cpp:122
ProcessWindows.h
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::HostThread::GetNativeThread
HostNativeThread & GetNativeThread()
Definition: HostThread.cpp:32
lldb_private::ArchSpec::GetMachine
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:667
lldb_private::HostThread
Definition: HostThread.h:29
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
lldb_private::Thread::GetUnwinder
virtual Unwind & GetUnwinder()
Definition: Thread.cpp:1862
lldb_private::TargetThreadWindows::RefreshStateAfterStop
void RefreshStateAfterStop() override
Definition: TargetThreadWindows.cpp:43
Unwind.h
lldb_private::TargetThreadWindows::GetRegisterContext
lldb::RegisterContextSP GetRegisterContext() override
Definition: TargetThreadWindows.cpp:53
TargetThreadWindows.h
lldb_private::TargetThreadWindows::m_host_thread
HostThread m_host_thread
Definition: TargetThreadWindows.h:44
lldb_private::ProcessWindows
Definition: ProcessWindows.h:23
lldb_private::TargetThreadWindows::CreateRegisterContextForFrame
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override
Definition: TargetThreadWindows.cpp:61
lldb::eErrorTypeWin32
@ eErrorTypeWin32
Standard Win32 error codes.
Definition: lldb-enumerations.h:312
lldb_private::Thread::GetState
lldb::StateType GetState() const
Definition: Thread.cpp:538
HostNativeThreadBase.h
ProcessWindowsLog.h
lldb::eStateStopped
@ eStateStopped
Process or thread is stopped and can be examined.
Definition: lldb-enumerations.h:84
lldb_private::StackFrame::GetConcreteFrameIndex
uint32_t GetConcreteFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
Definition: StackFrame.h:407
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:67
lldb_private::Thread::DestroyThread
virtual void DestroyThread()
Definition: Thread.cpp:248
lldb_private::TargetThreadWindows::DidStop
void DidStop() override
Definition: TargetThreadWindows.cpp:51
Log.h
lldb_private::Thread
Definition: Thread.h:62
lldb_private::Thread::GetTemporaryResumeState
lldb::StateType GetTemporaryResumeState() const
Definition: Thread.h:1156
lldb_private::Thread::SetStopInfo
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
Definition: Thread.cpp:434
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
HostInfo.h
lldb_private::Thread::SetState
void SetState(lldb::StateType state)
Definition: Thread.cpp:544
lldb_private::HostNativeThreadBase::GetSystemHandle
lldb::thread_t GetSystemHandle() const
Definition: HostNativeThreadBase.cpp:23
lldb_private::TargetThreadWindows::WillResume
void WillResume(lldb::StateType resume_state) override
Definition: TargetThreadWindows.cpp:49
lldb_private::Thread::m_stop_info_sp
lldb::StopInfoSP m_stop_info_sp
The private stop reason for this thread.
Definition: Thread.h:1239
lldb_private::Unwind::CreateRegisterContextForFrame
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame)
Definition: Unwind.h:56
lldb::eStateStepping
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
Definition: lldb-enumerations.h:86
RegisterContextWindows_x64.h
lldb_private::TargetThreadWindows::DoResume
Status DoResume()
Definition: TargetThreadWindows.cpp:127
lldb_private::Status
Definition: Status.h:44
lldb_private::Thread::m_reg_context_sp
lldb::RegisterContextSP m_reg_context_sp
The register context for this thread's current register state.
Definition: Thread.h:1249
uint32_t
RegisterContextWindows_arm.h
windows.h
LLDB_LOG
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:242
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::TargetThreadWindows::m_thread_reg_ctx_sp
lldb::RegisterContextSP m_thread_reg_ctx_sp
Definition: TargetThreadWindows.h:43
Logging.h
State.h
RegisterContextWindows_x86.h
lldb::StateType
StateType
Process and Thread States.
Definition: lldb-enumerations.h:73
lldb_private::Log
Definition: Log.h:49
lldb_private::TargetThreadWindows::~TargetThreadWindows
virtual ~TargetThreadWindows()
Definition: TargetThreadWindows.cpp:41
lldb_private::StackFrame
Definition: StackFrame.h:40
lldb
Definition: SBAddress.h:15
LIBLLDB_LOG_THREAD
#define LIBLLDB_LOG_THREAD
Definition: Logging.h:16
lldb::eStateRunning
@ eStateRunning
Process or thread is running and can't be examined.
Definition: lldb-enumerations.h:85
RegisterContext.h
HostThreadWindows.h
RegisterContextWindows_arm64.h