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 // The exit replaces a stop that has not been reported yet.
537 m_deferred_stop = false;
538
539 // No signal involved. It is just an exit event.
540 WaitStatus wait_status(WaitStatus::Exit, exit_code);
541 SetExitStatus(wait_status, started);
542
543 // Notify the native delegate.
544 SetState(eStateExited, started);
545}
546
549 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
550 GetDebuggedProcessId(), image_base);
551
552 // This is the earliest chance we can resolve the process ID and
553 // architecture if we don't know them yet.
556
558 bool got_info = Host::GetProcessInfo(GetDebuggedProcessId(), info);
559
560 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
561 if (!got_info) {
562 LLDB_LOG(log, "Cannot get process information during debugger connecting "
563 "to process");
564 return;
565 }
567 }
568
569 if (got_info) {
570 FileSpec exe = info.GetExecutableFile();
571 if (const std::string &image_path =
572 m_session_data->m_debugger->GetImagePath();
573 !image_path.empty() &&
574 !llvm::StringRef(image_path).equals_insensitive(exe.GetPath()))
575 exe = FileSpec(image_path);
576 if (exe) {
578 m_loaded_modules.Add(exe, image_base);
579 }
580 }
581
582 // The very first one shall always be the main thread.
583 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
584 assert(m_threads.empty());
585 m_threads.push_back(std::make_unique<NativeThreadWindows>(
586 *this, m_session_data->m_debugger->GetMainThread()));
587}
588
590 if (GetState() == eStateStopped) {
591 if (!m_deferred_stop)
593 "debug event on thread {0:x} while a reported stop is current",
595 return;
596 }
597 SetState(eStateStopped, /*notify_delegates=*/false);
598 m_deferred_stop = true;
600}
601
611
613 const ExceptionRecord &record) {
615 return false;
617 if (!thread)
618 return false;
619 const lldb::addr_t trap_addr = record.GetExceptionAddress();
620 llvm::ArrayRef<uint8_t> trap_opcode =
622 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
623 if (reg_ctx.GetPC() != trap_addr + trap_opcode.size())
624 return false;
625 llvm::SmallVector<uint8_t, 4> bytes(trap_opcode.size(), 0);
626 size_t bytes_read = 0;
627 if (ProcessDebugger::ReadMemory(trap_addr, bytes.data(), bytes.size(),
628 bytes_read)
629 .Fail() ||
630 bytes_read != bytes.size() ||
631 llvm::ArrayRef<uint8_t>(bytes) == trap_opcode)
632 return false;
634 "Trap at {0:x} on thread {1:x} is from a removed breakpoint, "
635 "rewinding the thread onto the original instruction.",
636 trap_addr, thread->GetID());
637 return reg_ctx.SetPC(trap_addr).Success();
638}
639
642 uint32_t wp_id = LLDB_INVALID_INDEX32;
643#ifndef __aarch64__
645 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
646 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
647 Status error =
648 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
649 if (error.Fail())
650 LLDB_LOG(log,
651 "received error while checking for watchpoint hits, pid = "
652 "{0}, error = {1}",
653 thread->GetID(), error);
654 if (wp_id != LLDB_INVALID_INDEX32) {
655 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
656 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
657 std::string desc =
658 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
660 }
661 }
662#endif
663 if (wp_id == LLDB_INVALID_INDEX32) {
665 if (thread && !thread->IsSingleStepping()) {
667 "ignoring a late single-step trap on thread {0:x}, which this "
668 "resume did not step",
669 record.GetThreadID());
671 }
673 }
674
675 DeferStop();
677}
678
682 const auto exception_addr = record.GetExceptionAddress();
683 const auto thread_id = record.GetThreadID();
684
685 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
686 auto &reg_ctx = stop_thread->GetRegisterContext();
687
688 if (FindSoftwareBreakpoint(exception_addr)) {
689 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
690 exception_addr);
692 // The current PC is AFTER the BP opcode, on all architectures.
693 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
694 DeferStop();
696 }
697
698 // This block of code will only be entered in case of a hardware
699 // watchpoint or breakpoint hit on AArch64. However, we only handle
700 // hardware watchpoints below as breakpoints are not yet supported.
701 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
702 // Check that the ExceptionInformation array of EXCEPTION_RECORD
703 // contains at least two elements: the first is a read-write flag
704 // indicating the type of data access operation (read or write) while
705 // the second contains the virtual address of the accessed data.
706 if (args.size() >= 2) {
707 uint32_t hw_id = LLDB_INVALID_INDEX32;
708 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
709 if (error.Fail())
710 LLDB_LOG(log,
711 "received error while checking for watchpoint hits, pid = "
712 "{0}, error = {1}",
713 thread_id, error);
714
715 if (hw_id != LLDB_INVALID_INDEX32) {
716 std::string desc =
717 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
718 exception_addr)
719 .str();
721 DeferStop();
723 }
724 }
725
728 }
729
730 if (!m_initial_stop_seen) {
731 m_initial_stop_seen = true;
732 LLDB_LOG(log,
733 "Hit loader breakpoint at address {0:x}, setting initial stop "
734 "event.",
735 exception_addr);
736
737 // We are required to report the reason for the first stop after
738 // launching or being attached.
739 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
741
742 // Do not notify the native delegate (e.g. llgs) since at this moment
743 // the program hasn't returned from Manager::Launch() and the delegate
744 // might not have an valid native process to operate on.
745 SetState(eStateStopped, false);
746
747 // Hit the initial stop. Continue the application.
749 }
750
751 // Our own DebugBreakProcess() injection, used to implement
752 // Halt()/Interrupt().
753 if (m_pending_halt) {
754 LLDB_LOG(log,
755 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
756 "{0:x}",
757 thread_id);
758 m_pending_halt = false;
759 ThreadStopInfo signal_info;
761 signal_info.signo =
762 UnixSignals::CreateForHost()->GetSignalNumberFromName("SIGSTOP");
763
764 // Halt all threads at the kernel level.
765 {
766 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
767 for (uint32_t i = 0; i < m_threads.size(); ++i) {
768 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
769 if (Status err = t->DoStop(); err.Fail()) {
770 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
771 err.GetError());
772 exit(1);
773 }
774 }
775 }
776 SetCurrentThreadID(thread_id);
777 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
778 injected->SetStopReason(signal_info, "interrupt");
779 DeferStop();
781 }
782
783 if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
785 LLDB_LOG(log,
786 "Skipping expected loader breakpoint at address {0:x} in a "
787 "system module.",
788 exception_addr);
790 }
791
792 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
793 record.GetExceptionValue(), exception_addr)
794 .str();
795 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
796 DeferStop();
798}
799
802 const ExceptionRecord &record) {
804 LLDB_LOG(log,
805 "Debugger thread reported exception {0:x} at address {1:x} "
806 "(first_chance={2})",
807 record.GetExceptionValue(), record.GetExceptionAddress(),
808 first_chance);
809
810 if (first_chance)
812
813 std::string desc;
814 llvm::raw_string_ostream desc_stream(desc);
815 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
816 << " encountered at address "
817 << llvm::format_hex(record.GetExceptionAddress(), 8);
818 record.Dump(desc_stream);
820 std::move(desc));
821
822 DeferStop();
824}
825
828 const ExceptionRecord &record) {
829 llvm::sys::ScopedLock lock(m_mutex);
830
831 // Handle the exception first to keep track of the stop reason.
832 ExceptionResult result;
833 switch (record.GetExceptionValue()) {
834 case DWORD(STATUS_SINGLE_STEP):
835 case STATUS_WX86_SINGLE_STEP:
836 result = HandleSingleStepException(record);
837 break;
838 case DWORD(STATUS_BREAKPOINT):
840 result = HandleBreakpointException(record);
841 break;
842 default:
843 result = HandleGenericException(first_chance, record);
844 break;
845 }
846
847 // Let the debugger establish the internal status.
848 ProcessDebugger::OnDebugException(first_chance, record);
849
850 return result;
851}
852
854 llvm::sys::ScopedLock lock(m_mutex);
855 const StateType state = GetState();
856 std::lock_guard<std::recursive_mutex> threads_guard(m_threads_mutex);
857
858 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
859 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
860 for (const auto &pair : GetWatchpointMap()) {
861 const NativeWatchpoint &wp = pair.second;
862 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
863 wp.m_hardware);
864 }
865
866 if (state == eStateStopped || state == eStateCrashed) {
867 if (Status error = thread->DoStop(); error.Fail()) {
869 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
870 thread->GetID(), error);
871 }
872 ThreadStopInfo stop_info;
873 stop_info.reason = lldb::eStopReasonNone;
874 thread->SetStopReason(stop_info, "");
875 }
876
877 m_threads.push_back(std::move(thread));
878}
879
881 uint32_t exit_code) {
882 llvm::sys::ScopedLock lock(m_mutex);
883 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
884 llvm::erase_if(m_threads, [thread_id](const auto &t) {
885 return t->GetID() == thread_id;
886 });
887}
888
890 lldb::addr_t module_addr,
891 lldb::tid_t thread_id) {
893 llvm::sys::ScopedLock lock(m_mutex);
894
895 FileSpec resolved = module_spec.GetFileSpec();
896 if (resolved) {
897 FileSystem::Instance().Resolve(resolved);
898 m_loaded_modules.Add(resolved, module_addr);
899 }
901
904
905 // Can't resolve a breakpoint in a system DLL.
906 if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
908
909 {
910 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
911 NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
912 if (!loader_thread && !m_threads.empty()) {
913 LLDB_LOG(log,
914 "LOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
915 thread_id);
916 loader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
917 }
918 if (loader_thread) {
919 SetCurrentThreadID(loader_thread->GetID());
920 if (loader_thread->DoStop().Fail())
921 LLDB_LOG(log, "Failed to suspend thread {0} on LOAD_DLL.",
922 loader_thread->GetID());
923 ThreadStopInfo info;
925 info.signo = 0;
926 loader_thread->SetStopReason(info, "");
927 }
928 }
929 SetState(eStateStopped, true);
930
932}
933
935 lldb::tid_t thread_id) {
937 llvm::sys::ScopedLock lock(m_mutex);
938
939 FileSpec unloaded_spec = m_loaded_modules.Remove(module_addr);
941
944
945 if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
947
948 {
949 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
950 NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
951 if (!unloader_thread && !m_threads.empty()) {
952 LLDB_LOG(log,
953 "UNLOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
954 thread_id);
955 unloader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
956 }
957 if (unloader_thread) {
958 SetCurrentThreadID(unloader_thread->GetID());
959 if (unloader_thread->DoStop().Fail())
960 LLDB_LOG(log, "Failed to suspend thread {0} on UNLOAD_DLL.",
961 unloader_thread->GetID());
962 ThreadStopInfo info;
964 info.signo = 0;
965 unloader_thread->SetStopReason(info, "");
966 }
967 }
968 SetState(eStateStopped, true);
970}
971
973 bool is_unicode,
974 uint16_t length_lower_word) {
976
977 llvm::SmallVector<char, 256> buffer;
978 if (llvm::Error err = ProcessDebugger::ReadDebugString(
979 debug_string_addr, is_unicode, length_lower_word, buffer)) {
980 std::string err_str = llvm::toString(std::move(err));
981 std::string msg =
982 llvm::formatv("Failed to read debug string at {0:x} "
983 "(size & 0xffff={1}, unicode={2}): {3}\n",
984 debug_string_addr, length_lower_word, is_unicode, err_str)
985 .str();
986 LLDB_LOG(log, "{0}", msg);
987 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
988 return;
989 }
990 if (buffer.empty())
991 return;
992
993 if (is_unicode) {
994 assert(buffer.size() % 2 == 0);
995 llvm::ArrayRef<unsigned short> utf16(
996 reinterpret_cast<const unsigned short *>(buffer.data()),
997 buffer.size() / 2);
998 std::string out;
999 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
1000 LLDB_LOG(log, "Debug string is not valid Utf 16");
1001 return;
1002 }
1003 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
1004 } else {
1005 m_delegate.NewProcessOutput(this,
1006 llvm::StringRef(buffer.data(), buffer.size()));
1007 }
1008}
1009
1010llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
1012 ProcessLaunchInfo &launch_info,
1013 NativeProcessProtocol::NativeDelegate &native_delegate) {
1014 Error E = Error::success();
1015 auto process_up = std::unique_ptr<NativeProcessWindows>(
1016 new NativeProcessWindows(launch_info, native_delegate, E));
1017 if (E)
1018 return std::move(E);
1019 return std::move(process_up);
1020}
1021
1022llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
1024 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) {
1025 Error E = Error::success();
1026 // Set pty primary fd invalid since it is not available.
1027 auto process_up = std::unique_ptr<NativeProcessWindows>(
1028 new NativeProcessWindows(pid, -1, native_delegate, E));
1029 if (E)
1030 return std::move(E);
1031 return std::move(process_up);
1032}
1033
1038
1040 if (!m_pty || !m_pty->IsConnected())
1041 return;
1042
1043 m_stdio_communication.SetConnection(
1044 std::make_unique<ConnectionConPTY>(m_pty));
1045 if (!m_stdio_communication.IsConnected())
1046 return;
1047 m_stdio_communication.SetReadThreadBytesReceivedCallback(
1049 m_stdio_communication.StartReadThread();
1050}
1051
1053 if (!m_stdio_communication.HasConnection())
1054 return;
1055
1056 m_stdio_communication.SynchronizeWithReadThread();
1057
1058 if (m_pty)
1059 m_pty->Close();
1060
1061 // Close() cancels the read pending on the pipe, but one that the read thread
1062 // is about to start would only return at its 5s timeout: EOF cannot come
1063 // while the inferior is held at its exit debug event. Wake the thread so that
1064 // it sees the closed PTY right away.
1065 m_stdio_communication.InterruptRead();
1066
1067 if (m_stdio_communication.ReadThreadIsRunning())
1068 m_stdio_communication.JoinReadThread();
1069
1070 if (m_stdio_communication.HasConnection())
1071 m_stdio_communication.Disconnect();
1072}
1073
1075 const void *src,
1076 size_t src_len) {
1077 auto *self = static_cast<NativeProcessWindows *>(baton);
1078 if (src_len == 0)
1079 return;
1080 self->m_delegate.NewProcessOutput(
1081 self, llvm::StringRef(static_cast<const char *>(src), src_len));
1082}
1083
1084size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
1085 Status &error) {
1086 if (!m_stdio_communication.HasConnection()) {
1088 "no ConPTY connection on this NativeProcessWindows");
1089 return 0;
1090 }
1091 ConnectionStatus status;
1092 size_t written = m_stdio_communication.Write(buf, len, status, &error);
1093 if (status != eConnectionStatusSuccess && error.Success())
1095 "ConPTY stdin write returned status {0}", static_cast<int>(status));
1096 return written;
1097}
1098} // 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:57
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)
void SynchronouslyNotifyProcessStateChanged(lldb::StateType state)
Notify the delegates of state.
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 DeferStop()
Stop the process without notifying the delegate yet.
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
bool m_deferred_stop
Whether the process is stopped but the stop has not been reported to the delegate yet.
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
lldb::tid_t m_deferred_stop_tid
The thread whose debug event started the deferred stop.
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