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
11#include "lldb/Target/Unwind.h"
13#include "lldb/Utility/Log.h"
14
15#include "ProcessWindows.h"
16#include "TargetThreadWindows.h"
18#include <llvm/Support/ConvertUTF.h>
19
20#if defined(__x86_64__) || defined(_M_AMD64)
22#elif defined(__i386__) || defined(_M_IX86)
24#elif defined(__aarch64__) || defined(_M_ARM64)
26#elif defined(__arm__) || defined(_M_ARM)
28#endif
29
30using namespace lldb;
31using namespace lldb_private;
32
34 const HostThread &thread)
35 : Thread(process, thread.GetNativeThread().GetThreadId()),
37
39
41 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
43 GetRegisterContext()->InvalidateIfNeeded(false);
44}
45
47
49
56
59 RegisterContextSP reg_ctx_sp;
60 uint32_t concrete_frame_idx = 0;
62
63 if (frame)
64 concrete_frame_idx = frame->GetConcreteFrameIndex();
65
66 if (concrete_frame_idx == 0) {
68 ArchSpec arch = HostInfo::GetArchitecture();
69 switch (arch.GetMachine()) {
70 case llvm::Triple::arm:
71 case llvm::Triple::thumb:
72#if defined(__arm__) || defined(_M_ARM)
74 new RegisterContextWindows_arm(*this, concrete_frame_idx));
75#else
76 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
77#endif
78 break;
79
80 case llvm::Triple::aarch64:
81#if defined(__aarch64__) || defined(_M_ARM64)
83 new RegisterContextWindows_arm64(*this, concrete_frame_idx));
84#else
85 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
86#endif
87 break;
88
89 case llvm::Triple::x86:
90#if defined(__i386__) || defined(_M_IX86)
92 new RegisterContextWindows_x86(*this, concrete_frame_idx));
93#else
94 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
95#endif
96 break;
97
98 case llvm::Triple::x86_64:
99#if defined(__x86_64__) || defined(_M_AMD64)
101 new RegisterContextWindows_x64(*this, concrete_frame_idx));
102#else
103 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
104#endif
105 break;
106
107 default:
108 break;
109 }
110 }
111 reg_ctx_sp = m_thread_reg_ctx_sp;
112 } else {
113 reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
114 }
115
116 return reg_ctx_sp;
117}
118
123
125 StateType resume_state = GetTemporaryResumeState();
126 StateType current_state = GetState();
127 if (resume_state == current_state)
128 return Status();
129
130 if (resume_state == eStateStepping) {
131 Log *log = GetLog(LLDBLog::Thread);
132
133 uint32_t flags_index =
134 GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
136 uint64_t flags_value =
137 GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
138 ProcessSP process = GetProcess();
139 const ArchSpec &arch = process->GetTarget().GetArchitecture();
140 switch (arch.GetMachine()) {
141 case llvm::Triple::x86:
142 case llvm::Triple::x86_64:
143 flags_value |= 0x100; // Set the trap flag on the CPU
144 break;
145 case llvm::Triple::aarch64:
146 case llvm::Triple::arm:
147 case llvm::Triple::thumb:
148 flags_value |= 0x200000; // The SS bit in PState
149 break;
150 default:
151 LLDB_LOG(log, "single stepping unsupported on this architecture");
152 break;
153 }
154 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
155 }
156
157 if (resume_state == eStateStepping || resume_state == eStateRunning) {
158 DWORD previous_suspend_count = 0;
159 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
160 do {
161 // ResumeThread returns -1 on error, or the thread's *previous* suspend
162 // count on success. This means that the return value is 1 when the thread
163 // was restarted. Note that DWORD is an unsigned int, so we need to
164 // explicitly compare with -1.
165 previous_suspend_count = ::ResumeThread(thread_handle);
166
167 if (previous_suspend_count == static_cast<DWORD>(-1))
168 return Status(::GetLastError(), eErrorTypeWin32);
169
170 } while (previous_suspend_count > 1);
171 }
172
173 return Status();
174}
175
177 Log *log = GetLog(LLDBLog::Thread);
178 static LazyImport<HRESULT(WINAPI *)(HANDLE, PWSTR *)>
179 s_get_thread_description{L"Kernel32.dll", "GetThreadDescription"};
180 if (!s_get_thread_description)
181 return m_name.c_str();
182 auto GetThreadDescription = *s_get_thread_description;
183
184 PWSTR pszThreadName;
185 if (SUCCEEDED(GetThreadDescription(
186 m_host_thread.GetNativeThread().GetSystemHandle(), &pszThreadName))) {
187 LLDB_LOGF(log, "GetThreadDescription: %ls", pszThreadName);
188 m_name.clear();
189 llvm::convertUTF16ToUTF8String(
190 llvm::ArrayRef(reinterpret_cast<char *>(pszThreadName),
191 wcslen(pszThreadName) * sizeof(wchar_t)),
192 m_name);
193 ::LocalFree(pszThreadName);
194 }
195
196 return m_name.c_str();
197}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
#define LLDB_LOGF(log,...)
Definition Log.h:378
void * HANDLE
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition ArchSpec.cpp:682
virtual uint32_t GetConcreteFrameIndex()
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
Definition StackFrame.h:486
An error handling class.
Definition Status.h:118
bool CalculateStopInfo() override
Ask the thread subclass to set its stop info.
TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
lldb::RegisterContextSP GetRegisterContext() override
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame) override
void WillResume(lldb::StateType resume_state) override
lldb::RegisterContextSP m_thread_reg_ctx_sp
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
Definition Thread.cpp:479
virtual void DestroyThread()
Definition Thread.cpp:259
virtual Unwind & GetUnwinder()
Definition Thread.cpp:2252
Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id=false)
Constructor.
Definition Thread.cpp:226
lldb::StateType GetTemporaryResumeState() const
Definition Thread.h:1269
void SetState(lldb::StateType state)
Definition Thread.cpp:589
lldb::ProcessSP GetProcess() const
Definition Thread.h:162
friend class StackFrame
Definition Thread.h:1371
lldb::StopInfoSP m_stop_info_sp
The private stop reason for this thread.
Definition Thread.h:1420
lldb::StateType GetState() const
Definition Thread.cpp:583
lldb::RegisterContextSP m_reg_context_sp
The register context for this thread's current register state.
Definition Thread.h:1436
lldb::RegisterContextSP CreateRegisterContextForFrame(StackFrame *frame)
Definition Unwind.h:56
#define LLDB_REGNUM_GENERIC_FLAGS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eErrorTypeWin32
Standard Win32 error codes.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target