[Go to site: main page, start]

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()),
36 m_host_thread(thread) {}
37
39
41 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
42 GetRegisterContext()->InvalidateIfNeeded(false);
43}
44
46
48 struct ThreadBasicInformation {
49 LONG ExitStatus;
50 PVOID TebBaseAddress;
51 struct {
52 HANDLE UniqueProcess;
53 HANDLE UniqueThread;
54 } ClientId;
55 ULONG_PTR AffinityMask;
56 LONG Priority;
57 LONG BasePriority;
58 };
59 using NtQueryInformationThreadFn =
60 LONG(WINAPI *)(HANDLE ThreadHandle, ULONG ThreadInformationClass,
61 PVOID ThreadInformation, ULONG ThreadInformationLength,
62 PULONG ReturnLength);
63
64 static LazyImport<NtQueryInformationThreadFn> s_query_information_thread{
65 L"Kernel32.dll", "NtQueryInformationThread"};
66 if (!s_query_information_thread)
68 auto NtQueryInformationThread = *s_query_information_thread;
69
70 HANDLE handle = m_host_thread.GetNativeThread().GetSystemHandle();
71 if (!handle || handle == INVALID_HANDLE_VALUE)
73
74 ThreadBasicInformation info = {};
75 // ThreadInformationClass 0 is ThreadBasicInformation.
76 if (NtQueryInformationThread(handle, 0, &info, sizeof(info), nullptr) < 0)
78 if (!info.TebBaseAddress)
80
81 auto dict = std::make_shared<StructuredData::Dictionary>();
82 dict->AddIntegerItem("teb_address",
83 reinterpret_cast<uint64_t>(info.TebBaseAddress));
84 return dict;
85}
86
88
95
98 RegisterContextSP reg_ctx_sp;
99 uint32_t concrete_frame_idx = 0;
100 Log *log = GetLog(LLDBLog::Thread);
101
102 if (frame)
103 concrete_frame_idx = frame->GetConcreteFrameIndex();
104
105 if (concrete_frame_idx == 0) {
106 if (!m_thread_reg_ctx_sp) {
107 ArchSpec arch = HostInfo::GetArchitecture();
108 switch (arch.GetMachine()) {
109 case llvm::Triple::arm:
110 case llvm::Triple::thumb:
111#if defined(__arm__) || defined(_M_ARM)
113 new RegisterContextWindows_arm(*this, concrete_frame_idx));
114#else
115 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
116#endif
117 break;
118
119 case llvm::Triple::aarch64:
120#if defined(__aarch64__) || defined(_M_ARM64)
122 new RegisterContextWindows_arm64(*this, concrete_frame_idx));
123#else
124 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
125#endif
126 break;
127
128 case llvm::Triple::x86:
129#if defined(__i386__) || defined(_M_IX86)
131 new RegisterContextWindows_x86(*this, concrete_frame_idx));
132#else
133 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
134#endif
135 break;
136
137 case llvm::Triple::x86_64:
138#if defined(__x86_64__) || defined(_M_AMD64)
140 new RegisterContextWindows_x64(*this, concrete_frame_idx));
141#else
142 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
143#endif
144 break;
145
146 default:
147 break;
148 }
149 }
150 reg_ctx_sp = m_thread_reg_ctx_sp;
151 } else {
152 reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
153 }
154
155 return reg_ctx_sp;
156}
157
162
164 StateType resume_state = GetTemporaryResumeState();
165 StateType current_state = GetState();
166 if (resume_state == current_state)
167 return Status();
168
169 if (resume_state == eStateStepping) {
170 Log *log = GetLog(LLDBLog::Thread);
171
172 uint32_t flags_index =
173 GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
175 uint64_t flags_value =
176 GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
177 ProcessSP process = GetProcess();
178 const ArchSpec &arch = process->GetTarget().GetArchitecture();
179 switch (arch.GetMachine()) {
180 case llvm::Triple::x86:
181 case llvm::Triple::x86_64:
182 flags_value |= 0x100; // Set the trap flag on the CPU
183 break;
184 case llvm::Triple::aarch64:
185 case llvm::Triple::arm:
186 case llvm::Triple::thumb:
187 flags_value |= 0x200000; // The SS bit in PState
188 break;
189 default:
190 LLDB_LOG(log, "single stepping unsupported on this architecture");
191 break;
192 }
193 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
194 }
195
196 if (resume_state == eStateStepping || resume_state == eStateRunning) {
197 DWORD previous_suspend_count = 0;
198 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
199 do {
200 // ResumeThread returns -1 on error, or the thread's *previous* suspend
201 // count on success. This means that the return value is 1 when the thread
202 // was restarted. Note that DWORD is an unsigned int, so we need to
203 // explicitly compare with -1.
204 previous_suspend_count = ::ResumeThread(thread_handle);
205
206 if (previous_suspend_count == static_cast<DWORD>(-1))
207 return Status(::GetLastError(), eErrorTypeWin32);
208
209 } while (previous_suspend_count > 1);
210 }
211
212 return Status();
213}
214
216 Log *log = GetLog(LLDBLog::Thread);
217 static LazyImport<HRESULT(WINAPI *)(HANDLE, PWSTR *)>
218 s_get_thread_description{L"Kernel32.dll", "GetThreadDescription"};
219 if (!s_get_thread_description)
220 return m_name.c_str();
221 auto GetThreadDescription = *s_get_thread_description;
222
223 PWSTR pszThreadName;
224 if (SUCCEEDED(GetThreadDescription(
225 m_host_thread.GetNativeThread().GetSystemHandle(), &pszThreadName))) {
226 LLDB_LOGF(log, "GetThreadDescription: %ls", pszThreadName);
227 m_name.clear();
228 llvm::convertUTF16ToUTF8String(
229 llvm::ArrayRef(reinterpret_cast<char *>(pszThreadName),
230 wcslen(pszThreadName) * sizeof(wchar_t)),
231 m_name);
232 ::LocalFree(pszThreadName);
233 }
234
235 return m_name.c_str();
236}
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOGF(log,...)
Definition Log.h:389
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:881
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
std::shared_ptr< Object > ObjectSP
bool CalculateStopInfo() override
Ask the thread subclass to set its stop info.
TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
lldb_private::StructuredData::ObjectSP FetchThreadExtendedInfo() override
Exposes this thread's TEB address under the "teb_address" key, so that language runtimes can resolve ...
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:2256
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
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:338
StateType
Process and Thread States.
@ 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