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