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 <psapi.h>
13
15#include "NativeThreadWindows.h"
27#include "lldb/Target/Process.h"
28#include "lldb/Utility/State.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/Support/ConvertUTF.h"
31#include "llvm/Support/Errc.h"
32#include "llvm/Support/Error.h"
33#include "llvm/Support/Format.h"
34#include "llvm/Support/Threading.h"
35#include "llvm/Support/raw_ostream.h"
36
37#include "DebuggerThread.h"
38#include "ExceptionRecord.h"
39#include "ProcessWindowsLog.h"
40
41#include <tlhelp32.h>
42
43#pragma warning(disable : 4005)
44#include "winternl.h"
45#include <ntstatus.h>
46
47using namespace lldb;
48using namespace lldb_private;
49using namespace llvm;
50
51namespace lldb_private {
52
54 NativeDelegate &delegate,
55 llvm::Error &E)
58 PseudoTerminal::invalid_fd, // NativeProcessWindows owns the ConPTY.
59 delegate),
60 ProcessDebugger(), m_arch(launch_info.GetArchitecture()),
61 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
62 ErrorAsOutParameter EOut(&E);
63 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
64 E = LaunchProcess(launch_info, delegate_sp).ToError();
65 if (E)
66 return;
67
69
70 m_pty = launch_info.TakePTY();
72}
73
75 NativeDelegate &delegate,
76 llvm::Error &E)
77 : NativeProcessProtocol(pid, terminal_fd, delegate), ProcessDebugger(),
78 m_stdio_communication("lldb.NativeProcessWindows.stdio") {
79 ErrorAsOutParameter EOut(&E);
80 DebugDelegateSP delegate_sp(new NativeDebugDelegate(*this));
81 ProcessAttachInfo attach_info;
82 attach_info.SetProcessID(pid);
83 E = AttachProcess(pid, attach_info, delegate_sp).ToError();
84 if (E)
85 return;
86
88
90
92 if (!Host::GetProcessInfo(pid, info)) {
93 E = createStringError(inconvertibleErrorCode(),
94 "Cannot get process information");
95 return;
96 }
97 m_arch = info.GetArchitecture();
98}
99
103 llvm::sys::ScopedLock lock(m_mutex);
104
105 StateType state = GetState();
106 if (state == eStateStopped || state == eStateCrashed) {
107 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
108 GetDebuggedProcessId(), state);
109 LLDB_LOG(log, "resuming {0} threads.", m_threads.size());
110
112
113 bool failed = false;
114 for (uint32_t i = 0; i < m_threads.size(); ++i) {
115 auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get());
116 const ResumeAction *const action =
117 resume_actions.GetActionForThread(thread->GetID(), true);
118 if (action == nullptr)
119 continue;
120
121 switch (action->state) {
122 case eStateRunning:
123 case eStateStepping: {
124 Status result = thread->DoResume(action->state);
125 if (result.Fail()) {
126 failed = true;
127 LLDB_LOG(log,
128 "Trying to resume thread at index {0}, but failed with "
129 "error {1}.",
130 i, result);
131 }
132 break;
133 }
134 case eStateSuspended:
135 case eStateStopped:
136 break;
137
138 default:
140 "NativeProcessWindows::%s (): unexpected state %s specified "
141 "for pid %" PRIu64 ", tid %" PRIu64,
142 __FUNCTION__, StateAsCString(action->state), GetID(),
143 thread->GetID());
144 }
145 }
146
147 if (failed) {
148 error = Status::FromErrorString("NativeProcessWindows::DoResume failed");
149 } else {
151 }
152
153 // Resume the debug loop.
154 ExceptionRecordSP active_exception =
155 m_session_data->m_debugger->GetActiveException().lock();
156 if (active_exception) {
157 // Resume the process and continue processing debug events. Mask the
158 // exception so that from the process's view, there is no indication that
159 // anything happened.
160 m_session_data->m_debugger->ContinueAsyncException(
162 } else {
163 m_session_data->m_debugger->ContinueAsyncDllEvent();
164 }
165 } else {
166 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
168 }
169
170 return error;
171}
172
178
180 bool caused_stop = false;
181 StateType state = GetState();
182 if (state != eStateStopped) {
183 m_pending_halt = true;
184 Status err = HaltProcess(caused_stop);
185 if (err.Fail() || !caused_stop)
186 m_pending_halt = false;
187 return err;
188 }
189 return Status();
190}
191
195 StateType state = GetState();
196 if (state != eStateExited && state != eStateDetached) {
198 if (error.Success())
200 else
201 LLDB_LOG(log, "Detaching process error: {0}", error);
202 } else {
204 "error: process {0} in state = {1}, but "
205 "cannot detach it in this state.",
206 GetID(), state);
207 LLDB_LOG(log, "error: {0}", error);
208 }
209 return error;
210}
211
215 "Windows does not support sending signals to processes");
216 return error;
217}
218
220
222 StateType state = GetState();
223 return DestroyProcess(state);
224}
225
226Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) {
227 return Status();
228}
229
234
236 size_t size, size_t &bytes_read) {
237 return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
238}
239
241 size_t size, size_t &bytes_written) {
242 return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
243}
244
245llvm::Expected<lldb::addr_t>
246NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
247 lldb::addr_t addr;
248 Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
249 if (ST.Success())
250 return addr;
251 return ST.ToError();
252}
253
257
259
261 StateType state = GetState();
262 switch (state) {
263 case eStateCrashed:
264 case eStateDetached:
265 case eStateExited:
266 case eStateInvalid:
267 case eStateUnloaded:
268 return false;
269 default:
270 return true;
271 }
272}
273
275 lldb::StopReason reason,
276 std::string description) {
277 SetCurrentThreadID(thread.GetID());
278
279 ThreadStopInfo stop_info;
280 stop_info.reason = reason;
281 // No signal support on Windows but required to provide a 'valid' signum.
282 stop_info.signo = SIGTRAP;
283
284 if (reason == StopReason::eStopReasonException) {
285 stop_info.details.exception.type = 0;
286 stop_info.details.exception.data_count = 0;
287 }
288
289 thread.SetStopReason(stop_info, description);
290}
291
293 lldb::StopReason reason,
294 std::string description) {
295 NativeThreadWindows *thread = GetThreadByID(thread_id);
296 if (!thread)
297 return;
298
300 for (uint32_t i = 0; i < m_threads.size(); ++i) {
301 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
302 if (Status error = t->DoStop(); error.Fail())
303 LLDB_LOG(log, "failed to stop thread {0}: {1}", t->GetID(), error);
304 }
305 SetStopReasonForThread(*thread, reason, description);
306}
307
309
310llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
312 // Not available on this target.
313 return llvm::errc::not_supported;
314}
315
316llvm::Expected<llvm::ArrayRef<uint8_t>>
318 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e,
319 0xd4}; // brk #0xf000
320 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
321
322 switch (GetArchitecture().GetMachine()) {
323 case llvm::Triple::aarch64:
324 return llvm::ArrayRef(g_aarch64_opcode);
325
326 case llvm::Triple::arm:
327 case llvm::Triple::thumb:
328 return llvm::ArrayRef(g_thumb_opcode);
329
330 default:
332 }
333}
334
336 // Windows always reports an incremented PC after a breakpoint is hit,
337 // even on ARM.
338 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
339}
340
344
346 bool hardware) {
347 if (hardware)
348 return SetHardwareBreakpoint(addr, size);
349 return SetSoftwareBreakpoint(addr, size);
350}
351
353 bool hardware) {
354 if (hardware)
355 return RemoveHardwareBreakpoint(addr);
356 return RemoveSoftwareBreakpoint(addr);
357}
358
361 if (!m_loaded_modules.empty())
362 return Status();
363
364 // Retrieve loaded modules by a Target/Module-free implementation.
365 AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
366 if (snapshot.IsValid()) {
367 MODULEENTRY32W me;
368 me.dwSize = sizeof(MODULEENTRY32W);
369 if (Module32FirstW(snapshot.get(), &me)) {
370 do {
371 std::string path;
372 if (!llvm::convertWideToUTF8(me.szExePath, path))
373 continue;
374
375 FileSpec file_spec(path);
376 FileSystem::Instance().Resolve(file_spec);
377 m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr;
378 } while (Module32Next(snapshot.get(), &me));
379 }
380
381 if (!m_loaded_modules.empty())
382 return Status();
383 }
384
385 error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
386 return error;
387}
388
390 FileSpec &file_spec) {
392 if (error.Fail())
393 return error;
394
395 FileSpec module_file_spec(module_path);
396 FileSystem::Instance().Resolve(module_file_spec);
397 for (auto &it : m_loaded_modules) {
398 if (it.first == module_file_spec) {
399 file_spec = it.first;
400 return Status();
401 }
402 }
404 "Module (%s) not found in process %" PRIu64 "!",
405 module_file_spec.GetPath().c_str(), GetID());
406}
407
408Status
409NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
410 lldb::addr_t &load_addr) {
412 if (error.Fail())
413 return error;
414
415 load_addr = LLDB_INVALID_ADDRESS;
416 FileSpec file_spec(file_name);
417 FileSystem::Instance().Resolve(file_spec);
418 for (auto &it : m_loaded_modules) {
419 if (it.first == file_spec) {
420 load_addr = it.second;
421 return Status();
422 }
423 }
425 "Can't get loaded address of file (%s) in process %" PRIu64 "!",
426 file_spec.GetPath().c_str(), GetID());
427}
428
429llvm::Expected<std::vector<LoadedLibraryInfo>>
431 if (Status error = CacheLoadedModules(); error.Fail())
432 return error.ToError();
433
434 std::vector<LoadedLibraryInfo> libs;
435 libs.reserve(m_loaded_modules.size());
436 for (const auto &[file_spec, base] : m_loaded_modules) {
438 info.name = file_spec.GetPath();
439 info.base_addr = base;
440 libs.push_back(std::move(info));
441 }
442 return libs;
443}
444
448
449void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
451 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
452
453 // Closing the ConPTY signals EOF on the parent-side STDOUT pipe so the
454 // read thread can exit. Tear it down before the debuggee is destroyed.
456
458
459 // No signal involved. It is just an exit event.
460 WaitStatus wait_status(WaitStatus::Exit, exit_code);
461 SetExitStatus(wait_status, true);
462
463 // Notify the native delegate.
464 SetState(eStateExited, true);
465}
466
469 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
470 GetDebuggedProcessId(), image_base);
471
472 // This is the earliest chance we can resolve the process ID and
473 // architecture if we don't know them yet.
476
478 bool got_info = Host::GetProcessInfo(GetDebuggedProcessId(), info);
479
480 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
481 if (!got_info) {
482 LLDB_LOG(log, "Cannot get process information during debugger connecting "
483 "to process");
484 return;
485 }
487 }
488
489 if (got_info) {
490 FileSpec exe = info.GetExecutableFile();
491 if (exe) {
493 m_loaded_modules[exe] = image_base;
494 }
495 }
496
497 // The very first one shall always be the main thread.
498 assert(m_threads.empty());
499 m_threads.push_back(std::make_unique<NativeThreadWindows>(
500 *this, m_session_data->m_debugger->GetMainThread()));
501}
502
506 uint32_t wp_id = LLDB_INVALID_INDEX32;
507#ifndef __aarch64__
508 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
509 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
510 Status error =
511 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
512 if (error.Fail())
513 LLDB_LOG(log,
514 "received error while checking for watchpoint hits, pid = "
515 "{0}, error = {1}",
516 thread->GetID(), error);
517 if (wp_id != LLDB_INVALID_INDEX32) {
518 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
519 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
520 std::string desc =
521 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
523 }
524 }
525#endif
526 if (wp_id == LLDB_INVALID_INDEX32)
528
529 SetState(eStateStopped, true);
531}
532
536 const auto exception_addr = record.GetExceptionAddress();
537 const auto thread_id = record.GetThreadID();
538
539 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
540 auto &reg_ctx = stop_thread->GetRegisterContext();
541
542 if (FindSoftwareBreakpoint(exception_addr)) {
543 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
544 exception_addr);
546 // The current PC is AFTER the BP opcode, on all architectures.
547 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
548 SetState(eStateStopped, true);
550 }
551
552 // This block of code will only be entered in case of a hardware
553 // watchpoint or breakpoint hit on AArch64. However, we only handle
554 // hardware watchpoints below as breakpoints are not yet supported.
555 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
556 // Check that the ExceptionInformation array of EXCEPTION_RECORD
557 // contains at least two elements: the first is a read-write flag
558 // indicating the type of data access operation (read or write) while
559 // the second contains the virtual address of the accessed data.
560 if (args.size() >= 2) {
561 uint32_t hw_id = LLDB_INVALID_INDEX32;
562 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
563 if (error.Fail())
564 LLDB_LOG(log,
565 "received error while checking for watchpoint hits, pid = "
566 "{0}, error = {1}",
567 thread_id, error);
568
569 if (hw_id != LLDB_INVALID_INDEX32) {
570 std::string desc =
571 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
572 exception_addr)
573 .str();
575 SetState(eStateStopped, true);
577 }
578 }
579 }
580
581 if (!m_initial_stop_seen) {
582 m_initial_stop_seen = true;
583 LLDB_LOG(log,
584 "Hit loader breakpoint at address {0:x}, setting initial stop "
585 "event.",
586 exception_addr);
587
588 // We are required to report the reason for the first stop after
589 // launching or being attached.
590 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
592
593 // Do not notify the native delegate (e.g. llgs) since at this moment
594 // the program hasn't returned from Manager::Launch() and the delegate
595 // might not have an valid native process to operate on.
596 SetState(eStateStopped, false);
597
598 // Hit the initial stop. Continue the application.
600 }
601
602 // Our own DebugBreakProcess() injection, used to implement
603 // Halt()/Interrupt().
604 if (m_pending_halt) {
605 LLDB_LOG(log,
606 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
607 "{0:x}",
608 thread_id);
609 m_pending_halt = false;
610 ThreadStopInfo signal_info;
612 signal_info.signo = 19; // SIGSTOP on POSIX
613
614 // Halt all threads at the kernel level.
615 for (uint32_t i = 0; i < m_threads.size(); ++i) {
616 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
617 if (Status err = t->DoStop(); err.Fail()) {
618 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
619 err.GetError());
620 exit(1);
621 }
622 }
623 SetCurrentThreadID(thread_id);
624 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
625 injected->SetStopReason(signal_info, "interrupt");
626 SetState(eStateStopped, true);
628 }
629
630 if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
632 LLDB_LOG(log,
633 "Skipping expected loader breakpoint at address {0:x} in a "
634 "system module.",
635 exception_addr);
637 }
638
639 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
640 record.GetExceptionValue(), exception_addr)
641 .str();
642 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
643 SetState(eStateStopped, true);
645}
646
649 const ExceptionRecord &record) {
651 LLDB_LOG(log,
652 "Debugger thread reported exception {0:x} at address {1:x} "
653 "(first_chance={2})",
654 record.GetExceptionValue(), record.GetExceptionAddress(),
655 first_chance);
656
657 if (first_chance)
659
660 std::string desc;
661 llvm::raw_string_ostream desc_stream(desc);
662 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
663 << " encountered at address "
664 << llvm::format_hex(record.GetExceptionAddress(), 8);
665 record.Dump(desc_stream);
667 std::move(desc));
668
669 SetState(eStateStopped, true);
671}
672
675 const ExceptionRecord &record) {
676 llvm::sys::ScopedLock lock(m_mutex);
677
678 // Handle the exception first to keep track of the stop reason.
679 ExceptionResult result;
680 switch (record.GetExceptionValue()) {
681 case DWORD(STATUS_SINGLE_STEP):
682 case STATUS_WX86_SINGLE_STEP:
683 result = HandleSingleStepException(record);
684 break;
685 case DWORD(STATUS_BREAKPOINT):
687 result = HandleBreakpointException(record);
688 break;
689 default:
690 result = HandleGenericException(first_chance, record);
691 break;
692 }
693
694 // Let the debugger establish the internal status.
695 ProcessDebugger::OnDebugException(first_chance, record);
696
697 return result;
698}
699
701 llvm::sys::ScopedLock lock(m_mutex);
702
703 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
704 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
705 for (const auto &pair : GetWatchpointMap()) {
706 const NativeWatchpoint &wp = pair.second;
707 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
708 wp.m_hardware);
709 }
710
711 if (StateType state = GetState();
712 state == eStateStopped || state == eStateCrashed) {
713 if (Status error = thread->DoStop(); error.Fail()) {
715 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
716 thread->GetID(), error);
717 }
718 ThreadStopInfo stop_info;
719 stop_info.reason = lldb::eStopReasonNone;
720 thread->SetStopReason(stop_info, "");
721 }
722
723 m_threads.push_back(std::move(thread));
724}
725
727 uint32_t exit_code) {
728 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
729 llvm::erase_if(m_threads, [thread_id](const auto &t) {
730 return t->GetID() == thread_id;
731 });
732}
733
735 lldb::addr_t module_addr,
736 lldb::tid_t thread_id) {
738 llvm::sys::ScopedLock lock(m_mutex);
739
740 FileSpec resolved = module_spec.GetFileSpec();
741 if (resolved) {
742 FileSystem::Instance().Resolve(resolved);
743 m_loaded_modules[resolved] = module_addr;
744 }
746
749
750 // Can't resolve a breakpoint in a system DLL.
751 if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
753
754 NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
755 if (!loader_thread && !m_threads.empty()) {
756 LLDB_LOG(log, "LOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
757 thread_id);
758 loader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
759 }
760 if (loader_thread) {
761 SetCurrentThreadID(loader_thread->GetID());
762 if (loader_thread->DoStop().Fail())
763 LLDB_LOG(log, "Failed to suspend thread {0} on LOAD_DLL.",
764 loader_thread->GetID());
765 ThreadStopInfo info;
767 info.signo = 0;
768 loader_thread->SetStopReason(info, "");
769 }
770 SetState(eStateStopped, true);
771
773}
774
776 lldb::tid_t thread_id) {
778 llvm::sys::ScopedLock lock(m_mutex);
779
780 FileSpec unloaded_spec;
781 for (auto it = m_loaded_modules.begin(); it != m_loaded_modules.end();) {
782 if (it->second == module_addr) {
783 unloaded_spec = it->first;
784 it = m_loaded_modules.erase(it);
785 } else {
786 ++it;
787 }
788 }
790
793
794 if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
796
797 NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
798 if (!unloader_thread && !m_threads.empty()) {
799 LLDB_LOG(log,
800 "UNLOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
801 thread_id);
802 unloader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
803 }
804 if (unloader_thread) {
805 SetCurrentThreadID(unloader_thread->GetID());
806 if (unloader_thread->DoStop().Fail())
807 LLDB_LOG(log, "Failed to suspend thread {0} on UNLOAD_DLL.",
808 unloader_thread->GetID());
809 ThreadStopInfo info;
811 info.signo = 0;
812 unloader_thread->SetStopReason(info, "");
813 }
814 SetState(eStateStopped, true);
816}
817
819 bool is_unicode,
820 uint16_t length_lower_word) {
822
823 llvm::SmallVector<char, 256> buffer;
824 if (llvm::Error err = ProcessDebugger::ReadDebugString(
825 debug_string_addr, is_unicode, length_lower_word, buffer)) {
826 std::string err_str = llvm::toString(std::move(err));
827 std::string msg =
828 llvm::formatv("Failed to read debug string at {0:x} "
829 "(size & 0xffff={1}, unicode={2}): {3}\n",
830 debug_string_addr, length_lower_word, is_unicode, err_str)
831 .str();
832 LLDB_LOG(log, "{0}", msg);
833 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
834 return;
835 }
836 if (buffer.empty())
837 return;
838
839 if (is_unicode) {
840 assert(buffer.size() % 2 == 0);
841 llvm::ArrayRef<unsigned short> utf16(
842 reinterpret_cast<const unsigned short *>(buffer.data()),
843 buffer.size() / 2);
844 std::string out;
845 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
846 LLDB_LOG(log, "Debug string is not valid Utf 16");
847 return;
848 }
849 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
850 } else {
851 m_delegate.NewProcessOutput(this,
852 llvm::StringRef(buffer.data(), buffer.size()));
853 }
854}
855
856llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
858 ProcessLaunchInfo &launch_info,
859 NativeProcessProtocol::NativeDelegate &native_delegate) {
860 Error E = Error::success();
861 auto process_up = std::unique_ptr<NativeProcessWindows>(
862 new NativeProcessWindows(launch_info, native_delegate, E));
863 if (E)
864 return std::move(E);
865 return std::move(process_up);
866}
867
868llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
871 Error E = Error::success();
872 // Set pty primary fd invalid since it is not available.
873 auto process_up = std::unique_ptr<NativeProcessWindows>(
874 new NativeProcessWindows(pid, -1, native_delegate, E));
875 if (E)
876 return std::move(E);
877 return std::move(process_up);
878}
879
881
883 if (!m_pty || !m_pty->IsConnected())
884 return;
885
886 m_stdio_communication.SetConnection(
887 std::make_unique<ConnectionConPTY>(m_pty));
888 if (!m_stdio_communication.IsConnected())
889 return;
890 m_stdio_communication.SetReadThreadBytesReceivedCallback(
892 m_stdio_communication.StartReadThread();
893}
894
896 if (!m_stdio_communication.HasConnection())
897 return;
898
899 if (m_pty)
900 m_pty->Close();
901
902 if (m_stdio_communication.ReadThreadIsRunning())
903 m_stdio_communication.JoinReadThread();
904
905 if (m_stdio_communication.HasConnection())
906 m_stdio_communication.Disconnect();
907}
908
910 const void *src,
911 size_t src_len) {
912 auto *self = static_cast<NativeProcessWindows *>(baton);
913 if (src_len == 0)
914 return;
915 self->m_delegate.NewProcessOutput(
916 self, llvm::StringRef(static_cast<const char *>(src), src_len));
917}
918
919size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
920 Status &error) {
921 if (!m_stdio_communication.HasConnection()) {
923 "no ConPTY connection on this NativeProcessWindows");
924 return 0;
925 }
926 ConnectionStatus status;
927 size_t written = m_stdio_communication.Write(buf, len, status, &error);
928 if (status != eConnectionStatusSuccess && error.Success())
930 "ConPTY stdin write returned status {0}", static_cast<int>(status));
931 return written;
932}
933} // 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
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:57
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
Definition FileSpec.cpp:376
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)
virtual llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint)
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr)
std::unordered_map< lldb::addr_t, SoftwareBreakpoint > m_software_breakpoints
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
Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) 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...
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
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)
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override
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
std::map< lldb_private::FileSpec, lldb::addr_t > m_loaded_modules
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)
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
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:83
uint64_t addr_t
Definition lldb-types.h:80
StopReason
Thread stop reasons.
@ eStopReasonBreakpoint
@ eStopReasonException
@ eStopReasonWatchpoint
uint64_t tid_t
Definition lldb-types.h:84
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