LLDB mainline
NativeThreadWindows.cpp
Go to the documentation of this file.
1//===-- NativeThreadWindows.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
17#include "lldb/Utility/Log.h"
18#include "lldb/Utility/State.h"
19
20#include <llvm/Support/ConvertUTF.h>
21
22using namespace lldb;
23using namespace lldb_private;
24
26 const HostThread &thread)
27 : NativeThreadProtocol(process, thread.GetNativeThread().GetThreadId()),
28 m_host_thread(thread) {
31 process.GetArchitecture(), *this));
32}
33
35 if (m_state != eStateStopped) {
36 DWORD previous_suspend_count =
37 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
38 if (previous_suspend_count == static_cast<DWORD>(-1))
39 return Status(::GetLastError(), eErrorTypeWin32);
40
41 // Invalidate cached register values on every stop.
43
45 }
46 return Status();
47}
48
50 StateType current_state = GetState();
51 if (resume_state == current_state)
52 return Status();
53
54 lldb::addr_t step_start_pc = LLDB_INVALID_ADDRESS;
55 if (resume_state == eStateStepping) {
58 }
59
60 if (resume_state == eStateStepping || resume_state == eStateRunning) {
61 // Clear any stop info left over from a previous stop.
63
64 DWORD previous_suspend_count = 0;
65 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
66 do {
67 // ResumeThread returns -1 on error, or the thread's *previous* suspend
68 // count on success. This means that the return value is 1 when the thread
69 // was restarted. Note that DWORD is an unsigned int, so we need to
70 // explicitly compare with -1.
71 previous_suspend_count = ::ResumeThread(thread_handle);
72
73 if (previous_suspend_count == static_cast<DWORD>(-1))
74 return Status(::GetLastError(), eErrorTypeWin32);
75
76 } while (previous_suspend_count > 1);
78 m_single_stepping = resume_state == eStateStepping;
79 m_single_step_start_pc = step_start_pc;
80 }
81
82 return Status();
83}
84
87
88 uint32_t flags_index =
91 uint64_t flags_value =
93 const ArchSpec &arch = GetProcess().GetArchitecture();
94 switch (arch.GetMachine()) {
95 case llvm::Triple::x86:
96 case llvm::Triple::x86_64:
97 flags_value |= 0x100; // Set the trap flag on the CPU
98 break;
99 case llvm::Triple::aarch64:
100 case llvm::Triple::arm:
101 case llvm::Triple::thumb:
102 flags_value |= 0x200000; // The SS bit in PState
103 break;
104 default:
105 LLDB_LOG(log, "single stepping unsupported on this architecture");
106 break;
107 }
108 GetRegisterContext().WriteRegisterFromUnsigned(flags_index, flags_value);
109}
110
112 lldb::addr_t start_pc =
114 if (start_pc == LLDB_INVALID_ADDRESS ||
115 (m_stop_info.reason != eStopReasonInvalid &&
116 m_stop_info.reason != eStopReasonNone) ||
117 GetRegisterContext().GetPC(start_pc) == start_pc)
118 return false;
120 return true;
121}
122
124 Log *log = GetLog(LLDBLog::Thread);
125 static LazyImport<HRESULT(WINAPI *)(HANDLE, PWSTR *)>
126 s_get_thread_description{L"Kernel32.dll", "GetThreadDescription"};
127 if (!s_get_thread_description)
128 return m_name;
129 auto GetThreadDescription = *s_get_thread_description;
130
131 PWSTR pszThreadName;
132 if (SUCCEEDED(GetThreadDescription(
133 m_host_thread.GetNativeThread().GetSystemHandle(), &pszThreadName))) {
134 LLDB_LOGF(log, "GetThreadDescription: %ls", pszThreadName);
135 m_name.clear();
136 llvm::convertUTF16ToUTF8String(
137 llvm::ArrayRef(reinterpret_cast<char *>(pszThreadName),
138 wcslen(pszThreadName) * sizeof(wchar_t)),
139 m_name);
140 ::LocalFree(pszThreadName);
141 }
142
143 return m_name;
144}
145
147 std::string description) {
149 m_stop_info = stop_info;
150 m_stop_description = description;
151}
152
154 std::string &description) {
155 Log *log = GetLog(LLDBLog::Thread);
156
157 switch (m_state) {
158 case eStateStopped:
159 case eStateCrashed:
160 case eStateExited:
161 case eStateSuspended:
162 case eStateUnloaded:
163 stop_info = m_stop_info;
164 description = m_stop_description;
165 return true;
166
167 case eStateInvalid:
168 case eStateConnected:
169 case eStateAttaching:
170 case eStateLaunching:
171 case eStateRunning:
172 case eStateStepping:
173 case eStateDetached:
174 LLDB_LOGF(log, "tid %" PRIu64 " in state %s cannot answer stop reason",
176 return false;
177 }
178 llvm_unreachable("unhandled StateType!");
179}
180
182 uint32_t watch_flags, bool hardware) {
183 if (!hardware)
184 return Status::FromErrorString("not implemented");
186 return Status();
188 if (error.Fail())
189 return error;
190 uint32_t wp_index =
191 m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
192 if (wp_index == LLDB_INVALID_INDEX32)
193 return Status::FromErrorString("Setting hardware watchpoint failed.");
194 m_watchpoint_index_map.insert({addr, wp_index});
195 return Status();
196}
197
199 auto wp = m_watchpoint_index_map.find(addr);
200 if (wp == m_watchpoint_index_map.end())
201 return Status();
202 uint32_t wp_index = wp->second;
203 m_watchpoint_index_map.erase(wp);
204 if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
205 return Status();
206 return Status::FromErrorString("Clearing hardware watchpoint failed.");
207}
208
210 size_t size) {
211 return Status::FromErrorString("unimplemented.");
212}
213
217
219 return m_host_thread.GetNativeThread().GetExtendedInfo();
220}
static llvm::raw_ostream & error(Stream &strm)
#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:702
virtual const ArchSpec & GetArchitecture() const =0
const ArchSpec & GetArchitecture() const override
static std::unique_ptr< NativeRegisterContextWindows > CreateHostNativeRegisterContextWindows(const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
uint32_t ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num) const
lldb::addr_t ReadRegisterAsUnsigned(uint32_t reg, lldb::addr_t fail_value)
Status WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval)
lldb::addr_t GetPC(lldb::addr_t fail_value=LLDB_INVALID_ADDRESS)
NativeThreadProtocol(NativeProcessProtocol &process, lldb::tid_t tid)
StructuredData::ObjectSP GetExtendedInfo() const override
Status RemoveWatchpoint(lldb::addr_t addr) override
bool CompleteSingleStepWithoutTrap()
Called when a stop is reported.
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override
void SetStopReason(ThreadStopInfo stop_info, std::string description)
Status DoResume(lldb::StateType resume_state)
bool GetStopReason(ThreadStopInfo &stop_info, std::string &description) override
NativeRegisterContextWindows & GetRegisterContext() override
lldb::StateType GetState() override
NativeThreadWindows(NativeProcessWindows &process, const HostThread &thread)
Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size) override
std::unique_ptr< NativeRegisterContextWindows > m_reg_context_up
Status RemoveHardwareBreakpoint(lldb::addr_t addr) override
An error handling class.
Definition Status.h:118
static Status FromErrorString(const char *str)
Definition Status.h:141
std::shared_ptr< Object > ObjectSP
#define LLDB_INVALID_INDEX32
#define LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_INVALID_ADDRESS
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
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ eStateConnected
Process is connected to remote debug services, but not launched or attached to anything yet.
@ eStateDetached
Process has been detached and can't be examined.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateLaunching
Process is in the process of launching.
@ eStateAttaching
Process is currently trying to attach.
@ eStateExited
Process has exited and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
@ eErrorTypeWin32
Standard Win32 error codes.
uint64_t addr_t
Definition lldb-types.h:80
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target