LLDB mainline
NativeProcessWindows.cpp
Go to the documentation of this file.
1//===-- NativeProcessWindows.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
10#include <dbghelp.h>
11#include <excpt.h>
12#include <pathcch.h>
13#include <psapi.h>
14
16#include "NativeThreadWindows.h"
29#include "lldb/Target/Process.h"
31#include "lldb/Utility/State.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/Support/ConvertUTF.h"
35#include "llvm/Support/Errc.h"
36#include "llvm/Support/Error.h"
37#include "llvm/Support/Format.h"
38#include "llvm/Support/Threading.h"
39#include "llvm/Support/raw_ostream.h"
40
41#include "DebuggerThread.h"
42#include "ExceptionRecord.h"
43#include "ProcessWindowsLog.h"
44
45#include <tlhelp32.h>
46
47#pragma warning(disable : 4005)
48#include "winternl.h"
49#include <ntstatus.h>
50
51using namespace lldb;
52using namespace lldb_private;
53using namespace llvm;
54
55namespace lldb_private {
56
58 NativeDelegate &delegate,
59 llvm::Error &E)
62 PseudoTerminal::invalid_fd, // NativeProcessWindows owns the ConPTY.
63 delegate),
64 ProcessDebugger(), m_arch(launch_info.GetArchitecture()),
65 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
66 ErrorAsOutParameter EOut(&E);
67 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
68 E = LaunchProcess(launch_info, delegate_sp).ToError();
69 if (E)
70 return;
71
73
74 m_pty = launch_info.TakePTY();
76}
77
79 NativeDelegate &delegate,
80 llvm::Error &E)
81 : NativeProcessProtocol(pid, terminal_fd, delegate), ProcessDebugger(),
82 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
83 ErrorAsOutParameter EOut(&E);
84 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
85 ProcessAttachInfo attach_info;
86 attach_info.SetProcessID(pid);
87 E = AttachProcess(pid, attach_info, delegate_sp).ToError();
88 if (E)
89 return;
90
92
94
96 if (!Host::GetProcessInfo(pid, info)) {
97 E = createStringError(inconvertibleErrorCode(),
98 "Cannot get process information");
99 return;
100 }
101 m_arch = info.GetArchitecture();
102}
103
107 llvm::sys::ScopedLock lock(m_mutex);
108
109 StateType state = GetState();
110 if (state == eStateStopped || state == eStateCrashed) {
111 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
112 GetDebuggedProcessId(), state);
113 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
114 LLDB_LOG(log, "resuming {0} threads.", m_threads.size());
115
117
118 bool failed = false;
119 for (uint32_t i = 0; i < m_threads.size(); ++i) {
120 auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get());
121 thread->ClearSingleStepping();
122 const ResumeAction *const action =
123 resume_actions.GetActionForThread(thread->GetID(), true);
124 if (action == nullptr)
125 continue;
126
127 switch (action->state) {
128 case eStateRunning:
129 case eStateStepping: {
130 Status result = thread->DoResume(action->state);
131 if (result.Fail()) {
132 failed = true;
133 LLDB_LOG(log,
134 "Trying to resume thread at index {0}, but failed with "
135 "error {1}.",
136 i, result);
137 }
138 break;
139 }
140 case eStateSuspended:
141 case eStateStopped:
142 break;
143
144 default:
146 "NativeProcessWindows::%s (): unexpected state %s specified "
147 "for pid %" PRIu64 ", tid %" PRIu64,
148 __FUNCTION__, StateAsCString(action->state), GetID(),
149 thread->GetID());
150 }
151 }
152
153 if (failed) {
154 error = Status::FromErrorString("NativeProcessWindows::DoResume failed");
155 } else {
157 }
158
159 // Resume the debug loop.
160 ExceptionRecordSP active_exception =
161 m_session_data->m_debugger->GetActiveException();
162 if (active_exception) {
163 // Resume the process and continue processing debug events. Mask the
164 // exception so that from the process's view, there is no indication that
165 // anything happened.
166 m_session_data->m_debugger->ContinueAsyncException(
168 } else {
169 m_session_data->m_debugger->ContinueAsyncDllEvent();
170 }
171 } else {
172 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
174 }
175
176 return error;
177}
178
184
186 bool caused_stop = false;
187 StateType state = GetState();
188 if (state != eStateStopped) {
189 m_pending_halt = true;
190 Status err = HaltProcess(caused_stop);
191 if (err.Fail() || !caused_stop)
192 m_pending_halt = false;
193 return err;
194 }
195 return Status();
196}
197
201 StateType state = GetState();
202 if (state != eStateExited && state != eStateDetached) {
204 if (error.Success())
206 else
207 LLDB_LOG(log, "Detaching process error: {0}", error);
208 } else {
210 "error: process {0} in state = {1}, but "
211 "cannot detach it in this state.",
212 GetID(), state);
213 LLDB_LOG(log, "error: {0}", error);
214 }
215 return error;
216}
217
221 "Windows does not support sending signals to processes");
222 return error;
223}
224
226
228 StateType state = GetState();
229 return DestroyProcess(state);
230}
231
232Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) {
233 return Status();
234}
235
240
242 void *buf, size_t size,
243 size_t &bytes_read) {
244 lldb::addr_t addr = process_addr.GetValue();
245 return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
246}
247
249 size_t size, size_t &bytes_written) {
250 return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
251}
252
253llvm::Expected<lldb::addr_t>
254NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
255 lldb::addr_t addr;
256 Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
257 if (ST.Success())
258 return addr;
259 return ST.ToError();
260}
261
265
267
269 StateType state = GetState();
270 switch (state) {
271 case eStateCrashed:
272 case eStateDetached:
273 case eStateExited:
274 case eStateInvalid:
275 case eStateUnloaded:
276 return false;
277 default:
278 return true;
279 }
280}
281
283 lldb::StopReason reason,
284 std::string description) {
285 SetCurrentThreadID(thread.GetID());
286
287 ThreadStopInfo stop_info;
288 stop_info.reason = reason;
289 // No signal support on Windows but required to provide a 'valid' signum.
290 stop_info.signo = SIGTRAP;
291
292 if (reason == StopReason::eStopReasonException) {
293 stop_info.details.exception.type = 0;
294 stop_info.details.exception.data_count = 0;
295 }
296
297 thread.SetStopReason(stop_info, description);
298}
299
301 lldb::StopReason reason,
302 std::string description) {
303 NativeThreadWindows *thread = GetThreadByID(thread_id);
304 if (!thread)
305 return;
306
308 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
309 for (uint32_t i = 0; i < m_threads.size(); ++i) {
310 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
311 if (Status error = t->DoStop(); error.Fail())
312 LLDB_LOG(log, "failed to stop thread {0}: {1}", t->GetID(), error);
313 }
314 SetStopReasonForThread(*thread, reason, description);
315}
316
318 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
319 return m_threads.size();
320}
321
322llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
324 // Not available on this target.
325 return llvm::errc::not_supported;
326}
327
328llvm::Expected<llvm::ArrayRef<uint8_t>>
330 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e,
331 0xd4}; // brk #0xf000
332 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
333
334 switch (GetArchitecture().GetMachine()) {
335 case llvm::Triple::aarch64:
336 return llvm::ArrayRef(g_aarch64_opcode);
337
338 case llvm::Triple::arm:
339 case llvm::Triple::thumb:
340 return llvm::ArrayRef(g_thumb_opcode);
341
342 default:
344 }
345}
346
348 // Windows always reports an incremented PC after a breakpoint is hit,
349 // even on ARM.
350 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
351}
352
356
358 bool hardware) {
359 if (hardware)
360 return SetHardwareBreakpoint(addr, size);
361 return SetSoftwareBreakpoint(addr, size);
362}
363
365 bool hardware) {
366 if (hardware)
367 return RemoveHardwareBreakpoint(addr);
368 return RemoveSoftwareBreakpoint(addr);
369}
370
371// Get the path of a module loaded in the target process, as the loader recorded
372// it.
373//
374// Keep the loader's spelling.
375static bool GetLoadedModulePath(HANDLE process, HMODULE module,
376 std::string &path) {
377 std::vector<wchar_t> name(MAX_PATH);
378 DWORD len = 0;
379 while (true) {
380 len = ::GetModuleFileNameExW(process, module, name.data(),
381 static_cast<DWORD>(name.size()));
382 if (len == 0)
383 return false;
384 if (len < name.size())
385 break;
386 if (name.size() >= PATHCCH_MAX_CCH)
387 return false;
388 name.resize(name.size() * 2);
389 }
390
391 std::wstring wpath(name.data(), len);
392 if (!llvm::convertWideToUTF8(wpath, path))
393 return false;
394 path = StripExtendedLengthPrefix(path);
395
396 // The loader's path often differs from the on-disk one only in case (e.g.
397 // C:\windows\System32\KERNEL32.DLL). Open the image file to get its on-disk
398 // spelling, and use it if that's the only difference.
399 AutoHandle file(::CreateFileW(
400 wpath.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
401 nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
402
403 if (!file.IsValid())
404 return true;
405
406 // Unlike GetModuleFileNameExW, GetFinalPathNameByHandleW reports the buffer
407 // size it needs instead of truncating, so start empty and let the first call
408 // size the buffer rather than guessing.
409 std::vector<wchar_t> full;
410 while (true) {
411 DWORD needed = ::GetFinalPathNameByHandleW(
412 file.get(), full.data(), static_cast<DWORD>(full.size()),
413 FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
414 if (needed == 0)
415 break;
416 if (needed < full.size()) {
417 std::string canonical;
418 if (!llvm::convertWideToUTF8(std::wstring_view(full.data(), needed),
419 canonical))
420 break;
421 // GetFinalPathNameByHandleW returns an extended-length ("\\?\") path.
422 canonical = StripExtendedLengthPrefix(canonical);
423 if (llvm::StringRef(canonical).equals_insensitive(path))
424 path = std::move(canonical);
425 break;
426 }
427 full.resize(needed);
428 }
429
430 return true;
431}
432
435 if (!m_loaded_modules.IsEmpty())
436 return Status();
437
438 AutoHandle process(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
439 FALSE, GetID()),
440 nullptr);
441 if (!process.IsValid())
442 return Status(::GetLastError(), eErrorTypeWin32);
443
444 AutoHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
445 if (!snapshot.IsValid())
446 return Status(::GetLastError(), eErrorTypeWin32);
447
448 MODULEENTRY32W me;
449 me.dwSize = sizeof(MODULEENTRY32W);
450 if (::Module32FirstW(snapshot.get(), &me)) {
451 do {
452 std::string path;
453 if (!GetLoadedModulePath(process.get(), me.hModule, path))
454 continue;
455
456 FileSpec file_spec(path);
457 FileSystem::Instance().Resolve(file_spec);
458 m_loaded_modules.Add(file_spec, reinterpret_cast<addr_t>(me.modBaseAddr));
459 } while (::Module32NextW(snapshot.get(), &me));
460 }
461
462 if (!m_loaded_modules.IsEmpty())
463 return Status();
464
465 error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
466 return error;
467}
468
470 FileSpec &file_spec) {
472 if (error.Fail())
473 return error;
474
475 FileSpec module_file_spec(module_path);
476 FileSystem::Instance().Resolve(module_file_spec);
477 if (const FileSpec *found = m_loaded_modules.FindFile(module_file_spec)) {
478 file_spec = *found;
479 return Status();
480 }
482 "Module (%s) not found in process %" PRIu64 "!",
483 module_file_spec.GetPath().c_str(), GetID());
484}
485
486Status
487NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
488 lldb::addr_t &load_addr) {
490 if (error.Fail())
491 return error;
492
493 load_addr = LLDB_INVALID_ADDRESS;
494 FileSpec file_spec(file_name);
495 FileSystem::Instance().Resolve(file_spec);
496 if (std::optional<addr_t> base = m_loaded_modules.GetBaseAddress(file_spec)) {
497 load_addr = *base;
498 return Status();
499 }
501 "Can't get loaded address of file (%s) in process %" PRIu64 "!",
502 file_spec.GetPath().c_str(), GetID());
503}
504
505llvm::Expected<std::vector<LoadedLibraryInfo>>
507 if (Status error = CacheLoadedModules(); error.Fail())
508 return error.ToError();
509
510 std::vector<LoadedLibraryInfo> libs;
511 libs.reserve(m_loaded_modules.GetSize());
512 for (const auto &[file_spec, base_addrs] : m_loaded_modules) {
514 info.name = file_spec.GetPath();
515 info.base_addr = base_addrs.front();
516 libs.push_back(std::move(info));
517 }
518 return libs;
519}
520
524
525void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
527 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
528
529 // Closing the ConPTY signals EOF on the parent-side STDOUT pipe so the
530 // read thread can exit. Tear it down before the debuggee is destroyed.
532
533 bool started = m_session_data && m_session_data->m_initial_stop_received;
535
536 // No signal involved. It is just an exit event.
537 WaitStatus wait_status(WaitStatus::Exit, exit_code);
538 SetExitStatus(wait_status, started);
539
540 // Notify the native delegate.
541 SetState(eStateExited, started);
542}
543
546 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
547 GetDebuggedProcessId(), image_base);
548
549 // This is the earliest chance we can resolve the process ID and
550 // architecture if we don't know them yet.
553
555 bool got_info = Host::GetProcessInfo(GetDebuggedProcessId(), info);
556
557 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
558 if (!got_info) {
559 LLDB_LOG(log, "Cannot get process information during debugger connecting "
560 "to process");
561 return;
562 }
564 }
565
566 if (got_info) {
567 FileSpec exe = info.GetExecutableFile();
568 if (const std::string &image_path =
569 m_session_data->m_debugger->GetImagePath();
570 !image_path.empty() &&
571 !llvm::StringRef(image_path).equals_insensitive(exe.GetPath()))
572 exe = FileSpec(image_path);
573 if (exe) {
575 m_loaded_modules.Add(exe, image_base);
576 }
577 }
578
579 // The very first one shall always be the main thread.
580 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
581 assert(m_threads.empty());
582 m_threads.push_back(std::make_unique<NativeThreadWindows>(
583 *this, m_session_data->m_debugger->GetMainThread()));
584}
585
587 const ExceptionRecord &record) {
589 return false;
591 if (!thread)
592 return false;
593 const lldb::addr_t trap_addr = record.GetExceptionAddress();
594 llvm::ArrayRef<uint8_t> trap_opcode =
596 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
597 if (reg_ctx.GetPC() != trap_addr + trap_opcode.size())
598 return false;
599 llvm::SmallVector<uint8_t, 4> bytes(trap_opcode.size(), 0);
600 size_t bytes_read = 0;
601 if (ProcessDebugger::ReadMemory(trap_addr, bytes.data(), bytes.size(),
602 bytes_read)
603 .Fail() ||
604 bytes_read != bytes.size() ||
605 llvm::ArrayRef<uint8_t>(bytes) == trap_opcode)
606 return false;
608 "Trap at {0:x} on thread {1:x} is from a removed breakpoint, "
609 "rewinding the thread onto the original instruction.",
610 trap_addr, thread->GetID());
611 return reg_ctx.SetPC(trap_addr).Success();
612}
613
616 uint32_t wp_id = LLDB_INVALID_INDEX32;
617#ifndef __aarch64__
619 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
620 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
621 Status error =
622 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
623 if (error.Fail())
624 LLDB_LOG(log,
625 "received error while checking for watchpoint hits, pid = "
626 "{0}, error = {1}",
627 thread->GetID(), error);
628 if (wp_id != LLDB_INVALID_INDEX32) {
629 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
630 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
631 std::string desc =
632 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
634 }
635 }
636#endif
637 if (wp_id == LLDB_INVALID_INDEX32) {
639 if (thread && !thread->IsSingleStepping()) {
641 "ignoring a late single-step trap on thread {0:x}, which this "
642 "resume did not step",
643 record.GetThreadID());
645 }
647 }
648
649 SetState(eStateStopped, true);
651}
652
656 const auto exception_addr = record.GetExceptionAddress();
657 const auto thread_id = record.GetThreadID();
658
659 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
660 auto &reg_ctx = stop_thread->GetRegisterContext();
661
662 if (FindSoftwareBreakpoint(exception_addr)) {
663 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
664 exception_addr);
666 // The current PC is AFTER the BP opcode, on all architectures.
667 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
668 SetState(eStateStopped, true);
670 }
671
672 // This block of code will only be entered in case of a hardware
673 // watchpoint or breakpoint hit on AArch64. However, we only handle
674 // hardware watchpoints below as breakpoints are not yet supported.
675 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
676 // Check that the ExceptionInformation array of EXCEPTION_RECORD
677 // contains at least two elements: the first is a read-write flag
678 // indicating the type of data access operation (read or write) while
679 // the second contains the virtual address of the accessed data.
680 if (args.size() >= 2) {
681 uint32_t hw_id = LLDB_INVALID_INDEX32;
682 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
683 if (error.Fail())
684 LLDB_LOG(log,
685 "received error while checking for watchpoint hits, pid = "
686 "{0}, error = {1}",
687 thread_id, error);
688
689 if (hw_id != LLDB_INVALID_INDEX32) {
690 std::string desc =
691 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
692 exception_addr)
693 .str();
695 SetState(eStateStopped, true);
697 }
698 }
699
702 }
703
704 if (!m_initial_stop_seen) {
705 m_initial_stop_seen = true;
706 LLDB_LOG(log,
707 "Hit loader breakpoint at address {0:x}, setting initial stop "
708 "event.",
709 exception_addr);
710
711 // We are required to report the reason for the first stop after
712 // launching or being attached.
713 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
715
716 // Do not notify the native delegate (e.g. llgs) since at this moment
717 // the program hasn't returned from Manager::Launch() and the delegate
718 // might not have an valid native process to operate on.
719 SetState(eStateStopped, false);
720
721 // Hit the initial stop. Continue the application.
723 }
724
725 // Our own DebugBreakProcess() injection, used to implement
726 // Halt()/Interrupt().
727 if (m_pending_halt) {
728 LLDB_LOG(log,
729 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
730 "{0:x}",
731 thread_id);
732 m_pending_halt = false;
733 ThreadStopInfo signal_info;
735 signal_info.signo =
736 UnixSignals::CreateForHost()->GetSignalNumberFromName("SIGSTOP");
737
738 // Halt all threads at the kernel level.
739 {
740 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
741 for (uint32_t i = 0; i < m_threads.size(); ++i) {
742 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
743 if (Status err = t->DoStop(); err.Fail()) {
744 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
745 err.GetError());
746 exit(1);
747 }
748 }
749 }
750 SetCurrentThreadID(thread_id);
751 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
752 injected->SetStopReason(signal_info, "interrupt");
753 SetState(eStateStopped, true);
755 }
756
757 if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
759 LLDB_LOG(log,
760 "Skipping expected loader breakpoint at address {0:x} in a "
761 "system module.",
762 exception_addr);
764 }
765
766 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
767 record.GetExceptionValue(), exception_addr)
768 .str();
769 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
770 SetState(eStateStopped, true);
772}
773
776 const ExceptionRecord &record) {
778 LLDB_LOG(log,
779 "Debugger thread reported exception {0:x} at address {1:x} "
780 "(first_chance={2})",
781 record.GetExceptionValue(), record.GetExceptionAddress(),
782 first_chance);
783
784 if (first_chance)
786
787 std::string desc;
788 llvm::raw_string_ostream desc_stream(desc);
789 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
790 << " encountered at address "
791 << llvm::format_hex(record.GetExceptionAddress(), 8);
792 record.Dump(desc_stream);
794 std::move(desc));
795
796 SetState(eStateStopped, true);
798}
799
802 const ExceptionRecord &record) {
803 llvm::sys::ScopedLock lock(m_mutex);
804
805 // Handle the exception first to keep track of the stop reason.
806 ExceptionResult result;
807 switch (record.GetExceptionValue()) {
808 case DWORD(STATUS_SINGLE_STEP):
809 case STATUS_WX86_SINGLE_STEP:
810 result = HandleSingleStepException(record);
811 break;
812 case DWORD(STATUS_BREAKPOINT):
814 result = HandleBreakpointException(record);
815 break;
816 default:
817 result = HandleGenericException(first_chance, record);
818 break;
819 }
820
821 // Let the debugger establish the internal status.
822 ProcessDebugger::OnDebugException(first_chance, record);
823
824 return result;
825}
826
828 llvm::sys::ScopedLock lock(m_mutex);
829
830 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
831 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
832 for (const auto &pair : GetWatchpointMap()) {
833 const NativeWatchpoint &wp = pair.second;
834 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
835 wp.m_hardware);
836 }
837
838 if (StateType state = GetState();
839 state == eStateStopped || state == eStateCrashed) {
840 if (Status error = thread->DoStop(); error.Fail()) {
842 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
843 thread->GetID(), error);
844 }
845 ThreadStopInfo stop_info;
846 stop_info.reason = lldb::eStopReasonNone;
847 thread->SetStopReason(stop_info, "");
848 }
849
850 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
851 m_threads.push_back(std::move(thread));
852}
853
855 uint32_t exit_code) {
856 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
857 llvm::erase_if(m_threads, [thread_id](const auto &t) {
858 return t->GetID() == thread_id;
859 });
860}
861
863 lldb::addr_t module_addr,
864 lldb::tid_t thread_id) {
866 llvm::sys::ScopedLock lock(m_mutex);
867
868 FileSpec resolved = module_spec.GetFileSpec();
869 if (resolved) {
870 FileSystem::Instance().Resolve(resolved);
871 m_loaded_modules.Add(resolved, module_addr);
872 }
874
877
878 // Can't resolve a breakpoint in a system DLL.
879 if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
881
882 {
883 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
884 NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
885 if (!loader_thread && !m_threads.empty()) {
886 LLDB_LOG(log,
887 "LOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
888 thread_id);
889 loader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
890 }
891 if (loader_thread) {
892 SetCurrentThreadID(loader_thread->GetID());
893 if (loader_thread->DoStop().Fail())
894 LLDB_LOG(log, "Failed to suspend thread {0} on LOAD_DLL.",
895 loader_thread->GetID());
896 ThreadStopInfo info;
898 info.signo = 0;
899 loader_thread->SetStopReason(info, "");
900 }
901 }
902 SetState(eStateStopped, true);
903
905}
906
908 lldb::tid_t thread_id) {
910 llvm::sys::ScopedLock lock(m_mutex);
911
912 FileSpec unloaded_spec = m_loaded_modules.Remove(module_addr);
914
917
918 if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
920
921 {
922 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
923 NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
924 if (!unloader_thread && !m_threads.empty()) {
925 LLDB_LOG(log,
926 "UNLOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
927 thread_id);
928 unloader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
929 }
930 if (unloader_thread) {
931 SetCurrentThreadID(unloader_thread->GetID());
932 if (unloader_thread->DoStop().Fail())
933 LLDB_LOG(log, "Failed to suspend thread {0} on UNLOAD_DLL.",
934 unloader_thread->GetID());
935 ThreadStopInfo info;
937 info.signo = 0;
938 unloader_thread->SetStopReason(info, "");
939 }
940 }
941 SetState(eStateStopped, true);
943}
944
946 bool is_unicode,
947 uint16_t length_lower_word) {
949
950 llvm::SmallVector<char, 256> buffer;
951 if (llvm::Error err = ProcessDebugger::ReadDebugString(
952 debug_string_addr, is_unicode, length_lower_word, buffer)) {
953 std::string err_str = llvm::toString(std::move(err));
954 std::string msg =
955 llvm::formatv("Failed to read debug string at {0:x} "
956 "(size & 0xffff={1}, unicode={2}): {3}\n",
957 debug_string_addr, length_lower_word, is_unicode, err_str)
958 .str();
959 LLDB_LOG(log, "{0}", msg);
960 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
961 return;
962 }
963 if (buffer.empty())
964 return;
965
966 if (is_unicode) {
967 assert(buffer.size() % 2 == 0);
968 llvm::ArrayRef<unsigned short> utf16(
969 reinterpret_cast<const unsigned short *>(buffer.data()),
970 buffer.size() / 2);
971 std::string out;
972 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
973 LLDB_LOG(log, "Debug string is not valid Utf 16");
974 return;
975 }
976 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
977 } else {
978 m_delegate.NewProcessOutput(this,
979 llvm::StringRef(buffer.data(), buffer.size()));
980 }
981}
982
983llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
985 ProcessLaunchInfo &launch_info,
986 NativeProcessProtocol::NativeDelegate &native_delegate) {
987 Error E = Error::success();
988 auto process_up = std::unique_ptr<NativeProcessWindows>(
989 new NativeProcessWindows(launch_info, native_delegate, E));
990 if (E)
991 return std::move(E);
992 return std::move(process_up);
993}
994
995llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
998 Error E = Error::success();
999 // Set pty primary fd invalid since it is not available.
1000 auto process_up = std::unique_ptr<NativeProcessWindows>(
1001 new NativeProcessWindows(pid, -1, native_delegate, E));
1002 if (E)
1003 return std::move(E);
1004 return std::move(process_up);
1005}
1006
1011
1013 if (!m_pty || !m_pty->IsConnected())
1014 return;
1015
1016 m_stdio_communication.SetConnection(
1017 std::make_unique<ConnectionConPTY>(m_pty));
1018 if (!m_stdio_communication.IsConnected())
1019 return;
1020 m_stdio_communication.SetReadThreadBytesReceivedCallback(
1022 m_stdio_communication.StartReadThread();
1023}
1024
1026 if (!m_stdio_communication.HasConnection())
1027 return;
1028
1029 m_stdio_communication.SynchronizeWithReadThread();
1030
1031 if (m_pty)
1032 m_pty->Close();
1033
1034 // Close() cancels the read pending on the pipe, but one that the read thread
1035 // is about to start would only return at its 5s timeout: EOF cannot come
1036 // while the inferior is held at its exit debug event. Wake the thread so that
1037 // it sees the closed PTY right away.
1038 m_stdio_communication.InterruptRead();
1039
1040 if (m_stdio_communication.ReadThreadIsRunning())
1041 m_stdio_communication.JoinReadThread();
1042
1043 if (m_stdio_communication.HasConnection())
1044 m_stdio_communication.Disconnect();
1045}
1046
1048 const void *src,
1049 size_t src_len) {
1050 auto *self = static_cast<NativeProcessWindows *>(baton);
1051 if (src_len == 0)
1052 return;
1053 self->m_delegate.NewProcessOutput(
1054 self, llvm::StringRef(static_cast<const char *>(src), src_len));
1055}
1056
1057size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
1058 Status &error) {
1059 if (!m_stdio_communication.HasConnection()) {
1061 "no ConPTY connection on this NativeProcessWindows");
1062 return 0;
1063 }
1064 ConnectionStatus status;
1065 size_t written = m_stdio_communication.Write(buf, len, status, &error);
1066 if (status != eConnectionStatusSuccess && error.Success())
1068 "ConPTY stdin write returned status {0}", static_cast<int>(status));
1069 return written;
1070}
1071} // namespace lldb_private
static llvm::raw_ostream & error(Stream &strm)
#define STATUS_WX86_BREAKPOINT
DllEventAction
Definition ForwardDecl.h:29
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define PATHCCH_MAX_CCH
#define MAX_PATH
void * HANDLE
lldb::tid_t GetThreadID() const
void Dump(llvm::raw_ostream &stream) const
unsigned long GetExceptionValue() const
llvm::ArrayRef< uint64_t > GetExceptionArguments() const
lldb::addr_t GetExceptionAddress() const
A file utility class.
Definition FileSpec.h:56
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:380
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition aix/Host.cpp:211
FileSpec & GetFileSpec()
Definition ModuleSpec.h:58
NativeProcessProtocol(lldb::pid_t pid, int terminal_fd, NativeDelegate &delegate)
Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
virtual const NativeWatchpointList::WatchpointMap & GetWatchpointMap() const
void SetState(lldb::StateType state, bool notify_delegates=true)
NativeThreadProtocol * GetThreadByID(lldb::tid_t tid)
std::vector< std::unique_ptr< NativeThreadProtocol > > m_threads
virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange)
Status RemoveSoftwareBreakpoint(lldb::addr_t addr)
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
std::map< lldb::addr_t, SoftwareBreakpoint > m_software_breakpoints
virtual llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint)
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr)
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate) override
Launch a process for debugging.
llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override
Attach to an existing process.
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override
ExceptionResult HandleBreakpointException(const ExceptionRecord &record)
llvm::Error DeallocateMemory(lldb::addr_t addr) override
Status Resume(const ResumeActionList &resume_actions) override
void OnCreateThread(const HostThread &thread) override
void OnExitProcess(uint32_t exit_code) override
bool RewindTrapOfRemovedBreakpoint(const ExceptionRecord &record)
A breakpoint trap whose debug event was only delivered after the client removed that breakpoint: the ...
Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) override
void StartStdioForwarding()
Wire up m_stdio_communication on m_pty's STDOUT HANDLE.
static void STDIOReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
Bridge between m_stdio_communication's read thread and NativeDelegate::NewProcessOutput.
llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint) override
void OnDebuggerConnected(lldb::addr_t image_base) override
NativeProcessWindows(ProcessLaunchInfo &launch_info, NativeDelegate &delegate, llvm::Error &E)
Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override
void StopStdioForwarding()
Tear down the read thread and disconnect m_stdio_communication.
size_t WriteStdin(const void *buf, size_t len, Status &error) override
Forward bytes from the gdb-remote I packet into the inferior's ConPTY-backed stdin via m_stdio_commun...
Status DoWriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override
bool m_pending_halt
Set when Halt() / Interrupt() schedules a DebugBreakProcess injection.
ExceptionResult HandleGenericException(bool first_chance, const ExceptionRecord &record)
void SetArchitecture(const ArchSpec &arch_spec)
ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override
void OnDebugString(lldb::addr_t debug_string_addr, bool is_unicode, uint16_t length_lower_word) override
Status ReadMemory(const ProcessAddress &addr, void *buf, size_t size, size_t &bytes_read) override
Plugins without address spaces should error on a non-default one.
size_t GetSoftwareBreakpointPCOffset() override
Return the offset of the PC relative to the software breakpoint that was hit.
std::shared_ptr< PseudoConsole > m_pty
PseudoConsole for the lldb-server stdio-forwarding path.
ThreadedCommunication m_stdio_communication
Wraps a ConnectionConPTY around the PTY's parent-side STDOUT HANDLE.
llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > GetAuxvData() const override
DllEventAction OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr, lldb::tid_t thread_id) override
Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr) override
NativeThreadWindows * GetThreadByID(lldb::tid_t thread_id)
void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override
llvm::Expected< lldb::addr_t > AllocateMemory(size_t size, uint32_t permissions) override
DllEventAction OnUnloadDll(lldb::addr_t module_addr, lldb::tid_t thread_id) override
Status Signal(int signo) override
Sends a process a UNIX signal signal.
Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false) override
const ArchSpec & GetArchitecture() const override
void SetStopReasonForThread(NativeThreadWindows &thread, lldb::StopReason reason, std::string description="")
Status Interrupt() override
Tells a process to interrupt all operations as if by a Ctrl-C.
void StopThread(lldb::tid_t thread_id, lldb::StopReason reason, std::string description="")
ExceptionResult HandleSingleStepException(const ExceptionRecord &record)
bool m_initial_stop_seen
Whether we've seen the loader breakpoint that fires once per process at launch / attach.
bool m_pending_library_events
Set whenever an OS DLL load/unload event has been seen since the last stop reply.
llvm::Expected< std::vector< LoadedLibraryInfo > > GetLoadedLibraries() override
Return the currently loaded libraries of the target in the qXfer:libraries:read form (generic name + ...
lldb::addr_t GetSharedLibraryInfoAddress() override
Status IgnoreSignals(llvm::ArrayRef< int > signals) override
virtual Status GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr)
virtual lldb::addr_t GetWatchpointAddress(uint32_t wp_index)
lldb::addr_t GetPC(lldb::addr_t fail_value=LLDB_INVALID_ADDRESS)
virtual lldb::addr_t GetWatchpointHitAddress(uint32_t wp_index)
void SetStopReason(ThreadStopInfo stop_info, std::string description)
An address in a process, qualified by an address space.
lldb::addr_t GetValue() const
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)
Status DestroyProcess(lldb::StateType process_state)
Status LaunchProcess(ProcessLaunchInfo &launch_info, DebugDelegateSP delegate)
Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
std::unique_ptr< ProcessWindowsData > m_session_data
Status AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr)
virtual ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record)
Status AttachProcess(lldb::pid_t pid, const ProcessAttachInfo &attach_info, DebugDelegateSP delegate)
lldb::pid_t GetDebuggedProcessId() const
void EndDebugSession()
End the debug session, terminating the inferior if it still runs, and wait for the debugger thread to...
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
bool IsSystemModuleAddress(lldb::addr_t addr)
virtual void OnExitProcess(uint32_t exit_code)
static bool IsSystemDLL(llvm::StringRef path)
llvm::Error ReadDebugString(lldb::addr_t debug_string_addr, bool is_unicode, uint16_t length_lower_word, llvm::SmallVectorImpl< char > &output)
Read an OUTPUT_DEBUG_STRING_INFO payload from the inferior.
Status HaltProcess(bool &caused_stop)
Status DeallocateMemory(lldb::addr_t addr)
void SetProcessID(lldb::pid_t pid)
Definition ProcessInfo.h:68
FileSpec & GetExecutableFile()
Definition ProcessInfo.h:41
ArchSpec & GetArchitecture()
Definition ProcessInfo.h:60
std::shared_ptr< PTY > TakePTY()
A pseudo terminal helper class.
const ResumeAction * GetActionForThread(lldb::tid_t tid, bool default_ok) const
Definition Debug.h:74
An error handling class.
Definition Status.h:118
llvm::Error ToError() const
FIXME: Replace all uses with takeError() instead.
Definition Status.cpp:138
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
bool Success() const
Test for success condition.
Definition Status.cpp:303
static lldb::UnixSignalsSP CreateForHost()
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_PROCESS_ID
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
std::string StripExtendedLengthPrefix(llvm::StringRef path)
Convert an extended-length path to a regular DOS path: "\\?\C:\a" becomes "C:\a" and "\\?...
Definition PathUtils.h:21
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition ForwardDecl.h:45
static bool GetLoadedModulePath(HANDLE process, HMODULE module, std::string &path)
std::shared_ptr< ExceptionRecord > ExceptionRecordSP
Definition ForwardDecl.h:47
const char * StateAsCString(lldb::StateType state)
Converts a StateType to a C string.
Definition State.cpp:14
ConnectionStatus
Connection Status Types.
@ eConnectionStatusSuccess
Success.
StateType
Process and Thread States.
@ eStateUnloaded
Process is object is valid, but not currently loaded.
@ 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.
@ 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 pid_t
Definition lldb-types.h:84
uint64_t addr_t
Definition lldb-types.h:80
StopReason
Thread stop reasons.
@ eStopReasonBreakpoint
@ eStopReasonException
@ eStopReasonWatchpoint
uint64_t tid_t
Definition lldb-types.h:85
Generic loaded-library entry used by the non-SVR4 qXfer:libraries:read form of the GDB remote library...
lldb::StateType state
Definition Debug.h:23
struct lldb_private::ThreadStopInfo::@116236113001137253323017204263037302160273237376::@034237007264067231263360140073224264215170222231 exception
lldb::StopReason reason
Definition Debug.h:132
union lldb_private::ThreadStopInfo::@116236113001137253323017204263037302160273237376 details
#define SIGTRAP