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 if (!Host::GetProcessInfo(pid, info)) {
91 E = createStringError(inconvertibleErrorCode(),
92 "Cannot get process information");
93 return;
94 }
95 m_arch = info.GetArchitecture();
96}
97
101 llvm::sys::ScopedLock lock(m_mutex);
102
103 StateType state = GetState();
104 if (state == eStateStopped || state == eStateCrashed) {
105 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
106 GetDebuggedProcessId(), state);
107 LLDB_LOG(log, "resuming {0} threads.", m_threads.size());
108
110
111 bool failed = false;
112 for (uint32_t i = 0; i < m_threads.size(); ++i) {
113 auto thread = static_cast<NativeThreadWindows *>(m_threads[i].get());
114 const ResumeAction *const action =
115 resume_actions.GetActionForThread(thread->GetID(), true);
116 if (action == nullptr)
117 continue;
118
119 switch (action->state) {
120 case eStateRunning:
121 case eStateStepping: {
122 Status result = thread->DoResume(action->state);
123 if (result.Fail()) {
124 failed = true;
125 LLDB_LOG(log,
126 "Trying to resume thread at index {0}, but failed with "
127 "error {1}.",
128 i, result);
129 }
130 break;
131 }
132 case eStateSuspended:
133 case eStateStopped:
134 break;
135
136 default:
138 "NativeProcessWindows::%s (): unexpected state %s specified "
139 "for pid %" PRIu64 ", tid %" PRIu64,
140 __FUNCTION__, StateAsCString(action->state), GetID(),
141 thread->GetID());
142 }
143 }
144
145 if (failed) {
146 error = Status::FromErrorString("NativeProcessWindows::DoResume failed");
147 } else {
149 }
150
151 // Resume the debug loop.
152 ExceptionRecordSP active_exception =
153 m_session_data->m_debugger->GetActiveException().lock();
154 if (active_exception) {
155 // Resume the process and continue processing debug events. Mask the
156 // exception so that from the process's view, there is no indication that
157 // anything happened.
158 m_session_data->m_debugger->ContinueAsyncException(
160 }
161 } else {
162 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
164 }
165
166 return error;
167}
168
174
176 bool caused_stop = false;
177 StateType state = GetState();
178 if (state != eStateStopped) {
179 m_pending_halt = true;
180 Status err = HaltProcess(caused_stop);
181 if (err.Fail() || !caused_stop)
182 m_pending_halt = false;
183 return err;
184 }
185 return Status();
186}
187
191 StateType state = GetState();
192 if (state != eStateExited && state != eStateDetached) {
194 if (error.Success())
196 else
197 LLDB_LOG(log, "Detaching process error: {0}", error);
198 } else {
200 "error: process {0} in state = {1}, but "
201 "cannot detach it in this state.",
202 GetID(), state);
203 LLDB_LOG(log, "error: {0}", error);
204 }
205 return error;
206}
207
211 "Windows does not support sending signals to processes");
212 return error;
213}
214
216
218 StateType state = GetState();
219 return DestroyProcess(state);
220}
221
222Status NativeProcessWindows::IgnoreSignals(llvm::ArrayRef<int> signals) {
223 return Status();
224}
225
230
232 size_t size, size_t &bytes_read) {
233 return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
234}
235
237 size_t size, size_t &bytes_written) {
238 return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
239}
240
241llvm::Expected<lldb::addr_t>
242NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
243 lldb::addr_t addr;
244 Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
245 if (ST.Success())
246 return addr;
247 return ST.ToError();
248}
249
253
255
257 StateType state = GetState();
258 switch (state) {
259 case eStateCrashed:
260 case eStateDetached:
261 case eStateExited:
262 case eStateInvalid:
263 case eStateUnloaded:
264 return false;
265 default:
266 return true;
267 }
268}
269
271 lldb::StopReason reason,
272 std::string description) {
273 SetCurrentThreadID(thread.GetID());
274
275 ThreadStopInfo stop_info;
276 stop_info.reason = reason;
277 // No signal support on Windows but required to provide a 'valid' signum.
278 stop_info.signo = SIGTRAP;
279
280 if (reason == StopReason::eStopReasonException) {
281 stop_info.details.exception.type = 0;
282 stop_info.details.exception.data_count = 0;
283 }
284
285 thread.SetStopReason(stop_info, description);
286}
287
289 lldb::StopReason reason,
290 std::string description) {
291 NativeThreadWindows *thread = GetThreadByID(thread_id);
292 if (!thread)
293 return;
294
296 for (uint32_t i = 0; i < m_threads.size(); ++i) {
297 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
298 if (Status error = t->DoStop(); error.Fail())
299 LLDB_LOG(log, "failed to stop thread {0}: {1}", t->GetID(), error);
300 }
301 SetStopReasonForThread(*thread, reason, description);
302}
303
305
306llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
308 // Not available on this target.
309 return llvm::errc::not_supported;
310}
311
312llvm::Expected<llvm::ArrayRef<uint8_t>>
314 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e,
315 0xd4}; // brk #0xf000
316 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
317
318 switch (GetArchitecture().GetMachine()) {
319 case llvm::Triple::aarch64:
320 return llvm::ArrayRef(g_aarch64_opcode);
321
322 case llvm::Triple::arm:
323 case llvm::Triple::thumb:
324 return llvm::ArrayRef(g_thumb_opcode);
325
326 default:
328 }
329}
330
332 // Windows always reports an incremented PC after a breakpoint is hit,
333 // even on ARM.
334 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
335}
336
340
342 bool hardware) {
343 if (hardware)
344 return SetHardwareBreakpoint(addr, size);
345 return SetSoftwareBreakpoint(addr, size);
346}
347
349 bool hardware) {
350 if (hardware)
351 return RemoveHardwareBreakpoint(addr);
352 return RemoveSoftwareBreakpoint(addr);
353}
354
357 if (!m_loaded_modules.empty())
358 return Status();
359
360 // Retrieve loaded modules by a Target/Module-free implementation.
361 AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
362 if (snapshot.IsValid()) {
363 MODULEENTRY32W me;
364 me.dwSize = sizeof(MODULEENTRY32W);
365 if (Module32FirstW(snapshot.get(), &me)) {
366 do {
367 std::string path;
368 if (!llvm::convertWideToUTF8(me.szExePath, path))
369 continue;
370
371 FileSpec file_spec(path);
372 FileSystem::Instance().Resolve(file_spec);
373 m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr;
374 } while (Module32Next(snapshot.get(), &me));
375 }
376
377 if (!m_loaded_modules.empty())
378 return Status();
379 }
380
381 error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
382 return error;
383}
384
386 FileSpec &file_spec) {
388 if (error.Fail())
389 return error;
390
391 FileSpec module_file_spec(module_path);
392 FileSystem::Instance().Resolve(module_file_spec);
393 for (auto &it : m_loaded_modules) {
394 if (it.first == module_file_spec) {
395 file_spec = it.first;
396 return Status();
397 }
398 }
400 "Module (%s) not found in process %" PRIu64 "!",
401 module_file_spec.GetPath().c_str(), GetID());
402}
403
404Status
405NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
406 lldb::addr_t &load_addr) {
408 if (error.Fail())
409 return error;
410
411 load_addr = LLDB_INVALID_ADDRESS;
412 FileSpec file_spec(file_name);
413 FileSystem::Instance().Resolve(file_spec);
414 for (auto &it : m_loaded_modules) {
415 if (it.first == file_spec) {
416 load_addr = it.second;
417 return Status();
418 }
419 }
421 "Can't get loaded address of file (%s) in process %" PRIu64 "!",
422 file_spec.GetPath().c_str(), GetID());
423}
424
425llvm::Expected<std::vector<LoadedLibraryInfo>>
427 if (Status error = CacheLoadedModules(); error.Fail())
428 return error.ToError();
429
430 std::vector<LoadedLibraryInfo> libs;
431 libs.reserve(m_loaded_modules.size());
432 for (const auto &[file_spec, base] : m_loaded_modules) {
434 info.name = file_spec.GetPath();
435 info.base_addr = base;
436 libs.push_back(std::move(info));
437 }
438 return libs;
439}
440
444
445void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
447 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
448
449 // Closing the ConPTY signals EOF on the parent-side STDOUT pipe so the
450 // read thread can exit. Tear it down before the debuggee is destroyed.
452
454
455 // No signal involved. It is just an exit event.
456 WaitStatus wait_status(WaitStatus::Exit, exit_code);
457 SetExitStatus(wait_status, true);
458
459 // Notify the native delegate.
460 SetState(eStateExited, true);
461}
462
465 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
466 GetDebuggedProcessId(), image_base);
467
468 // This is the earliest chance we can resolve the process ID and
469 // architecture if we don't know them yet.
472
473 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
474 ProcessInstanceInfo process_info;
475 if (!Host::GetProcessInfo(GetDebuggedProcessId(), process_info)) {
476 LLDB_LOG(log, "Cannot get process information during debugger connecting "
477 "to process");
478 return;
479 }
480 SetArchitecture(process_info.GetArchitecture());
481 }
482
483 // The very first one shall always be the main thread.
484 assert(m_threads.empty());
485 m_threads.push_back(std::make_unique<NativeThreadWindows>(
486 *this, m_session_data->m_debugger->GetMainThread()));
487}
488
492 uint32_t wp_id = LLDB_INVALID_INDEX32;
493#ifndef __aarch64__
494 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
495 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
496 Status error =
497 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
498 if (error.Fail())
499 LLDB_LOG(log,
500 "received error while checking for watchpoint hits, pid = "
501 "{0}, error = {1}",
502 thread->GetID(), error);
503 if (wp_id != LLDB_INVALID_INDEX32) {
504 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
505 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
506 std::string desc =
507 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
509 }
510 }
511#endif
512 if (wp_id == LLDB_INVALID_INDEX32)
514
515 SetState(eStateStopped, true);
517}
518
522 const auto exception_addr = record.GetExceptionAddress();
523 const auto thread_id = record.GetThreadID();
524
525 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
526 auto &reg_ctx = stop_thread->GetRegisterContext();
527
528 if (FindSoftwareBreakpoint(exception_addr)) {
529 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
530 exception_addr);
532 // The current PC is AFTER the BP opcode, on all architectures.
533 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
534 SetState(eStateStopped, true);
536 }
537
538 // This block of code will only be entered in case of a hardware
539 // watchpoint or breakpoint hit on AArch64. However, we only handle
540 // hardware watchpoints below as breakpoints are not yet supported.
541 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
542 // Check that the ExceptionInformation array of EXCEPTION_RECORD
543 // contains at least two elements: the first is a read-write flag
544 // indicating the type of data access operation (read or write) while
545 // the second contains the virtual address of the accessed data.
546 if (args.size() >= 2) {
547 uint32_t hw_id = LLDB_INVALID_INDEX32;
548 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
549 if (error.Fail())
550 LLDB_LOG(log,
551 "received error while checking for watchpoint hits, pid = "
552 "{0}, error = {1}",
553 thread_id, error);
554
555 if (hw_id != LLDB_INVALID_INDEX32) {
556 std::string desc =
557 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
558 exception_addr)
559 .str();
561 SetState(eStateStopped, true);
563 }
564 }
565 }
566
567 if (!m_initial_stop_seen) {
568 m_initial_stop_seen = true;
569 LLDB_LOG(log,
570 "Hit loader breakpoint at address {0:x}, setting initial stop "
571 "event.",
572 exception_addr);
573
574 // We are required to report the reason for the first stop after
575 // launching or being attached.
576 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
578
579 // Do not notify the native delegate (e.g. llgs) since at this moment
580 // the program hasn't returned from Manager::Launch() and the delegate
581 // might not have an valid native process to operate on.
582 SetState(eStateStopped, false);
583
584 // Hit the initial stop. Continue the application.
586 }
587
588 // Any remaining STATUS_BREAKPOINT is a breakpoint instruction in the
589 // program's own code (e.g. `__debugbreak()` or `__builtin_debugtrap()`).
590 // Stop the debugger and let the user decide what to do.
591 if (m_pending_halt) {
592 LLDB_LOG(log,
593 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
594 "{0:x}",
595 thread_id);
596 m_pending_halt = false;
597 ThreadStopInfo signal_info;
599 signal_info.signo = 19; // SIGSTOP on POSIX
600
601 // Halt all threads at the kernel level.
602 for (uint32_t i = 0; i < m_threads.size(); ++i) {
603 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
604 if (Status err = t->DoStop(); err.Fail()) {
605 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
606 err.GetError());
607 exit(1);
608 }
609 }
610 SetCurrentThreadID(thread_id);
611 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
612 injected->SetStopReason(signal_info, "interrupt");
613 SetState(eStateStopped, true);
615 }
616
617 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
618 record.GetExceptionValue(), exception_addr)
619 .str();
620 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
621 SetState(eStateStopped, true);
623}
624
627 const ExceptionRecord &record) {
629 LLDB_LOG(log,
630 "Debugger thread reported exception {0:x} at address {1:x} "
631 "(first_chance={2})",
632 record.GetExceptionValue(), record.GetExceptionAddress(),
633 first_chance);
634
635 if (first_chance)
637
638 std::string desc;
639 llvm::raw_string_ostream desc_stream(desc);
640 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
641 << " encountered at address "
642 << llvm::format_hex(record.GetExceptionAddress(), 8);
643 record.Dump(desc_stream);
645 std::move(desc));
646
647 SetState(eStateStopped, true);
649}
650
653 const ExceptionRecord &record) {
654 llvm::sys::ScopedLock lock(m_mutex);
655
656 // Let the debugger establish the internal status.
657 ProcessDebugger::OnDebugException(first_chance, record);
658
659 switch (record.GetExceptionValue()) {
660 case DWORD(STATUS_SINGLE_STEP):
661 case STATUS_WX86_SINGLE_STEP:
662 return HandleSingleStepException(record);
663 case DWORD(STATUS_BREAKPOINT):
665 return HandleBreakpointException(record);
666 default:
667 return HandleGenericException(first_chance, record);
668 }
669}
670
672 llvm::sys::ScopedLock lock(m_mutex);
673
674 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
675 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
676 for (const auto &pair : GetWatchpointMap()) {
677 const NativeWatchpoint &wp = pair.second;
678 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
679 wp.m_hardware);
680 }
681
682 if (StateType state = GetState();
683 state == eStateStopped || state == eStateCrashed) {
684 if (Status error = thread->DoStop(); error.Fail()) {
686 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
687 thread->GetID(), error);
688 }
689 ThreadStopInfo stop_info;
690 stop_info.reason = lldb::eStopReasonNone;
691 thread->SetStopReason(stop_info, "");
692 }
693
694 m_threads.push_back(std::move(thread));
695}
696
698 uint32_t exit_code) {
699 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
700 llvm::erase_if(m_threads, [thread_id](const auto &t) {
701 return t->GetID() == thread_id;
702 });
703}
704
706 lldb::addr_t module_addr) {
707 m_loaded_modules.clear();
709}
710
715
717 bool is_unicode,
718 uint16_t length_lower_word) {
720
721 llvm::SmallVector<char, 256> buffer;
722 if (llvm::Error err = ProcessDebugger::ReadDebugString(
723 debug_string_addr, is_unicode, length_lower_word, buffer)) {
724 std::string err_str = llvm::toString(std::move(err));
725 std::string msg =
726 llvm::formatv("Failed to read debug string at {0:x} "
727 "(size & 0xffff={1}, unicode={2}): {3}\n",
728 debug_string_addr, length_lower_word, is_unicode, err_str)
729 .str();
730 LLDB_LOG(log, "{0}", msg);
731 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
732 return;
733 }
734 if (buffer.empty())
735 return;
736
737 if (is_unicode) {
738 assert(buffer.size() % 2 == 0);
739 llvm::ArrayRef<unsigned short> utf16(
740 reinterpret_cast<const unsigned short *>(buffer.data()),
741 buffer.size() / 2);
742 std::string out;
743 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
744 LLDB_LOG(log, "Debug string is not valid Utf 16");
745 return;
746 }
747 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
748 } else {
749 m_delegate.NewProcessOutput(this,
750 llvm::StringRef(buffer.data(), buffer.size()));
751 }
752}
753
754llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
756 ProcessLaunchInfo &launch_info,
757 NativeProcessProtocol::NativeDelegate &native_delegate) {
758 Error E = Error::success();
759 auto process_up = std::unique_ptr<NativeProcessWindows>(
760 new NativeProcessWindows(launch_info, native_delegate, E));
761 if (E)
762 return std::move(E);
763 return std::move(process_up);
764}
765
766llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
769 Error E = Error::success();
770 // Set pty primary fd invalid since it is not available.
771 auto process_up = std::unique_ptr<NativeProcessWindows>(
772 new NativeProcessWindows(pid, -1, native_delegate, E));
773 if (E)
774 return std::move(E);
775 return std::move(process_up);
776}
777
779
781 if (!m_pty || !m_pty->IsConnected())
782 return;
783
784 m_stdio_communication.SetConnection(
785 std::make_unique<ConnectionConPTY>(m_pty));
786 if (!m_stdio_communication.IsConnected())
787 return;
788 m_stdio_communication.SetReadThreadBytesReceivedCallback(
790 m_stdio_communication.StartReadThread();
791}
792
794 if (!m_stdio_communication.HasConnection())
795 return;
796
797 if (m_pty)
798 m_pty->Close();
799
800 if (m_stdio_communication.ReadThreadIsRunning())
801 m_stdio_communication.JoinReadThread();
802
803 if (m_stdio_communication.HasConnection())
804 m_stdio_communication.Disconnect();
805}
806
808 const void *src,
809 size_t src_len) {
810 auto *self = static_cast<NativeProcessWindows *>(baton);
811 if (src_len == 0)
812 return;
813 self->m_delegate.NewProcessOutput(
814 self, llvm::StringRef(static_cast<const char *>(src), src_len));
815}
816
817size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
818 Status &error) {
819 if (!m_stdio_communication.HasConnection()) {
821 "no ConPTY connection on this NativeProcessWindows");
822 return 0;
823 }
824 ConnectionStatus status;
825 size_t written = m_stdio_communication.Write(buf, len, status, &error);
826 if (status != eConnectionStatusSuccess && error.Success())
828 "ConPTY stdin write returned status {0}", static_cast<int>(status));
829 return written;
830}
831} // namespace lldb_private
static llvm::raw_ostream & error(Stream &strm)
#define STATUS_WX86_BREAKPOINT
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
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:374
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
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
void OnUnloadDll(lldb::addr_t module_addr) 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
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 OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) override
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)
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)
virtual void OnExitProcess(uint32_t exit_code)
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
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:327
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition ForwardDecl.h:35
std::shared_ptr< ExceptionRecord > ExceptionRecordSP
Definition ForwardDecl.h:37
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