1dda28197Spatrick //===-- NativeProcessWindows.cpp ------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "lldb/Host/windows/windows.h"
10061da546Spatrick #include <psapi.h>
11061da546Spatrick
12061da546Spatrick #include "NativeProcessWindows.h"
13061da546Spatrick #include "NativeThreadWindows.h"
14061da546Spatrick #include "lldb/Host/FileSystem.h"
15061da546Spatrick #include "lldb/Host/HostNativeProcessBase.h"
16061da546Spatrick #include "lldb/Host/HostProcess.h"
17061da546Spatrick #include "lldb/Host/ProcessLaunchInfo.h"
18061da546Spatrick #include "lldb/Host/windows/AutoHandle.h"
19061da546Spatrick #include "lldb/Host/windows/HostThreadWindows.h"
20061da546Spatrick #include "lldb/Host/windows/ProcessLauncherWindows.h"
21061da546Spatrick #include "lldb/Target/MemoryRegionInfo.h"
22061da546Spatrick #include "lldb/Target/Process.h"
23061da546Spatrick #include "lldb/Utility/State.h"
24061da546Spatrick #include "llvm/Support/ConvertUTF.h"
25061da546Spatrick #include "llvm/Support/Errc.h"
26061da546Spatrick #include "llvm/Support/Error.h"
27061da546Spatrick #include "llvm/Support/Format.h"
28061da546Spatrick #include "llvm/Support/Threading.h"
29061da546Spatrick #include "llvm/Support/raw_ostream.h"
30061da546Spatrick
31061da546Spatrick #include "DebuggerThread.h"
32061da546Spatrick #include "ExceptionRecord.h"
33061da546Spatrick #include "ProcessWindowsLog.h"
34061da546Spatrick
35061da546Spatrick #include <tlhelp32.h>
36061da546Spatrick
37061da546Spatrick #pragma warning(disable : 4005)
38061da546Spatrick #include "winternl.h"
39061da546Spatrick #include <ntstatus.h>
40061da546Spatrick
41061da546Spatrick using namespace lldb;
42061da546Spatrick using namespace lldb_private;
43061da546Spatrick using namespace llvm;
44061da546Spatrick
45061da546Spatrick namespace lldb_private {
46061da546Spatrick
NativeProcessWindows(ProcessLaunchInfo & launch_info,NativeDelegate & delegate,llvm::Error & E)47061da546Spatrick NativeProcessWindows::NativeProcessWindows(ProcessLaunchInfo &launch_info,
48061da546Spatrick NativeDelegate &delegate,
49061da546Spatrick llvm::Error &E)
50061da546Spatrick : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID,
51dda28197Spatrick launch_info.GetPTY().ReleasePrimaryFileDescriptor(),
52061da546Spatrick delegate),
53061da546Spatrick ProcessDebugger(), m_arch(launch_info.GetArchitecture()) {
54061da546Spatrick ErrorAsOutParameter EOut(&E);
55061da546Spatrick DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
56061da546Spatrick E = LaunchProcess(launch_info, delegate_sp).ToError();
57061da546Spatrick if (E)
58061da546Spatrick return;
59061da546Spatrick
60061da546Spatrick SetID(GetDebuggedProcessId());
61061da546Spatrick }
62061da546Spatrick
NativeProcessWindows(lldb::pid_t pid,int terminal_fd,NativeDelegate & delegate,llvm::Error & E)63061da546Spatrick NativeProcessWindows::NativeProcessWindows(lldb::pid_t pid, int terminal_fd,
64061da546Spatrick NativeDelegate &delegate,
65061da546Spatrick llvm::Error &E)
66061da546Spatrick : NativeProcessProtocol(pid, terminal_fd, delegate), ProcessDebugger() {
67061da546Spatrick ErrorAsOutParameter EOut(&E);
68061da546Spatrick DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
69061da546Spatrick ProcessAttachInfo attach_info;
70061da546Spatrick attach_info.SetProcessID(pid);
71061da546Spatrick E = AttachProcess(pid, attach_info, delegate_sp).ToError();
72061da546Spatrick if (E)
73061da546Spatrick return;
74061da546Spatrick
75061da546Spatrick SetID(GetDebuggedProcessId());
76061da546Spatrick
77061da546Spatrick ProcessInstanceInfo info;
78061da546Spatrick if (!Host::GetProcessInfo(pid, info)) {
79061da546Spatrick E = createStringError(inconvertibleErrorCode(),
80061da546Spatrick "Cannot get process information");
81061da546Spatrick return;
82061da546Spatrick }
83061da546Spatrick m_arch = info.GetArchitecture();
84061da546Spatrick }
85061da546Spatrick
Resume(const ResumeActionList & resume_actions)86061da546Spatrick Status NativeProcessWindows::Resume(const ResumeActionList &resume_actions) {
87*f6aab3d8Srobert Log *log = GetLog(WindowsLog::Process);
88061da546Spatrick Status error;
89061da546Spatrick llvm::sys::ScopedLock lock(m_mutex);
90061da546Spatrick
91061da546Spatrick StateType state = GetState();
92061da546Spatrick if (state == eStateStopped || state == eStateCrashed) {
93061da546Spatrick LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
94061da546Spatrick GetDebuggedProcessId(), state);
95061da546Spatrick LLDB_LOG(log, "resuming {0} threads.", m_threads.size());
96061da546Spatrick
97061da546Spatrick bool failed = false;
98061da546Spatrick for (uint32_t i = 0; i < m_threads.size(); ++i) {
99061da546Spatrick auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get());
100061da546Spatrick const ResumeAction *const action =
101061da546Spatrick resume_actions.GetActionForThread(thread->GetID(), true);
102061da546Spatrick if (action == nullptr)
103061da546Spatrick continue;
104061da546Spatrick
105061da546Spatrick switch (action->state) {
106061da546Spatrick case eStateRunning:
107061da546Spatrick case eStateStepping: {
108061da546Spatrick Status result = thread->DoResume(action->state);
109061da546Spatrick if (result.Fail()) {
110061da546Spatrick failed = true;
111061da546Spatrick LLDB_LOG(log,
112061da546Spatrick "Trying to resume thread at index {0}, but failed with "
113061da546Spatrick "error {1}.",
114061da546Spatrick i, result);
115061da546Spatrick }
116061da546Spatrick break;
117061da546Spatrick }
118061da546Spatrick case eStateSuspended:
119061da546Spatrick case eStateStopped:
120*f6aab3d8Srobert break;
121061da546Spatrick
122061da546Spatrick default:
123061da546Spatrick return Status(
124061da546Spatrick "NativeProcessWindows::%s (): unexpected state %s specified "
125061da546Spatrick "for pid %" PRIu64 ", tid %" PRIu64,
126061da546Spatrick __FUNCTION__, StateAsCString(action->state), GetID(),
127061da546Spatrick thread->GetID());
128061da546Spatrick }
129061da546Spatrick }
130061da546Spatrick
131061da546Spatrick if (failed) {
132061da546Spatrick error.SetErrorString("NativeProcessWindows::DoResume failed");
133061da546Spatrick } else {
134061da546Spatrick SetState(eStateRunning);
135061da546Spatrick }
136061da546Spatrick
137061da546Spatrick // Resume the debug loop.
138061da546Spatrick ExceptionRecordSP active_exception =
139061da546Spatrick m_session_data->m_debugger->GetActiveException().lock();
140061da546Spatrick if (active_exception) {
141061da546Spatrick // Resume the process and continue processing debug events. Mask the
142061da546Spatrick // exception so that from the process's view, there is no indication that
143061da546Spatrick // anything happened.
144061da546Spatrick m_session_data->m_debugger->ContinueAsyncException(
145061da546Spatrick ExceptionResult::MaskException);
146061da546Spatrick }
147061da546Spatrick } else {
148061da546Spatrick LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
149061da546Spatrick GetDebuggedProcessId(), GetState());
150061da546Spatrick }
151061da546Spatrick
152061da546Spatrick return error;
153061da546Spatrick }
154061da546Spatrick
155061da546Spatrick NativeThreadWindows *
GetThreadByID(lldb::tid_t thread_id)156061da546Spatrick NativeProcessWindows::GetThreadByID(lldb::tid_t thread_id) {
157061da546Spatrick return static_cast<NativeThreadWindows *>(
158061da546Spatrick NativeProcessProtocol::GetThreadByID(thread_id));
159061da546Spatrick }
160061da546Spatrick
Halt()161061da546Spatrick Status NativeProcessWindows::Halt() {
162061da546Spatrick bool caused_stop = false;
163061da546Spatrick StateType state = GetState();
164061da546Spatrick if (state != eStateStopped)
165061da546Spatrick return HaltProcess(caused_stop);
166061da546Spatrick return Status();
167061da546Spatrick }
168061da546Spatrick
Detach()169061da546Spatrick Status NativeProcessWindows::Detach() {
170061da546Spatrick Status error;
171*f6aab3d8Srobert Log *log = GetLog(WindowsLog::Process);
172061da546Spatrick StateType state = GetState();
173061da546Spatrick if (state != eStateExited && state != eStateDetached) {
174061da546Spatrick error = DetachProcess();
175061da546Spatrick if (error.Success())
176061da546Spatrick SetState(eStateDetached);
177061da546Spatrick else
178061da546Spatrick LLDB_LOG(log, "Detaching process error: {0}", error);
179061da546Spatrick } else {
180061da546Spatrick error.SetErrorStringWithFormatv("error: process {0} in state = {1}, but "
181061da546Spatrick "cannot detach it in this state.",
182061da546Spatrick GetID(), state);
183061da546Spatrick LLDB_LOG(log, "error: {0}", error);
184061da546Spatrick }
185061da546Spatrick return error;
186061da546Spatrick }
187061da546Spatrick
Signal(int signo)188061da546Spatrick Status NativeProcessWindows::Signal(int signo) {
189061da546Spatrick Status error;
190061da546Spatrick error.SetErrorString("Windows does not support sending signals to processes");
191061da546Spatrick return error;
192061da546Spatrick }
193061da546Spatrick
Interrupt()194061da546Spatrick Status NativeProcessWindows::Interrupt() { return Halt(); }
195061da546Spatrick
Kill()196061da546Spatrick Status NativeProcessWindows::Kill() {
197061da546Spatrick StateType state = GetState();
198061da546Spatrick return DestroyProcess(state);
199061da546Spatrick }
200061da546Spatrick
IgnoreSignals(llvm::ArrayRef<int> signals)201061da546Spatrick Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) {
202061da546Spatrick return Status();
203061da546Spatrick }
204061da546Spatrick
GetMemoryRegionInfo(lldb::addr_t load_addr,MemoryRegionInfo & range_info)205061da546Spatrick Status NativeProcessWindows::GetMemoryRegionInfo(lldb::addr_t load_addr,
206061da546Spatrick MemoryRegionInfo &range_info) {
207061da546Spatrick return ProcessDebugger::GetMemoryRegionInfo(load_addr, range_info);
208061da546Spatrick }
209061da546Spatrick
ReadMemory(lldb::addr_t addr,void * buf,size_t size,size_t & bytes_read)210061da546Spatrick Status NativeProcessWindows::ReadMemory(lldb::addr_t addr, void *buf,
211061da546Spatrick size_t size, size_t &bytes_read) {
212061da546Spatrick return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
213061da546Spatrick }
214061da546Spatrick
WriteMemory(lldb::addr_t addr,const void * buf,size_t size,size_t & bytes_written)215061da546Spatrick Status NativeProcessWindows::WriteMemory(lldb::addr_t addr, const void *buf,
216061da546Spatrick size_t size, size_t &bytes_written) {
217061da546Spatrick return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
218061da546Spatrick }
219061da546Spatrick
220be691f3bSpatrick llvm::Expected<lldb::addr_t>
AllocateMemory(size_t size,uint32_t permissions)221be691f3bSpatrick NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
222be691f3bSpatrick lldb::addr_t addr;
223be691f3bSpatrick Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
224be691f3bSpatrick if (ST.Success())
225be691f3bSpatrick return addr;
226be691f3bSpatrick return ST.ToError();
227061da546Spatrick }
228061da546Spatrick
DeallocateMemory(lldb::addr_t addr)229be691f3bSpatrick llvm::Error NativeProcessWindows::DeallocateMemory(lldb::addr_t addr) {
230be691f3bSpatrick return ProcessDebugger::DeallocateMemory(addr).ToError();
231061da546Spatrick }
232061da546Spatrick
GetSharedLibraryInfoAddress()233061da546Spatrick lldb::addr_t NativeProcessWindows::GetSharedLibraryInfoAddress() { return 0; }
234061da546Spatrick
IsAlive() const235061da546Spatrick bool NativeProcessWindows::IsAlive() const {
236061da546Spatrick StateType state = GetState();
237061da546Spatrick switch (state) {
238061da546Spatrick case eStateCrashed:
239061da546Spatrick case eStateDetached:
240061da546Spatrick case eStateExited:
241061da546Spatrick case eStateInvalid:
242061da546Spatrick case eStateUnloaded:
243061da546Spatrick return false;
244061da546Spatrick default:
245061da546Spatrick return true;
246061da546Spatrick }
247061da546Spatrick }
248061da546Spatrick
SetStopReasonForThread(NativeThreadWindows & thread,lldb::StopReason reason,std::string description)249061da546Spatrick void NativeProcessWindows::SetStopReasonForThread(NativeThreadWindows &thread,
250061da546Spatrick lldb::StopReason reason,
251061da546Spatrick std::string description) {
252061da546Spatrick SetCurrentThreadID(thread.GetID());
253061da546Spatrick
254061da546Spatrick ThreadStopInfo stop_info;
255061da546Spatrick stop_info.reason = reason;
256061da546Spatrick // No signal support on Windows but required to provide a 'valid' signum.
257*f6aab3d8Srobert stop_info.signo = SIGTRAP;
258*f6aab3d8Srobert
259061da546Spatrick if (reason == StopReason::eStopReasonException) {
260061da546Spatrick stop_info.details.exception.type = 0;
261061da546Spatrick stop_info.details.exception.data_count = 0;
262061da546Spatrick }
263061da546Spatrick
264061da546Spatrick thread.SetStopReason(stop_info, description);
265061da546Spatrick }
266061da546Spatrick
StopThread(lldb::tid_t thread_id,lldb::StopReason reason,std::string description)267061da546Spatrick void NativeProcessWindows::StopThread(lldb::tid_t thread_id,
268061da546Spatrick lldb::StopReason reason,
269061da546Spatrick std::string description) {
270061da546Spatrick NativeThreadWindows *thread = GetThreadByID(thread_id);
271061da546Spatrick if (!thread)
272061da546Spatrick return;
273061da546Spatrick
274061da546Spatrick for (uint32_t i = 0; i < m_threads.size(); ++i) {
275061da546Spatrick auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
276061da546Spatrick Status error = t->DoStop();
277061da546Spatrick if (error.Fail())
278061da546Spatrick exit(1);
279061da546Spatrick }
280061da546Spatrick SetStopReasonForThread(*thread, reason, description);
281061da546Spatrick }
282061da546Spatrick
UpdateThreads()283061da546Spatrick size_t NativeProcessWindows::UpdateThreads() { return m_threads.size(); }
284061da546Spatrick
285061da546Spatrick llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
GetAuxvData() const286061da546Spatrick NativeProcessWindows::GetAuxvData() const {
287061da546Spatrick // Not available on this target.
288061da546Spatrick return llvm::errc::not_supported;
289061da546Spatrick }
290061da546Spatrick
291*f6aab3d8Srobert llvm::Expected<llvm::ArrayRef<uint8_t>>
GetSoftwareBreakpointTrapOpcode(size_t size_hint)292*f6aab3d8Srobert NativeProcessWindows::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
293*f6aab3d8Srobert static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e, 0xd4}; // brk #0xf000
294*f6aab3d8Srobert static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
295*f6aab3d8Srobert
296*f6aab3d8Srobert switch (GetArchitecture().GetMachine()) {
297*f6aab3d8Srobert case llvm::Triple::aarch64:
298*f6aab3d8Srobert return llvm::ArrayRef(g_aarch64_opcode);
299*f6aab3d8Srobert
300*f6aab3d8Srobert case llvm::Triple::arm:
301*f6aab3d8Srobert case llvm::Triple::thumb:
302*f6aab3d8Srobert return llvm::ArrayRef(g_thumb_opcode);
303*f6aab3d8Srobert
304*f6aab3d8Srobert default:
305*f6aab3d8Srobert return NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_hint);
306*f6aab3d8Srobert }
307*f6aab3d8Srobert }
308*f6aab3d8Srobert
GetSoftwareBreakpointPCOffset()309*f6aab3d8Srobert size_t NativeProcessWindows::GetSoftwareBreakpointPCOffset() {
310*f6aab3d8Srobert // Windows always reports an incremented PC after a breakpoint is hit,
311*f6aab3d8Srobert // even on ARM.
312*f6aab3d8Srobert return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
313*f6aab3d8Srobert }
314*f6aab3d8Srobert
FindSoftwareBreakpoint(lldb::addr_t addr)315061da546Spatrick bool NativeProcessWindows::FindSoftwareBreakpoint(lldb::addr_t addr) {
316061da546Spatrick auto it = m_software_breakpoints.find(addr);
317061da546Spatrick if (it == m_software_breakpoints.end())
318061da546Spatrick return false;
319061da546Spatrick return true;
320061da546Spatrick }
321061da546Spatrick
SetBreakpoint(lldb::addr_t addr,uint32_t size,bool hardware)322061da546Spatrick Status NativeProcessWindows::SetBreakpoint(lldb::addr_t addr, uint32_t size,
323061da546Spatrick bool hardware) {
324061da546Spatrick if (hardware)
325061da546Spatrick return SetHardwareBreakpoint(addr, size);
326061da546Spatrick return SetSoftwareBreakpoint(addr, size);
327061da546Spatrick }
328061da546Spatrick
RemoveBreakpoint(lldb::addr_t addr,bool hardware)329061da546Spatrick Status NativeProcessWindows::RemoveBreakpoint(lldb::addr_t addr,
330061da546Spatrick bool hardware) {
331061da546Spatrick if (hardware)
332061da546Spatrick return RemoveHardwareBreakpoint(addr);
333061da546Spatrick return RemoveSoftwareBreakpoint(addr);
334061da546Spatrick }
335061da546Spatrick
CacheLoadedModules()336061da546Spatrick Status NativeProcessWindows::CacheLoadedModules() {
337061da546Spatrick Status error;
338061da546Spatrick if (!m_loaded_modules.empty())
339061da546Spatrick return Status();
340061da546Spatrick
341061da546Spatrick // Retrieve loaded modules by a Target/Module free implemenation.
342061da546Spatrick AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
343061da546Spatrick if (snapshot.IsValid()) {
344061da546Spatrick MODULEENTRY32W me;
345061da546Spatrick me.dwSize = sizeof(MODULEENTRY32W);
346061da546Spatrick if (Module32FirstW(snapshot.get(), &me)) {
347061da546Spatrick do {
348061da546Spatrick std::string path;
349061da546Spatrick if (!llvm::convertWideToUTF8(me.szExePath, path))
350061da546Spatrick continue;
351061da546Spatrick
352061da546Spatrick FileSpec file_spec(path);
353061da546Spatrick FileSystem::Instance().Resolve(file_spec);
354061da546Spatrick m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr;
355061da546Spatrick } while (Module32Next(snapshot.get(), &me));
356061da546Spatrick }
357061da546Spatrick
358061da546Spatrick if (!m_loaded_modules.empty())
359061da546Spatrick return Status();
360061da546Spatrick }
361061da546Spatrick
362061da546Spatrick error.SetError(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
363061da546Spatrick return error;
364061da546Spatrick }
365061da546Spatrick
GetLoadedModuleFileSpec(const char * module_path,FileSpec & file_spec)366061da546Spatrick Status NativeProcessWindows::GetLoadedModuleFileSpec(const char *module_path,
367061da546Spatrick FileSpec &file_spec) {
368061da546Spatrick Status error = CacheLoadedModules();
369061da546Spatrick if (error.Fail())
370061da546Spatrick return error;
371061da546Spatrick
372061da546Spatrick FileSpec module_file_spec(module_path);
373061da546Spatrick FileSystem::Instance().Resolve(module_file_spec);
374061da546Spatrick for (auto &it : m_loaded_modules) {
375061da546Spatrick if (it.first == module_file_spec) {
376061da546Spatrick file_spec = it.first;
377061da546Spatrick return Status();
378061da546Spatrick }
379061da546Spatrick }
380061da546Spatrick return Status("Module (%s) not found in process %" PRIu64 "!",
381*f6aab3d8Srobert module_file_spec.GetPath().c_str(), GetID());
382061da546Spatrick }
383061da546Spatrick
384061da546Spatrick Status
GetFileLoadAddress(const llvm::StringRef & file_name,lldb::addr_t & load_addr)385061da546Spatrick NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
386061da546Spatrick lldb::addr_t &load_addr) {
387061da546Spatrick Status error = CacheLoadedModules();
388061da546Spatrick if (error.Fail())
389061da546Spatrick return error;
390061da546Spatrick
391061da546Spatrick load_addr = LLDB_INVALID_ADDRESS;
392061da546Spatrick FileSpec file_spec(file_name);
393061da546Spatrick FileSystem::Instance().Resolve(file_spec);
394061da546Spatrick for (auto &it : m_loaded_modules) {
395061da546Spatrick if (it.first == file_spec) {
396061da546Spatrick load_addr = it.second;
397061da546Spatrick return Status();
398061da546Spatrick }
399061da546Spatrick }
400061da546Spatrick return Status("Can't get loaded address of file (%s) in process %" PRIu64 "!",
401*f6aab3d8Srobert file_spec.GetPath().c_str(), GetID());
402061da546Spatrick }
403061da546Spatrick
OnExitProcess(uint32_t exit_code)404061da546Spatrick void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
405*f6aab3d8Srobert Log *log = GetLog(WindowsLog::Process);
406061da546Spatrick LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
407061da546Spatrick
408061da546Spatrick ProcessDebugger::OnExitProcess(exit_code);
409061da546Spatrick
410061da546Spatrick // No signal involved. It is just an exit event.
411061da546Spatrick WaitStatus wait_status(WaitStatus::Exit, exit_code);
412061da546Spatrick SetExitStatus(wait_status, true);
413061da546Spatrick
414061da546Spatrick // Notify the native delegate.
415061da546Spatrick SetState(eStateExited, true);
416061da546Spatrick }
417061da546Spatrick
OnDebuggerConnected(lldb::addr_t image_base)418061da546Spatrick void NativeProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
419*f6aab3d8Srobert Log *log = GetLog(WindowsLog::Process);
420061da546Spatrick LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
421061da546Spatrick GetDebuggedProcessId(), image_base);
422061da546Spatrick
423061da546Spatrick // This is the earliest chance we can resolve the process ID and
424dda28197Spatrick // architecture if we don't know them yet.
425061da546Spatrick if (GetID() == LLDB_INVALID_PROCESS_ID)
426061da546Spatrick SetID(GetDebuggedProcessId());
427061da546Spatrick
428061da546Spatrick if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
429061da546Spatrick ProcessInstanceInfo process_info;
430061da546Spatrick if (!Host::GetProcessInfo(GetDebuggedProcessId(), process_info)) {
431061da546Spatrick LLDB_LOG(log, "Cannot get process information during debugger connecting "
432061da546Spatrick "to process");
433061da546Spatrick return;
434061da546Spatrick }
435061da546Spatrick SetArchitecture(process_info.GetArchitecture());
436061da546Spatrick }
437061da546Spatrick
438061da546Spatrick // The very first one shall always be the main thread.
439061da546Spatrick assert(m_threads.empty());
440061da546Spatrick m_threads.push_back(std::make_unique<NativeThreadWindows>(
441061da546Spatrick *this, m_session_data->m_debugger->GetMainThread()));
442061da546Spatrick }
443061da546Spatrick
444061da546Spatrick ExceptionResult
OnDebugException(bool first_chance,const ExceptionRecord & record)445061da546Spatrick NativeProcessWindows::OnDebugException(bool first_chance,
446061da546Spatrick const ExceptionRecord &record) {
447*f6aab3d8Srobert Log *log = GetLog(WindowsLog::Exception);
448061da546Spatrick llvm::sys::ScopedLock lock(m_mutex);
449061da546Spatrick
450061da546Spatrick // Let the debugger establish the internal status.
451061da546Spatrick ProcessDebugger::OnDebugException(first_chance, record);
452061da546Spatrick
453061da546Spatrick static bool initial_stop = false;
454061da546Spatrick if (!first_chance) {
455061da546Spatrick SetState(eStateStopped, false);
456061da546Spatrick }
457061da546Spatrick
458061da546Spatrick ExceptionResult result = ExceptionResult::SendToApplication;
459061da546Spatrick switch (record.GetExceptionCode()) {
460061da546Spatrick case DWORD(STATUS_SINGLE_STEP):
461061da546Spatrick case STATUS_WX86_SINGLE_STEP: {
462061da546Spatrick uint32_t wp_id = LLDB_INVALID_INDEX32;
463061da546Spatrick if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
464061da546Spatrick NativeRegisterContextWindows ®_ctx = thread->GetRegisterContext();
465061da546Spatrick Status error =
466061da546Spatrick reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
467061da546Spatrick if (error.Fail())
468061da546Spatrick LLDB_LOG(log,
469061da546Spatrick "received error while checking for watchpoint hits, pid = "
470061da546Spatrick "{0}, error = {1}",
471061da546Spatrick thread->GetID(), error);
472061da546Spatrick if (wp_id != LLDB_INVALID_INDEX32) {
473061da546Spatrick addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
474061da546Spatrick addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
475061da546Spatrick std::string desc =
476061da546Spatrick formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
477061da546Spatrick StopThread(record.GetThreadID(), StopReason::eStopReasonWatchpoint,
478061da546Spatrick desc);
479061da546Spatrick }
480061da546Spatrick }
481061da546Spatrick if (wp_id == LLDB_INVALID_INDEX32)
482061da546Spatrick StopThread(record.GetThreadID(), StopReason::eStopReasonTrace);
483061da546Spatrick
484061da546Spatrick SetState(eStateStopped, true);
485061da546Spatrick
486061da546Spatrick // Continue the debugger.
487061da546Spatrick return ExceptionResult::MaskException;
488061da546Spatrick }
489061da546Spatrick case DWORD(STATUS_BREAKPOINT):
490061da546Spatrick case STATUS_WX86_BREAKPOINT:
491061da546Spatrick if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
492061da546Spatrick LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
493061da546Spatrick record.GetExceptionAddress());
494061da546Spatrick
495061da546Spatrick StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
496061da546Spatrick
497061da546Spatrick if (NativeThreadWindows *stop_thread =
498061da546Spatrick GetThreadByID(record.GetThreadID())) {
499061da546Spatrick auto ®ister_context = stop_thread->GetRegisterContext();
500*f6aab3d8Srobert uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
501*f6aab3d8Srobert // The current PC is AFTER the BP opcode, on all architectures.
502*f6aab3d8Srobert uint64_t pc = register_context.GetPC() - breakpoint_size;
503061da546Spatrick register_context.SetPC(pc);
504061da546Spatrick }
505061da546Spatrick
506061da546Spatrick SetState(eStateStopped, true);
507061da546Spatrick return ExceptionResult::MaskException;
508061da546Spatrick }
509061da546Spatrick
510061da546Spatrick if (!initial_stop) {
511061da546Spatrick initial_stop = true;
512061da546Spatrick LLDB_LOG(log,
513061da546Spatrick "Hit loader breakpoint at address {0:x}, setting initial stop "
514061da546Spatrick "event.",
515061da546Spatrick record.GetExceptionAddress());
516061da546Spatrick
517061da546Spatrick // We are required to report the reason for the first stop after
518061da546Spatrick // launching or being attached.
519061da546Spatrick if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID()))
520061da546Spatrick SetStopReasonForThread(*thread, StopReason::eStopReasonBreakpoint);
521061da546Spatrick
522061da546Spatrick // Do not notify the native delegate (e.g. llgs) since at this moment
523061da546Spatrick // the program hasn't returned from Factory::Launch() and the delegate
524061da546Spatrick // might not have an valid native process to operate on.
525061da546Spatrick SetState(eStateStopped, false);
526061da546Spatrick
527061da546Spatrick // Hit the initial stop. Continue the application.
528061da546Spatrick return ExceptionResult::BreakInDebugger;
529061da546Spatrick }
530061da546Spatrick
531*f6aab3d8Srobert [[fallthrough]];
532061da546Spatrick default:
533061da546Spatrick LLDB_LOG(log,
534061da546Spatrick "Debugger thread reported exception {0:x} at address {1:x} "
535061da546Spatrick "(first_chance={2})",
536061da546Spatrick record.GetExceptionCode(), record.GetExceptionAddress(),
537061da546Spatrick first_chance);
538061da546Spatrick
539061da546Spatrick {
540061da546Spatrick std::string desc;
541061da546Spatrick llvm::raw_string_ostream desc_stream(desc);
542061da546Spatrick desc_stream << "Exception "
543061da546Spatrick << llvm::format_hex(record.GetExceptionCode(), 8)
544061da546Spatrick << " encountered at address "
545061da546Spatrick << llvm::format_hex(record.GetExceptionAddress(), 8);
546061da546Spatrick StopThread(record.GetThreadID(), StopReason::eStopReasonException,
547061da546Spatrick desc_stream.str().c_str());
548061da546Spatrick
549061da546Spatrick SetState(eStateStopped, true);
550061da546Spatrick }
551061da546Spatrick
552061da546Spatrick // For non-breakpoints, give the application a chance to handle the
553061da546Spatrick // exception first.
554061da546Spatrick if (first_chance)
555061da546Spatrick result = ExceptionResult::SendToApplication;
556061da546Spatrick else
557061da546Spatrick result = ExceptionResult::BreakInDebugger;
558061da546Spatrick }
559061da546Spatrick
560061da546Spatrick return result;
561061da546Spatrick }
562061da546Spatrick
OnCreateThread(const HostThread & new_thread)563061da546Spatrick void NativeProcessWindows::OnCreateThread(const HostThread &new_thread) {
564061da546Spatrick llvm::sys::ScopedLock lock(m_mutex);
565061da546Spatrick
566061da546Spatrick auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
567061da546Spatrick thread->GetRegisterContext().ClearAllHardwareWatchpoints();
568061da546Spatrick for (const auto &pair : GetWatchpointMap()) {
569061da546Spatrick const NativeWatchpoint &wp = pair.second;
570061da546Spatrick thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
571061da546Spatrick wp.m_hardware);
572061da546Spatrick }
573061da546Spatrick
574061da546Spatrick m_threads.push_back(std::move(thread));
575061da546Spatrick }
576061da546Spatrick
OnExitThread(lldb::tid_t thread_id,uint32_t exit_code)577061da546Spatrick void NativeProcessWindows::OnExitThread(lldb::tid_t thread_id,
578061da546Spatrick uint32_t exit_code) {
579061da546Spatrick llvm::sys::ScopedLock lock(m_mutex);
580061da546Spatrick NativeThreadWindows *thread = GetThreadByID(thread_id);
581061da546Spatrick if (!thread)
582061da546Spatrick return;
583061da546Spatrick
584061da546Spatrick for (auto t = m_threads.begin(); t != m_threads.end();) {
585061da546Spatrick if ((*t)->GetID() == thread_id) {
586061da546Spatrick t = m_threads.erase(t);
587061da546Spatrick } else {
588061da546Spatrick ++t;
589061da546Spatrick }
590061da546Spatrick }
591061da546Spatrick }
592061da546Spatrick
OnLoadDll(const ModuleSpec & module_spec,lldb::addr_t module_addr)593061da546Spatrick void NativeProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
594061da546Spatrick lldb::addr_t module_addr) {
595061da546Spatrick // Simply invalidate the cached loaded modules.
596061da546Spatrick if (!m_loaded_modules.empty())
597061da546Spatrick m_loaded_modules.clear();
598061da546Spatrick }
599061da546Spatrick
OnUnloadDll(lldb::addr_t module_addr)600061da546Spatrick void NativeProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
601061da546Spatrick if (!m_loaded_modules.empty())
602061da546Spatrick m_loaded_modules.clear();
603061da546Spatrick }
604061da546Spatrick
605061da546Spatrick llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
Launch(ProcessLaunchInfo & launch_info,NativeProcessProtocol::NativeDelegate & native_delegate,MainLoop & mainloop) const606061da546Spatrick NativeProcessWindows::Factory::Launch(
607061da546Spatrick ProcessLaunchInfo &launch_info,
608061da546Spatrick NativeProcessProtocol::NativeDelegate &native_delegate,
609061da546Spatrick MainLoop &mainloop) const {
610061da546Spatrick Error E = Error::success();
611061da546Spatrick auto process_up = std::unique_ptr<NativeProcessWindows>(
612061da546Spatrick new NativeProcessWindows(launch_info, native_delegate, E));
613061da546Spatrick if (E)
614061da546Spatrick return std::move(E);
615061da546Spatrick return std::move(process_up);
616061da546Spatrick }
617061da546Spatrick
618061da546Spatrick llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
Attach(lldb::pid_t pid,NativeProcessProtocol::NativeDelegate & native_delegate,MainLoop & mainloop) const619061da546Spatrick NativeProcessWindows::Factory::Attach(
620061da546Spatrick lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
621061da546Spatrick MainLoop &mainloop) const {
622061da546Spatrick Error E = Error::success();
623*f6aab3d8Srobert // Set pty primary fd invalid since it is not available.
624061da546Spatrick auto process_up = std::unique_ptr<NativeProcessWindows>(
625061da546Spatrick new NativeProcessWindows(pid, -1, native_delegate, E));
626061da546Spatrick if (E)
627061da546Spatrick return std::move(E);
628061da546Spatrick return std::move(process_up);
629061da546Spatrick }
630061da546Spatrick } // namespace lldb_private
631