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();
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 void *buf, size_t size,
237 size_t &bytes_read) {
238 lldb::addr_t addr = process_addr.GetValue();
239 return ProcessDebugger::ReadMemory(addr, buf, size, bytes_read);
240}
241
243 size_t size, size_t &bytes_written) {
244 return ProcessDebugger::WriteMemory(addr, buf, size, bytes_written);
245}
246
247llvm::Expected<lldb::addr_t>
248NativeProcessWindows::AllocateMemory(size_t size, uint32_t permissions) {
249 lldb::addr_t addr;
250 Status ST = ProcessDebugger::AllocateMemory(size, permissions, addr);
251 if (ST.Success())
252 return addr;
253 return ST.ToError();
254}
255
259
261
263 StateType state = GetState();
264 switch (state) {
265 case eStateCrashed:
266 case eStateDetached:
267 case eStateExited:
268 case eStateInvalid:
269 case eStateUnloaded:
270 return false;
271 default:
272 return true;
273 }
274}
275
277 lldb::StopReason reason,
278 std::string description) {
279 SetCurrentThreadID(thread.GetID());
280
281 ThreadStopInfo stop_info;
282 stop_info.reason = reason;
283 // No signal support on Windows but required to provide a 'valid' signum.
284 stop_info.signo = SIGTRAP;
285
286 if (reason == StopReason::eStopReasonException) {
287 stop_info.details.exception.type = 0;
288 stop_info.details.exception.data_count = 0;
289 }
290
291 thread.SetStopReason(stop_info, description);
292}
293
295 lldb::StopReason reason,
296 std::string description) {
297 NativeThreadWindows *thread = GetThreadByID(thread_id);
298 if (!thread)
299 return;
300
302 for (uint32_t i = 0; i < m_threads.size(); ++i) {
303 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
304 if (Status error = t->DoStop(); error.Fail())
305 LLDB_LOG(log, "failed to stop thread {0}: {1}", t->GetID(), error);
306 }
307 SetStopReasonForThread(*thread, reason, description);
308}
309
311
312llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
314 // Not available on this target.
315 return llvm::errc::not_supported;
316}
317
318llvm::Expected<llvm::ArrayRef<uint8_t>>
320 static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x3e,
321 0xd4}; // brk #0xf000
322 static const uint8_t g_thumb_opcode[] = {0xfe, 0xde}; // udf #0xfe
323
324 switch (GetArchitecture().GetMachine()) {
325 case llvm::Triple::aarch64:
326 return llvm::ArrayRef(g_aarch64_opcode);
327
328 case llvm::Triple::arm:
329 case llvm::Triple::thumb:
330 return llvm::ArrayRef(g_thumb_opcode);
331
332 default:
334 }
335}
336
338 // Windows always reports an incremented PC after a breakpoint is hit,
339 // even on ARM.
340 return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
341}
342
346
348 bool hardware) {
349 if (hardware)
350 return SetHardwareBreakpoint(addr, size);
351 return SetSoftwareBreakpoint(addr, size);
352}
353
355 bool hardware) {
356 if (hardware)
357 return RemoveHardwareBreakpoint(addr);
358 return RemoveSoftwareBreakpoint(addr);
359}
360
363 if (!m_loaded_modules.empty())
364 return Status();
365
366 // Retrieve loaded modules by a Target/Module-free implementation.
367 AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetID()));
368 if (snapshot.IsValid()) {
369 MODULEENTRY32W me;
370 me.dwSize = sizeof(MODULEENTRY32W);
371 if (Module32FirstW(snapshot.get(), &me)) {
372 do {
373 std::string path;
374 if (!llvm::convertWideToUTF8(me.szExePath, path))
375 continue;
376
377 FileSpec file_spec(path);
378 FileSystem::Instance().Resolve(file_spec);
379 m_loaded_modules[file_spec] = (addr_t)me.modBaseAddr;
380 } while (Module32Next(snapshot.get(), &me));
381 }
382
383 if (!m_loaded_modules.empty())
384 return Status();
385 }
386
387 error = Status(::GetLastError(), lldb::ErrorType::eErrorTypeWin32);
388 return error;
389}
390
392 FileSpec &file_spec) {
394 if (error.Fail())
395 return error;
396
397 FileSpec module_file_spec(module_path);
398 FileSystem::Instance().Resolve(module_file_spec);
399 for (auto &it : m_loaded_modules) {
400 if (it.first == module_file_spec) {
401 file_spec = it.first;
402 return Status();
403 }
404 }
406 "Module (%s) not found in process %" PRIu64 "!",
407 module_file_spec.GetPath().c_str(), GetID());
408}
409
410Status
411NativeProcessWindows::GetFileLoadAddress(const llvm::StringRef &file_name,
412 lldb::addr_t &load_addr) {
414 if (error.Fail())
415 return error;
416
417 load_addr = LLDB_INVALID_ADDRESS;
418 FileSpec file_spec(file_name);
419 FileSystem::Instance().Resolve(file_spec);
420 for (auto &it : m_loaded_modules) {
421 if (it.first == file_spec) {
422 load_addr = it.second;
423 return Status();
424 }
425 }
427 "Can't get loaded address of file (%s) in process %" PRIu64 "!",
428 file_spec.GetPath().c_str(), GetID());
429}
430
431llvm::Expected<std::vector<LoadedLibraryInfo>>
433 if (Status error = CacheLoadedModules(); error.Fail())
434 return error.ToError();
435
436 std::vector<LoadedLibraryInfo> libs;
437 libs.reserve(m_loaded_modules.size());
438 for (const auto &[file_spec, base] : m_loaded_modules) {
440 info.name = file_spec.GetPath();
441 info.base_addr = base;
442 libs.push_back(std::move(info));
443 }
444 return libs;
445}
446
450
451void NativeProcessWindows::OnExitProcess(uint32_t exit_code) {
453 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
454
455 // Closing the ConPTY signals EOF on the parent-side STDOUT pipe so the
456 // read thread can exit. Tear it down before the debuggee is destroyed.
458
460
461 // No signal involved. It is just an exit event.
462 WaitStatus wait_status(WaitStatus::Exit, exit_code);
463 SetExitStatus(wait_status, true);
464
465 // Notify the native delegate.
466 SetState(eStateExited, true);
467}
468
471 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
472 GetDebuggedProcessId(), image_base);
473
474 // This is the earliest chance we can resolve the process ID and
475 // architecture if we don't know them yet.
478
480 bool got_info = Host::GetProcessInfo(GetDebuggedProcessId(), info);
481
482 if (GetArchitecture().GetMachine() == llvm::Triple::UnknownArch) {
483 if (!got_info) {
484 LLDB_LOG(log, "Cannot get process information during debugger connecting "
485 "to process");
486 return;
487 }
489 }
490
491 if (got_info) {
492 FileSpec exe = info.GetExecutableFile();
493 if (exe) {
495 m_loaded_modules[exe] = image_base;
496 }
497 }
498
499 // The very first one shall always be the main thread.
500 assert(m_threads.empty());
501 m_threads.push_back(std::make_unique<NativeThreadWindows>(
502 *this, m_session_data->m_debugger->GetMainThread()));
503}
504
508 uint32_t wp_id = LLDB_INVALID_INDEX32;
509#ifndef __aarch64__
510 if (NativeThreadWindows *thread = GetThreadByID(record.GetThreadID())) {
511 NativeRegisterContextWindows &reg_ctx = thread->GetRegisterContext();
512 Status error =
513 reg_ctx.GetWatchpointHitIndex(wp_id, record.GetExceptionAddress());
514 if (error.Fail())
515 LLDB_LOG(log,
516 "received error while checking for watchpoint hits, pid = "
517 "{0}, error = {1}",
518 thread->GetID(), error);
519 if (wp_id != LLDB_INVALID_INDEX32) {
520 addr_t wp_addr = reg_ctx.GetWatchpointAddress(wp_id);
521 addr_t wp_hit_addr = reg_ctx.GetWatchpointHitAddress(wp_id);
522 std::string desc =
523 formatv("{0} {1} {2}", wp_addr, wp_id, wp_hit_addr).str();
525 }
526 }
527#endif
528 if (wp_id == LLDB_INVALID_INDEX32)
530
531 SetState(eStateStopped, true);
533}
534
538 const auto exception_addr = record.GetExceptionAddress();
539 const auto thread_id = record.GetThreadID();
540
541 if (NativeThreadWindows *stop_thread = GetThreadByID(thread_id)) {
542 auto &reg_ctx = stop_thread->GetRegisterContext();
543
544 if (FindSoftwareBreakpoint(exception_addr)) {
545 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
546 exception_addr);
548 // The current PC is AFTER the BP opcode, on all architectures.
549 reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
550 SetState(eStateStopped, true);
552 }
553
554 // This block of code will only be entered in case of a hardware
555 // watchpoint or breakpoint hit on AArch64. However, we only handle
556 // hardware watchpoints below as breakpoints are not yet supported.
557 const ArrayRef<uint64_t> args = record.GetExceptionArguments();
558 // Check that the ExceptionInformation array of EXCEPTION_RECORD
559 // contains at least two elements: the first is a read-write flag
560 // indicating the type of data access operation (read or write) while
561 // the second contains the virtual address of the accessed data.
562 if (args.size() >= 2) {
563 uint32_t hw_id = LLDB_INVALID_INDEX32;
564 Status error = reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
565 if (error.Fail())
566 LLDB_LOG(log,
567 "received error while checking for watchpoint hits, pid = "
568 "{0}, error = {1}",
569 thread_id, error);
570
571 if (hw_id != LLDB_INVALID_INDEX32) {
572 std::string desc =
573 formatv("{0} {1} {2}", reg_ctx.GetWatchpointAddress(hw_id), hw_id,
574 exception_addr)
575 .str();
577 SetState(eStateStopped, true);
579 }
580 }
581 }
582
583 if (!m_initial_stop_seen) {
584 m_initial_stop_seen = true;
585 LLDB_LOG(log,
586 "Hit loader breakpoint at address {0:x}, setting initial stop "
587 "event.",
588 exception_addr);
589
590 // We are required to report the reason for the first stop after
591 // launching or being attached.
592 if (NativeThreadWindows *thread = GetThreadByID(thread_id))
594
595 // Do not notify the native delegate (e.g. llgs) since at this moment
596 // the program hasn't returned from Manager::Launch() and the delegate
597 // might not have an valid native process to operate on.
598 SetState(eStateStopped, false);
599
600 // Hit the initial stop. Continue the application.
602 }
603
604 // Our own DebugBreakProcess() injection, used to implement
605 // Halt()/Interrupt().
606 if (m_pending_halt) {
607 LLDB_LOG(log,
608 "DebugBreakProcess injection treated as Halt SIGSTOP for tid "
609 "{0:x}",
610 thread_id);
611 m_pending_halt = false;
612 ThreadStopInfo signal_info;
614 signal_info.signo = 19; // SIGSTOP on POSIX
615
616 // Halt all threads at the kernel level.
617 for (uint32_t i = 0; i < m_threads.size(); ++i) {
618 auto t = static_cast<NativeThreadWindows *>(m_threads[i].get());
619 if (Status err = t->DoStop(); err.Fail()) {
620 LLDB_LOG(log, "Failed to stop thread {1:x}: {0}", t->GetID(),
621 err.GetError());
622 exit(1);
623 }
624 }
625 SetCurrentThreadID(thread_id);
626 if (NativeThreadWindows *injected = GetThreadByID(thread_id))
627 injected->SetStopReason(signal_info, "interrupt");
628 SetState(eStateStopped, true);
630 }
631
632 if (m_expecting_loader_int3 && IsSystemModuleAddress(exception_addr)) {
634 LLDB_LOG(log,
635 "Skipping expected loader breakpoint at address {0:x} in a "
636 "system module.",
637 exception_addr);
639 }
640
641 std::string desc = formatv("Exception {0:x8} encountered at address {1:x8}",
642 record.GetExceptionValue(), exception_addr)
643 .str();
644 StopThread(thread_id, StopReason::eStopReasonException, std::move(desc));
645 SetState(eStateStopped, true);
647}
648
651 const ExceptionRecord &record) {
653 LLDB_LOG(log,
654 "Debugger thread reported exception {0:x} at address {1:x} "
655 "(first_chance={2})",
656 record.GetExceptionValue(), record.GetExceptionAddress(),
657 first_chance);
658
659 if (first_chance)
661
662 std::string desc;
663 llvm::raw_string_ostream desc_stream(desc);
664 desc_stream << "Exception " << llvm::format_hex(record.GetExceptionValue(), 8)
665 << " encountered at address "
666 << llvm::format_hex(record.GetExceptionAddress(), 8);
667 record.Dump(desc_stream);
669 std::move(desc));
670
671 SetState(eStateStopped, true);
673}
674
677 const ExceptionRecord &record) {
678 llvm::sys::ScopedLock lock(m_mutex);
679
680 // Handle the exception first to keep track of the stop reason.
681 ExceptionResult result;
682 switch (record.GetExceptionValue()) {
683 case DWORD(STATUS_SINGLE_STEP):
684 case STATUS_WX86_SINGLE_STEP:
685 result = HandleSingleStepException(record);
686 break;
687 case DWORD(STATUS_BREAKPOINT):
689 result = HandleBreakpointException(record);
690 break;
691 default:
692 result = HandleGenericException(first_chance, record);
693 break;
694 }
695
696 // Let the debugger establish the internal status.
697 ProcessDebugger::OnDebugException(first_chance, record);
698
699 return result;
700}
701
703 llvm::sys::ScopedLock lock(m_mutex);
704
705 auto thread = std::make_unique<NativeThreadWindows>(*this, new_thread);
706 thread->GetRegisterContext().ClearAllHardwareWatchpoints();
707 for (const auto &pair : GetWatchpointMap()) {
708 const NativeWatchpoint &wp = pair.second;
709 thread->SetWatchpoint(wp.m_addr, wp.m_size, wp.m_watch_flags,
710 wp.m_hardware);
711 }
712
713 if (StateType state = GetState();
714 state == eStateStopped || state == eStateCrashed) {
715 if (Status error = thread->DoStop(); error.Fail()) {
717 LLDB_LOG(log, "failed to suspend newly-created thread {0}: {1}",
718 thread->GetID(), error);
719 }
720 ThreadStopInfo stop_info;
721 stop_info.reason = lldb::eStopReasonNone;
722 thread->SetStopReason(stop_info, "");
723 }
724
725 m_threads.push_back(std::move(thread));
726}
727
729 uint32_t exit_code) {
730 std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
731 llvm::erase_if(m_threads, [thread_id](const auto &t) {
732 return t->GetID() == thread_id;
733 });
734}
735
737 lldb::addr_t module_addr,
738 lldb::tid_t thread_id) {
740 llvm::sys::ScopedLock lock(m_mutex);
741
742 FileSpec resolved = module_spec.GetFileSpec();
743 if (resolved) {
744 FileSystem::Instance().Resolve(resolved);
745 m_loaded_modules[resolved] = module_addr;
746 }
748
751
752 // Can't resolve a breakpoint in a system DLL.
753 if (!resolved || ProcessDebugger::IsSystemDLL(resolved.GetPath()))
755
756 NativeThreadWindows *loader_thread = GetThreadByID(thread_id);
757 if (!loader_thread && !m_threads.empty()) {
758 LLDB_LOG(log, "LOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
759 thread_id);
760 loader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
761 }
762 if (loader_thread) {
763 SetCurrentThreadID(loader_thread->GetID());
764 if (loader_thread->DoStop().Fail())
765 LLDB_LOG(log, "Failed to suspend thread {0} on LOAD_DLL.",
766 loader_thread->GetID());
767 ThreadStopInfo info;
769 info.signo = 0;
770 loader_thread->SetStopReason(info, "");
771 }
772 SetState(eStateStopped, true);
773
775}
776
778 lldb::tid_t thread_id) {
780 llvm::sys::ScopedLock lock(m_mutex);
781
782 FileSpec unloaded_spec;
783 for (auto it = m_loaded_modules.begin(); it != m_loaded_modules.end();) {
784 if (it->second == module_addr) {
785 unloaded_spec = it->first;
786 it = m_loaded_modules.erase(it);
787 } else {
788 ++it;
789 }
790 }
792
795
796 if (!unloaded_spec || ProcessDebugger::IsSystemDLL(unloaded_spec.GetPath()))
798
799 NativeThreadWindows *unloader_thread = GetThreadByID(thread_id);
800 if (!unloader_thread && !m_threads.empty()) {
801 LLDB_LOG(log,
802 "UNLOAD_DLL on unknown tid {0:x}. Falling back to main thread.",
803 thread_id);
804 unloader_thread = static_cast<NativeThreadWindows *>(m_threads[0].get());
805 }
806 if (unloader_thread) {
807 SetCurrentThreadID(unloader_thread->GetID());
808 if (unloader_thread->DoStop().Fail())
809 LLDB_LOG(log, "Failed to suspend thread {0} on UNLOAD_DLL.",
810 unloader_thread->GetID());
811 ThreadStopInfo info;
813 info.signo = 0;
814 unloader_thread->SetStopReason(info, "");
815 }
816 SetState(eStateStopped, true);
818}
819
821 bool is_unicode,
822 uint16_t length_lower_word) {
824
825 llvm::SmallVector<char, 256> buffer;
826 if (llvm::Error err = ProcessDebugger::ReadDebugString(
827 debug_string_addr, is_unicode, length_lower_word, buffer)) {
828 std::string err_str = llvm::toString(std::move(err));
829 std::string msg =
830 llvm::formatv("Failed to read debug string at {0:x} "
831 "(size & 0xffff={1}, unicode={2}): {3}\n",
832 debug_string_addr, length_lower_word, is_unicode, err_str)
833 .str();
834 LLDB_LOG(log, "{0}", msg);
835 m_delegate.NewProcessOutput(this, llvm::StringRef(msg));
836 return;
837 }
838 if (buffer.empty())
839 return;
840
841 if (is_unicode) {
842 assert(buffer.size() % 2 == 0);
843 llvm::ArrayRef<unsigned short> utf16(
844 reinterpret_cast<const unsigned short *>(buffer.data()),
845 buffer.size() / 2);
846 std::string out;
847 if (!llvm::convertUTF16ToUTF8String(utf16, out)) {
848 LLDB_LOG(log, "Debug string is not valid Utf 16");
849 return;
850 }
851 m_delegate.NewProcessOutput(this, llvm::StringRef(out.data(), out.size()));
852 } else {
853 m_delegate.NewProcessOutput(this,
854 llvm::StringRef(buffer.data(), buffer.size()));
855 }
856}
857
858llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
860 ProcessLaunchInfo &launch_info,
861 NativeProcessProtocol::NativeDelegate &native_delegate) {
862 Error E = Error::success();
863 auto process_up = std::unique_ptr<NativeProcessWindows>(
864 new NativeProcessWindows(launch_info, native_delegate, E));
865 if (E)
866 return std::move(E);
867 return std::move(process_up);
868}
869
870llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
873 Error E = Error::success();
874 // Set pty primary fd invalid since it is not available.
875 auto process_up = std::unique_ptr<NativeProcessWindows>(
876 new NativeProcessWindows(pid, -1, native_delegate, E));
877 if (E)
878 return std::move(E);
879 return std::move(process_up);
880}
881
883
885 if (!m_pty || !m_pty->IsConnected())
886 return;
887
888 m_stdio_communication.SetConnection(
889 std::make_unique<ConnectionConPTY>(m_pty));
890 if (!m_stdio_communication.IsConnected())
891 return;
892 m_stdio_communication.SetReadThreadBytesReceivedCallback(
894 m_stdio_communication.StartReadThread();
895}
896
898 if (!m_stdio_communication.HasConnection())
899 return;
900
901 if (m_pty)
902 m_pty->Close();
903
904 if (m_stdio_communication.ReadThreadIsRunning())
905 m_stdio_communication.JoinReadThread();
906
907 if (m_stdio_communication.HasConnection())
908 m_stdio_communication.Disconnect();
909}
910
912 const void *src,
913 size_t src_len) {
914 auto *self = static_cast<NativeProcessWindows *>(baton);
915 if (src_len == 0)
916 return;
917 self->m_delegate.NewProcessOutput(
918 self, llvm::StringRef(static_cast<const char *>(src), src_len));
919}
920
921size_t NativeProcessWindows::WriteStdin(const void *buf, size_t len,
922 Status &error) {
923 if (!m_stdio_communication.HasConnection()) {
925 "no ConPTY connection on this NativeProcessWindows");
926 return 0;
927 }
928 ConnectionStatus status;
929 size_t written = m_stdio_communication.Write(buf, len, status, &error);
930 if (status != eConnectionStatusSuccess && error.Success())
932 "ConPTY stdin write returned status {0}", static_cast<int>(status));
933 return written;
934}
935} // 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: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
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
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)
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
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