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
55
58 RegisterContextSP reg_ctx_sp;
59 uint32_t concrete_frame_idx = 0;
61
62 if (frame)
63 concrete_frame_idx = frame->GetConcreteFrameIndex();
64
65 if (concrete_frame_idx == 0) {
67 ArchSpec arch = HostInfo::GetArchitecture();
68 switch (arch.GetMachine()) {
69 case llvm::Triple::arm:
70 case llvm::Triple::thumb:
71#if defined(__arm__) || defined(_M_ARM)
73 new RegisterContextWindows_arm(*this, concrete_frame_idx));
74#else
75 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
76#endif
77 break;
78
79 case llvm::Triple::aarch64:
80#if defined(__aarch64__) || defined(_M_ARM64)
82 new RegisterContextWindows_arm64(*this, concrete_frame_idx));
83#else
84 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
85#endif
86 break;
87
88 case llvm::Triple::x86:
89#if defined(__i386__) || defined(_M_IX86)
91 new RegisterContextWindows_x86(*this, concrete_frame_idx));
92#else
93 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
94#endif
95 break;
96
97 case llvm::Triple::x86_64:
98#if defined(__x86_64__) || defined(_M_AMD64)
100 new RegisterContextWindows_x64(*this, concrete_frame_idx));
101#else
102 LLDB_LOG(log, "debugging foreign targets is currently unsupported");
103#endif
104 break;
105
106 default:
107 break;
108 }
109 }
110 reg_ctx_sp = m_thread_reg_ctx_sp;
111 } else {
112 reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
113 }
114
115 return reg_ctx_sp;
116}
117
122
124 StateType resume_state = GetTemporaryResumeState();
125 StateType current_state = GetState();
126 if (resume_state == current_state)
127 return Status();
128
129 if (resume_state == eStateStepping) {
130 Log *log = GetLog(LLDBLog::Thread);
131
132 uint32_t flags_index =
133 GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
135 uint64_t flags_value =
136 GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
137 ProcessSP process = GetProcess();
138 const ArchSpec &arch = process->GetTarget().GetArchitecture();
139 switch (arch.GetMachine()) {
140 case llvm::Triple::x86:
141 case llvm::Triple::x86_64:
142 flags_value |= 0x100; // Set the trap flag on the CPU
143 break;
144 case llvm::Triple::aarch64:
145 case llvm::Triple::arm:
146 case llvm::Triple::thumb:
147 flags_value |= 0x200000; // The SS bit in PState
148 break;
149 default:
150 LLDB_LOG(log, "single stepping unsupported on this architecture");
151 break;
152 }
153 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
154 }
155
156 if (resume_state == eStateStepping || resume_state == eStateRunning) {
157 DWORD previous_suspend_count = 0;
158 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
159 do {
160 // ResumeThread returns -1 on error, or the thread's *previous* suspend
161 // count on success. This means that the return value is 1 when the thread
162 // was restarted. Note that DWORD is an unsigned int, so we need to
163 // explicitly compare with -1.
164 previous_suspend_count = ::ResumeThread(thread_handle);
165
166 if (previous_suspend_count == static_cast<DWORD>(-1))
167 return Status(::GetLastError(), eErrorTypeWin32);
168
169 } while (previous_suspend_count > 1);
170 }
171
172 return Status();
173}
174
176 Log *log = GetLog(LLDBLog::Thread);
177 static LazyImport<HRESULT(WINAPI *)(HANDLE, PWSTR *)>
178 s_get_thread_description{L"Kernel32.dll", "GetThreadDescription"};
179 if (!s_get_thread_description)
180 return m_name.c_str();
181 auto GetThreadDescription = *s_get_thread_description;
182
183 PWSTR pszThreadName;
184 if (SUCCEEDED(GetThreadDescription(
185 m_host_thread.GetNativeThread().GetSystemHandle(), &pszThreadName))) {
186 LLDB_LOGF(log, "GetThreadDescription: %ls", pszThreadName);
187 m_name.clear();
188 llvm::convertUTF16ToUTF8String(
189 llvm::ArrayRef(reinterpret_cast<char *>(pszThreadName),
190 wcslen(pszThreadName) * sizeof(wchar_t)),
191 m_name);
192 ::LocalFree(pszThreadName);
193 }
194
195 return m_name.c_str();
196}
#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
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.
@ 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