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"
30#include "lldb/Utility/State.h"
31#include "llvm/ADT/STLExtras.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/Support/ConvertUTF.h"
34#include "llvm/Support/Errc.h"
35#include "llvm/Support/Error.h"
36#include "llvm/Support/Format.h"
37#include "llvm/Support/Threading.h"
38#include "llvm/Support/raw_ostream.h"
39
40#include "DebuggerThread.h"
41#include "ExceptionRecord.h"
42#include "ProcessWindowsLog.h"
43
44#include <tlhelp32.h>
45
46#pragma warning(disable : 4005)
47#include "winternl.h"
48#include <ntstatus.h>
49
50using namespace lldb;
51using namespace lldb_private;
52using namespace llvm;
53
54namespace lldb_private {
55
57 NativeDelegate &delegate,
58 llvm::Error &E)
61 PseudoTerminal::invalid_fd, // NativeProcessWindows owns the ConPTY.
62 delegate),
63 ProcessDebugger(), m_arch(launch_info.GetArchitecture()),
64 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
65 ErrorAsOutParameter EOut(&E);
66 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
67 E = LaunchProcess(launch_info, delegate_sp).ToError();
68 if (E)
69 return;
70
72
73 m_pty = launch_info.TakePTY();
75}
76
78 NativeDelegate &delegate,
79 llvm::Error &E)
80 : NativeProcessProtocol(pid, terminal_fd, delegate), ProcessDebugger(),
81 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
82 ErrorAsOutParameter EOut(&E);
83 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
84 ProcessAttachInfo attach_info;
85 attach_info.SetProcessID(pid);
86 E = AttachProcess(pid, attach_info, delegate_sp).ToError();
87 if (E)
88 return;
89
91
93
95 if (!Host::GetProcessInfo(pid, info)) {
96 E = createStringError(inconvertibleErrorCode(),
97 "Cannot get process information");
98 return;
99 }
100 m_arch = info.GetArchitecture();
101}
102
106 llvm::sys::ScopedLock lock(m_mutex);
107
108 StateType state = GetState();
109 if (state == eStateStopped || state == eStateCrashed) {
110 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
111 GetDebuggedProcessId(), state);
112 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
113 LLDB_LOG(log, "resuming {0} threads.", m_threads.size());
114
116
117 bool failed = false;
118 for (uint32_t i = 0; i < m_threads.size(); ++i) {
119 auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get());
120 const ResumeAction *const action =
121 resume_actions.GetActionForThread(thread->GetID(), true);
122 if (action == nullptr)
123 continue;
124
125 switch (action->state) {
126 case eStateRunning:
127 case eStateStepping: {
128 Status result = thread->DoResume(action->state);
129 if (result.Fail()) {
130 failed = true;
131 LLDB_LOG(log,
132 "Trying to resume thread at index {0}, but failed with "
133 "error {1}.",
134 i, result);
135 }
136 break;
137 }
138 case eStateSuspended:
139 case eStateStopped:
140 break;
141
142 default:
144 "NativeProcessWindows::%s (): unexpected state %s specified "
145 "for pid %" PRIu64 ", tid %" PRIu64,
146 __FUNCTION__, StateAsCString(action->state), GetID(),
147 thread->GetID());
148 }
149 }
150
151 if (failed) {
152 error = Status::FromErrorString("NativeProcessWindows::DoResume failed");
153 } else {
155 }
156
157 // Resume the debug loop.
158 ExceptionRecordSP active_exception =
159 m_session_data->m_debugger->GetActiveException();
160 if (active_exception) {
161 // Resume the process and continue processing debug events. Mask the
162 // exception so that from the process's view, there is no indication that
163 // anything happened.
164 m_session_data->m_debugger->ContinueAsyncException(
166 } else {
167 m_session_data->m_debugger->ContinueAsyncDllEvent();
168 }
169 } else {
170 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
172 }
173
174 return error;
175}
176
182
184 bool caused_stop = false;
185 StateType state = GetState();
186 if (state != eStateStopped) {
187 m_pending_halt = true;
188 Status err = HaltProcess(caused_stop);
189 if (err.Fail() || !caused_stop)
190 m_pending_halt = false;
191 return err;
192 }
193 return Status();
194}
195
199 StateType state = GetState();
200 if (state != eStateExited && state != eStateDetached) {
202 if (error.Success())
204 else
205 LLDB_LOG(log, "Detaching process error: {0}", error);
206 } else {
208 "error: process {0} in state = {1}, but "
209 "cannot detach it in this state.",
210 GetID(), state);
211 LLDB_LOG(log, "error: {0}", error);
212 }
213 return error;
214}
215
219 "Windows does not support sending signals to processes");
220 return error;
221}
222
224
226 StateType state = GetState();
227 return DestroyProcess(state);
228}
229
230Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) {
231 return Status();
232}
233
238
240 void *buf, size_t size,
241 size_t &bytes_read) {
242 lldb::addr_t addr = process_addr.GetValue();
243 return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
244}
245
247 size_t size, size_t &bytes_written) {
248 return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
249}
250
251llvm::Expected<lldb::addr_t>
252NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
253 lldb::addr_t addr;
254 Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
255 if (ST.Success())
256 return addr;
257 return ST.ToError();
258}
259
263
265
267 StateType state = GetState();
268 switch (state) {
269 case eStateCrashed:
270 case eStateDetached:
271 case eStateExited:
272 case eStateInvalid:
273 case eStateUnloaded:
274 return false;
275 default:
276 return true;
277 }
278}
279
281 lldb::StopReason reason,
282 std::string description) {
283 SetCurrentThreadID(thread.GetID());
284
285 ThreadStopInfo stop_info;
286 stop_info.reason = reason;
287 // No signal support on Windows but required to provide a 'valid' signum.
288 stop_info.signo = SIGTRAP;
289
290 if (reason == StopReason::eStopReasonException) {
291 stop_info.details.exception.type = 0;
292 stop_info.details.exception.data_count = 0;
293 }
294
295 thread.SetStopReason(stop_info, description);
296}
297
299 lldb::StopReason reason,
300 std::string description) {
301 NativeThreadWindows *thread = GetThreadByID(thread_id);
302 if (!thread)
303 return;
304
306 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
307 for (uint32_t i = 0; i < m_threads.size(); ++i) {
308 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
309 if (Status error = t->DoStop(); error.Fail())
310 LLDB_LOG(log, "failed to stop thread {0}: {1}", t->GetID(), error);
311 }
312 SetStopReasonForThread(*thread, reason, description);
313}
314
316 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
317 return m_threads.size();
318}
319
320llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
322 // Not available on this target.
323 return llvm::errc::not_supported;
324}
325
326llvm::Expected<llvm::ArrayRef<uint8_t>>
328 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e,
329 0xd4}; // brk #0xf000
330 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
331
332 switch (GetArchitecture().GetMachine()) {
333 case llvm::Triple::aarch64:
334 return llvm::ArrayRef(g_aarch64_opcode);
335
336 case llvm::Triple::arm:
337 case llvm::Triple::thumb:
338 return llvm::ArrayRef(g_thumb_opcode);
339
340 default:
342 }
343}
344
346 // Windows always reports an incremented PC after a breakpoint is hit,
347 // even on ARM.
348 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
349}
350
354
356 bool hardware) {
357 if (hardware)
358 return SetHardwareBreakpoint(addr, size);
359 return SetSoftwareBreakpoint(addr, size);
360}
361
363 bool hardware) {
364 if (hardware)
365 return RemoveHardwareBreakpoint(addr);
366 return RemoveSoftwareBreakpoint(addr);
367}
368
369// Get the path of a module loaded in the target process, as the loader recorded
370// it.
371//
372// Keep the loader's spelling.
373static bool GetLoadedModulePath(HANDLE process, HMODULE module,
374 std::string &path) {
375 std::vector<wchar_t> name(MAX_PATH);
376 DWORD len = 0;
377 while (true) {
378 len = ::GetModuleFileNameExW(process, module, name.data(),
379 static_cast<DWORD>(name.size()));
380 if (len == 0)
381 return false;
382 if (len < name.size())
383 break;
384 if (name.size() >= PATHCCH_MAX_CCH)
385 return false;
386 name.resize(name.size() * 2);
387 }
388
389 std::wstring wpath(name.data(), len);
390 if (!llvm::convertWideToUTF8(wpath, path))
391 return false;
392 path = StripExtendedLengthPrefix(path);
393
394 // The loader's path often differs from the on-disk one only in case (e.g.
395 // C:\windows\System32\KERNEL32.DLL). Open the image file to get its on-disk
396 // spelling, and use it if that's the only difference.
397 AutoHandle file(::CreateFileW(
398 wpath.c_str(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
399 nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
400
401 if (!file.IsValid())
402 return true;
403
404 // Unlike GetModuleFileNameExW, GetFinalPathNameByHandleW reports the buffer
405 // size it needs instead of truncating, so start empty and let the first call
406 // size the buffer rather than guessing.
407 std::vector<wchar_t> full;
408 while (true) {
409 DWORD needed = ::GetFinalPathNameByHandleW(
410 file.get(), full.data(), static_cast<DWORD>(full.size()),
411 FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
412 if (needed == 0)
413 break;
414 if (needed < full.size()) {
415 std::string canonical;
416 if (!llvm::convertWideToUTF8(std::wstring_view(full.data(), needed),
417 canonical))
418 break;
419 // GetFinalPathNameByHandleW returns an extended-length ("\\?\") path.
420 canonical = StripExtendedLengthPrefix(canonical);
421 if (llvm::StringRef(canonical).equals_insensitive(path))
422 path = std::move(canonical);
423 break;
424 }
425 full.resize(needed);
426 }
427
428 return true;
429}
430
433 if (!m_loaded_modules.IsEmpty())
434 return Status();
435
436 AutoHandle process(::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
437 FALSE, GetID()),
438 nullptr);
439 if (!process.IsValid())
440 return Status(::GetLastError(), eErrorTypeWin32);
441
442 AutoHandle snapshot(::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
443 if (!snapshot.IsValid())
444 return Status(::GetLastError(), eErrorTypeWin32);
445
446 MODULEENTRY32W me;
447 me.dwSize = sizeof(MODULEENTRY32W);
448 if (::Module32FirstW(snapshot.get(), &me)) {
449 do {
450 std::string path;
451 if (!GetLoadedModulePath(process.get(), me.hModule, path))
452 continue;
453
454 FileSpec file_spec(path);
455 FileSystem::Instance().Resolve(file_spec);
456 m_loaded_modules.Add(file_spec, reinterpret_cast<addr_t>(me.modBaseAddr));
457 } while (::Module32NextW(snapshot.get(), &me));
458 }
459
460 if (!m_loaded_modules.IsEmpty())
461 return Status();
462
463 error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
464 return error;
465}
466
468 FileSpec &file_spec) {
470 if (error.Fail())
471 return error;
472
473 FileSpec module_file_spec(module_path);
474 FileSystem::Instance().Resolve(module_file_spec);
475 if (const FileSpec *found = m_loaded_modules.FindFile(module_file_spec)) {
476 file_spec = *found;
477 return Status();
478 }
480 "Module (%s) not found in process %" PRIu64 "!",
481 module_file_spec.GetPath().c_str(), GetID());
482}
483
484Status
485NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
486 lldb::addr_t &load_addr) {
488 if (error.Fail())
489 return error;
490
491 load_addr = LLDB_INVALID_ADDRESS;
492 FileSpec file_spec(file_name);
493 FileSystem::Instance().Resolve(file_spec);
494 if (std::optional<addr_t> base = m_loaded_modules.GetBaseAddress(file_spec)) {
495 load_addr = *base;
496 return Status();
497 }
499 "Can't get loaded address of file (%s) in process %" PRIu64 "!",
500 file_spec.GetPath().c_str(), GetID());
501}
502
503llvm::Expected<std::vector<LoadedLibraryInfo>>
505 if (Status error = CacheLoadedModules(); error.Fail())
506 return error.ToError();
507
508 std::vector<LoadedLibraryInfo> libs;
509 libs.reserve(m_loaded_modules.GetSize());
510 for (const auto &[file_spec, base_addrs] : m_loaded_modules) {
512 info.name = file_spec.GetPath();
513 info.base_addr = base_addrs.front();
514 libs.push_back(std::move(info));
515 }
516 return libs;
517}
518
522
523void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
525 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
526
527 // Closing the ConPTY signals EOF on the parent-side STDOUT pipe so the
528 // read thread can exit. Tear it down before the debuggee is destroyed.
530
532
533 // No signal involved. It is just an exit event.
534 WaitStatus wait_status(WaitStatus::Exit, exit_code);
535 SetExitStatus(wait_status, true);
536
537 // Notify the native delegate.
538 SetState(eStateExited, true);
539}
540
543 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
544 GetDebuggedProcessId(), image_base);
545
546 // This is the earliest chance we can resolve the process ID and
547 // architecture if we don't know them yet.
550
552 bool got_info = Host::GetProcessInfo(GetDebuggedProcessId(), info);
553
554 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
555 if (!got_info) {
556 LLDB_LOG(log, "Cannot get process information during debugger connecting "
557 "to process");
558 return;
559 }
561 }
562
563 if (got_info) {
564 FileSpec exe = info.GetExecutableFile();
565 if (const std::string &image_path =
566 m_session_data->m_debugger->GetImagePath();
567 !image_path.empty() &&
568 !llvm::StringRef(image_path).equals_insensitive(exe.GetPath()))
569 exe = FileSpec(image_path);
570 if (exe) {
572 m_loaded_modules.Add(exe, image_base);
573 }
574 }
575
576 // The very first one shall always be the main thread.
577 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
578 assert(m_threads.empty());
579 m_threads.push_back(std::make_unique<NativeThreadWindows>(
580 *this, m_session_data->m_debugger->GetMainThread()));
581}
582
585 uint32_t wp_id = LLDB_INVALID_INDEX32;
586#ifndef __aarch64__
588 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
589 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
590 Status error =
591 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
592 if (error.Fail())
593 LLDB_LOG(log,
594 "received error while checking for watchpoint hits, pid = "
595 "{0}, error = {1}",
596 thread->GetID(), error);
597 if (wp_id != LLDB_INVALID_INDEX32) {
598 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
599 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
600 std::string desc =
601 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
603 }
604 }
605#endif
606 if (wp_id == LLDB_INVALID_INDEX32)
608
609 SetState(eStateStopped, true);
611}
612
616 const auto exception_addr = record.GetExceptionAddress();
617 const auto thread_id = record.GetThreadID();
618
619 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
620 auto &reg_ctx = stop_thread->GetRegisterContext();
621
622 if (FindSoftwareBreakpoint(exception_addr)) {
623 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
624 exception_addr);
626 // The current PC is AFTER the BP opcode, on all architectures.
627 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
628 SetState(eStateStopped, true);
630 }
631
632 // This block of code will only be entered in case of a hardware
633 // watchpoint or breakpoint hit on AArch64. However, we only handle
634 // hardware watchpoints below as breakpoints are not yet supported.
635 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
636 // Check that the ExceptionInformation array of EXCEPTION_RECORD
637 // contains at least two elements: the first is a read-write flag
638 // indicating the type of data access operation (read or write) while
639 // the second contains the virtual address of the accessed data.
640 if (args.size() >= 2) {
641 uint32_t hw_id = LLDB_INVALID_INDEX32;
642 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
643 if (error.Fail())
644 LLDB_LOG(log,
645 "received error while checking for watchpoint hits, pid = "
646 "{0}, error = {1}",
647 thread_id, error);
648
649 if (hw_id != LLDB_INVALID_INDEX32) {
650 std::string desc =
651 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
652 exception_addr)
653 .str();
655 SetState(eStateStopped, true);
657 }
658 }
659 }
660
661 if (!m_initial_stop_seen) {
662 m_initial_stop_seen = true;
663 LLDB_LOG(log,
664 "Hit loader breakpoint at address {0:x}, setting initial stop "
665 "event.",
666 exception_addr);
667
668 // We are required to report the reason for the first stop after
669 // launching or being attached.
670 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
672
673 // Do not notify the native delegate (e.g. llgs) since at this moment
674 // the program hasn't returned from Manager::Launch() and the delegate
675 // might not have an valid native process to operate on.
676 SetState(eStateStopped, false);
677
678 // Hit the initial stop. Continue the application.
680 }
681
682 // Our own DebugBreakProcess() injection, used to implement
683 // Halt()/Interrupt().
684 if (m_pending_halt) {
685 LLDB_LOG(log,
686 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
687 "{0:x}",
688 thread_id);
689 m_pending_halt = false;
690 ThreadStopInfo signal_info;
692 signal_info.signo = 19; // SIGSTOP on POSIX
693
694 // Halt all threads at the kernel level.
695 {
696 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
697 for (uint32_t i = 0; i < m_threads.size(); ++i) {
698 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
699 if (Status err = t->DoStop(); err.Fail()) {
700 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
701 err.GetError());
702 exit(1);
703 }
704 }
705 }
706 SetCurrentThreadID(thread_id);
707 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
708 injected->SetStopReason(signal_info, "interrupt");
709 SetState(eStateStopped, true);
711 }
712
713 if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
715 LLDB_LOG(log,
716 "Skipping expected loader breakpoint at address {0:x} in a "
717 "system module.",
718 exception_addr);
720 }
721
722 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
723 record.GetExceptionValue(), exception_addr)
724 .str();
725 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
726 SetState(eStateStopped, true);
728}
729
732 const ExceptionRecord &record) {
734 LLDB_LOG(log,
735 "Debugger thread reported exception {0:x} at address {1:x} "
736 "(first_chance={2})",
737 record.GetExceptionValue(), record.GetExceptionAddress(),
738 first_chance);
739
740 if (first_chance)
742
743 std::string desc;
744 llvm::raw_string_ostream desc_stream(desc);
745 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
746 << " encountered at address "
747 << llvm::format_hex(record.GetExceptionAddress(), 8);
748 record.Dump(desc_stream);
750 std::move(desc));
751
752 SetState(eStateStopped, true);
754}
755
758 const ExceptionRecord &record) {
759 llvm::sys::ScopedLock lock(m_mutex);
760
761 // Handle the exception first to keep track of the stop reason.
762 ExceptionResult result;
763 switch (record.GetExceptionValue()) {
764 case DWORD(STATUS_SINGLE_STEP):
765 case STATUS_WX86_SINGLE_STEP:
766 result = HandleSingleStepException(record);
767 break;
768 case DWORD(STATUS_BREAKPOINT):
770 result = HandleBreakpointException(record);
771 break;
772 default:
773 result = HandleGenericException(first_chance, record);
774 break;
775 }
776
777 // Let the debugger establish the internal status.
778 ProcessDebugger::OnDebugException(first_chance, record);
779
780 return result;
781}
782
784 llvm::sys::ScopedLock lock(m_mutex);
785
786 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
787 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
788 for (const auto &pair : GetWatchpointMap()) {
789 const NativeWatchpoint &wp = pair.second;
790 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
791 wp.m_hardware);
792 }
793
794 if (StateType state = GetState();
795 state == eStateStopped || state == eStateCrashed) {
796 if (Status error = thread->DoStop(); error.Fail()) {
798 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
799 thread->GetID(), error);
800 }
801 ThreadStopInfo stop_info;
802 stop_info.reason = lldb::eStopReasonNone;
803 thread->SetStopReason(stop_info, "");
804 }
805
806 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
807 m_threads.push_back(std::move(thread));
808}
809
811 uint32_t exit_code) {
812 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
813 llvm::erase_if(m_threads, [thread_id](const auto &t) {
814 return t->GetID() == thread_id;
815 });
816}
817
819 lldb::addr_t module_addr,
820 lldb::tid_t thread_id) {
822 llvm::sys::ScopedLock lock(m_mutex);
823
824 FileSpec resolved = module_spec.GetFileSpec();
825 if (resolved) {
826 FileSystem::Instance().Resolve(resolved);
827 m_loaded_modules.Add(resolved, module_addr);
828 }
830
833
834 // Can't resolve a breakpoint in a system DLL.
835 if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
837
838 {
839 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
840 NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
841 if (!loader_thread && !m_threads.empty()) {
842 LLDB_LOG(log,
843 "LOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
844 thread_id);
845 loader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
846 }
847 if (loader_thread) {
848 SetCurrentThreadID(loader_thread->GetID());
849 if (loader_thread->DoStop().Fail())
850 LLDB_LOG(log, "Failed to suspend thread {0} on LOAD_DLL.",
851 loader_thread->GetID());
852 ThreadStopInfo info;
854 info.signo = 0;
855 loader_thread->SetStopReason(info, "");
856 }
857 }
858 SetState(eStateStopped, true);
859
861}
862
864 lldb::tid_t thread_id) {
866 llvm::sys::ScopedLock lock(m_mutex);
867
868 FileSpec unloaded_spec = m_loaded_modules.Remove(module_addr);
870
873
874 if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
876
877 {
878 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
879 NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
880 if (!unloader_thread && !m_threads.empty()) {
881 LLDB_LOG(log,
882 "UNLOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
883 thread_id);
884 unloader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
885 }
886 if (unloader_thread) {
887 SetCurrentThreadID(unloader_thread->GetID());
888 if (unloader_thread->DoStop().Fail())
889 LLDB_LOG(log, "Failed to suspend thread {0} on UNLOAD_DLL.",
890 unloader_thread->GetID());
891 ThreadStopInfo info;
893 info.signo = 0;
894 unloader_thread->SetStopReason(info, "");
895 }
896 }
897 SetState(eStateStopped, true);
899}
900
902 bool is_unicode,
903 uint16_t length_lower_word) {
905
906 llvm::SmallVector<char, 256> buffer;
907 if (llvm::Error err = ProcessDebugger::ReadDebugString(
908 debug_string_addr, is_unicode, length_lower_word, buffer)) {
909 std::string err_str = llvm::toString(std::move(err));
910 std::string msg =
911 llvm::formatv("Failed to read debug string at {0:x} "
912 "(size & 0xffff={1}, unicode={2}): {3}\n",
913 debug_string_addr, length_lower_word, is_unicode, err_str)
914 .str();
915 LLDB_LOG(log, "{0}", msg);
916 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
917 return;
918 }
919 if (buffer.empty())
920 return;
921
922 if (is_unicode) {
923 assert(buffer.size() % 2 == 0);
924 llvm::ArrayRef<unsigned short> utf16(
925 reinterpret_cast<const unsigned short *>(buffer.data()),
926 buffer.size() / 2);
927 std::string out;
928 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
929 LLDB_LOG(log, "Debug string is not valid Utf 16");
930 return;
931 }
932 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
933 } else {
934 m_delegate.NewProcessOutput(this,
935 llvm::StringRef(buffer.data(), buffer.size()));
936 }
937}
938
939llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
941 ProcessLaunchInfo &launch_info,
942 NativeProcessProtocol::NativeDelegate &native_delegate) {
943 Error E = Error::success();
944 auto process_up = std::unique_ptr<NativeProcessWindows>(
945 new NativeProcessWindows(launch_info, native_delegate, E));
946 if (E)
947 return std::move(E);
948 return std::move(process_up);
949}
950
951llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
954 Error E = Error::success();
955 // Set pty primary fd invalid since it is not available.
956 auto process_up = std::unique_ptr<NativeProcessWindows>(
957 new NativeProcessWindows(pid, -1, native_delegate, E));
958 if (E)
959 return std::move(E);
960 return std::move(process_up);
961}
962
964
966 if (!m_pty || !m_pty->IsConnected())
967 return;
968
969 m_stdio_communication.SetConnection(
970 std::make_unique<ConnectionConPTY>(m_pty));
971 if (!m_stdio_communication.IsConnected())
972 return;
973 m_stdio_communication.SetReadThreadBytesReceivedCallback(
975 m_stdio_communication.StartReadThread();
976}
977
979 if (!m_stdio_communication.HasConnection())
980 return;
981
982 if (m_pty)
983 m_pty->Close();
984
985 if (m_stdio_communication.ReadThreadIsRunning())
986 m_stdio_communication.JoinReadThread();
987
988 if (m_stdio_communication.HasConnection())
989 m_stdio_communication.Disconnect();
990}
991
993 const void *src,
994 size_t src_len) {
995 auto *self = static_cast<NativeProcessWindows *>(baton);
996 if (src_len == 0)
997 return;
998 self->m_delegate.NewProcessOutput(
999 self, llvm::StringRef(static_cast<const char *>(src), src_len));
1000}
1001
1002size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
1003 Status &error) {
1004 if (!m_stdio_communication.HasConnection()) {
1006 "no ConPTY connection on this NativeProcessWindows");
1007 return 0;
1008 }
1009 ConnectionStatus status;
1010 size_t written = m_stdio_communication.Write(buf, len, status, &error);
1011 if (status != eConnectionStatusSuccess && error.Success())
1013 "ConPTY stdin write returned status {0}", static_cast<int>(status));
1014 return written;
1015}
1016} // 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)
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
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)
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
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
#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