LLDB mainline
ProcessWindows.cpp
Go to the documentation of this file.
1//===-- ProcessWindows.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
9#include "ProcessWindows.h"
10
11// Windows includes
13#include <psapi.h>
14
16#include "lldb/Core/IOHandler.h"
17#include "lldb/Core/Module.h"
20#include "lldb/Core/Section.h"
22#include "lldb/Host/HostInfo.h"
25#include "lldb/Host/Pipe.h"
33#include "lldb/Target/Target.h"
35#include "lldb/Utility/Log.h"
36#include "lldb/Utility/State.h"
37
38#include "llvm/Support/ConvertUTF.h"
39#include "llvm/Support/Format.h"
40#include "llvm/Support/Threading.h"
41#include "llvm/Support/raw_ostream.h"
42
43#include "DebuggerThread.h"
44#include "ExceptionRecord.h"
45#include "ForwardDecl.h"
46#include "LocalDebugDelegate.h"
47#include "ProcessWindowsLog.h"
48#include "TargetThreadWindows.h"
49
50using namespace lldb;
51using namespace lldb_private;
52
53LLDB_PLUGIN_DEFINE_ADV(ProcessWindows, ProcessWindowsCommon)
54
55namespace {
56std::string GetProcessExecutableName(HANDLE process_handle) {
57 std::vector<wchar_t> file_name;
58 DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
59 DWORD copied = 0;
60 do {
61 file_name_size *= 2;
62 file_name.resize(file_name_size);
63 copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
64 file_name_size);
65 } while (copied >= file_name_size);
66 file_name.resize(copied);
67 std::string result;
68 llvm::convertWideToUTF8(file_name.data(), result);
69 return result;
70}
71
72std::string GetProcessExecutableName(DWORD pid) {
73 std::string file_name;
74 HANDLE process_handle =
75 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
76 if (process_handle != NULL) {
77 file_name = GetProcessExecutableName(process_handle);
78 ::CloseHandle(process_handle);
79 }
80 return file_name;
81}
82} // anonymous namespace
83
84namespace lldb_private {
85
87 lldb::ListenerSP listener_sp,
88 const FileSpec *crash_file_path,
89 bool can_connect) {
90 if (crash_file_path)
91 return nullptr; // Cannot create a Windows process from a crash_file.
92 return ProcessSP(new ProcessWindows(target_sp, listener_sp));
93}
94
95static bool ShouldUseLLDBServer() {
96 llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER");
97 return use_lldb_server.equals_insensitive("on") ||
98 use_lldb_server.equals_insensitive("yes") ||
99 use_lldb_server.equals_insensitive("1") ||
100 use_lldb_server.equals_insensitive("true");
101}
102
109
114
116 return "Process plugin for Windows";
117}
118
119// Constructors and destructors.
120
122 lldb::ListenerSP listener_sp)
123 : lldb_private::Process(target_sp, listener_sp),
125 RegisterContextWindows::GetNumHardwareBreakpointSlots(),
127
129
131 if (bp_site->HardwareRequired())
132 return Status::FromErrorString("Hardware breakpoints are not supported.");
133
135 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
136 bp_site->GetID(), bp_site->GetLoadAddress());
137
139 if (!error.Success())
140 LLDB_LOG(log, "error: {0}", error);
141 return error;
142}
143
146 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
147 bp_site->GetID(), bp_site->GetLoadAddress());
148
150
151 if (!error.Success())
152 LLDB_LOG(log, "error: {0}", error);
153 return error;
154}
155
159 StateType private_state = GetPrivateState();
160 if (private_state != eStateExited && private_state != eStateDetached) {
161 if (!keep_stopped) {
162 // if the thread is suspended by lldb, we have to resume threads before
163 // detaching process. When we do after DetachProcess(), thread handles
164 // become invalid so we do before detach.
165 if (private_state == eStateStopped || private_state == eStateCrashed) {
166 LLDB_LOG(log, "process {0} is in state {1}. Resuming for detach...",
167 m_session_data->m_debugger->GetProcess().GetProcessId(),
169
170 LLDB_LOG(log, "resuming {0} threads for detach.",
171 m_thread_list.GetSize());
172
173 bool failed = false;
174 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
175 auto thread = std::static_pointer_cast<TargetThreadWindows>(
176 m_thread_list.GetThreadAtIndex(i));
177 Status result = thread->DoResume();
178 if (result.Fail()) {
179 failed = true;
180 LLDB_LOG(log,
181 "Trying to resume thread at index {0}, but failed with "
182 "error {1}.",
183 i, result);
184 }
185 }
186
187 if (failed) {
188 error = Status::FromErrorString("Resuming Threads for Detach failed");
189 }
190 }
191 }
192
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(), private_state);
203 LLDB_LOG(log, "error: {0}", error);
204 }
205 return error;
206}
207
209 ProcessLaunchInfo &launch_info) {
211 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
212 error = LaunchProcess(launch_info, delegate);
213 if (error.Success())
214 SetID(launch_info.GetProcessID());
215 m_pty = launch_info.TakePTY();
216 return error;
217}
218
219Status
221 const ProcessAttachInfo &attach_info) {
222 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
223 Status error = AttachProcess(pid, attach_info, delegate);
224 if (error.Success())
226 return error;
227}
228
231 llvm::sys::ScopedLock lock(m_mutex);
232
233 if (direction == RunDirection::eRunReverse) {
235 "{0} does not support reverse execution of processes", GetPluginName());
236 }
237
239
240 StateType private_state = GetPrivateState();
241 if (private_state == eStateStopped || private_state == eStateCrashed) {
242 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
243 m_session_data->m_debugger->GetProcess().GetProcessId(),
245
246 LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
247
248 bool failed = false;
249 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
250 auto thread = std::static_pointer_cast<TargetThreadWindows>(
251 m_thread_list.GetThreadAtIndex(i));
252 Status result = thread->DoResume();
253 if (result.Fail()) {
254 failed = true;
255 LLDB_LOG(
256 log,
257 "Trying to resume thread at index {0}, but failed with error {1}.",
258 i, result);
259 }
260 }
261
262 if (failed) {
263 error = Status::FromErrorString("ProcessWindows::DoResume failed");
264 } else {
266 }
267
268 ExceptionRecordSP active_exception =
269 m_session_data->m_debugger->GetActiveException().lock();
270 if (active_exception) {
271 // Resume the process and continue processing debug events. Mask the
272 // exception so that from the process's view, there is no indication that
273 // anything happened.
274 m_session_data->m_debugger->ContinueAsyncException(
276 }
277 } else {
278 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
279 m_session_data->m_debugger->GetProcess().GetProcessId(),
281 }
282 return error;
283}
284
286 StateType private_state = GetPrivateState();
287 return DestroyProcess(private_state);
288}
289
290Status ProcessWindows::DoHalt(bool &caused_stop) {
291 StateType state = GetPrivateState();
292 if (state != eStateStopped)
293 return HaltProcess(caused_stop);
294 caused_stop = false;
295 return Status();
296}
297
299 ArchSpec arch_spec;
300 DidAttach(arch_spec);
301}
302
304 llvm::sys::ScopedLock lock(m_mutex);
305
306 // The initial stop won't broadcast the state change event, so account for
307 // that here.
309 m_session_data->m_stop_at_entry)
311}
312
313static void
314DumpAdditionalExceptionInformation(llvm::raw_ostream &stream,
315 const ExceptionRecordSP &exception) {
316 // Decode additional exception information for specific exception types based
317 // on
318 // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record
319
320 const int addr_min_width = 2 + 8; // "0x" + 4 address bytes
321
322 const std::vector<ULONG_PTR> &args = exception->GetExceptionArguments();
323 switch (exception->GetExceptionCode()) {
324 case EXCEPTION_ACCESS_VIOLATION: {
325 if (args.size() < 2)
326 break;
327
328 stream << ": ";
329 const int access_violation_code = args[0];
330 const lldb::addr_t access_violation_address = args[1];
331 switch (access_violation_code) {
332 case 0:
333 stream << "Access violation reading";
334 break;
335 case 1:
336 stream << "Access violation writing";
337 break;
338 case 8:
339 stream << "User-mode data execution prevention (DEP) violation at";
340 break;
341 default:
342 stream << "Unknown access violation (code " << access_violation_code
343 << ") at";
344 break;
345 }
346 stream << " location "
347 << llvm::format_hex(access_violation_address, addr_min_width);
348 break;
349 }
350 case EXCEPTION_IN_PAGE_ERROR: {
351 if (args.size() < 3)
352 break;
353
354 stream << ": ";
355 const int page_load_error_code = args[0];
356 const lldb::addr_t page_load_error_address = args[1];
357 const DWORD underlying_code = args[2];
358 switch (page_load_error_code) {
359 case 0:
360 stream << "In page error reading";
361 break;
362 case 1:
363 stream << "In page error writing";
364 break;
365 case 8:
366 stream << "User-mode data execution prevention (DEP) violation at";
367 break;
368 default:
369 stream << "Unknown page loading error (code " << page_load_error_code
370 << ") at";
371 break;
372 }
373 stream << " location "
374 << llvm::format_hex(page_load_error_address, addr_min_width)
375 << " (status code " << llvm::format_hex(underlying_code, 8) << ")";
376 break;
377 }
378 }
379}
380
383 llvm::sys::ScopedLock lock(m_mutex);
384
385 if (!m_session_data) {
386 LLDB_LOG(log, "no active session. Returning...");
387 return;
388 }
389
390 m_thread_list.RefreshStateAfterStop();
391
392 std::weak_ptr<ExceptionRecord> exception_record =
393 m_session_data->m_debugger->GetActiveException();
394 ExceptionRecordSP active_exception = exception_record.lock();
395 if (!active_exception) {
396 LLDB_LOG(log,
397 "there is no active exception in process {0}. Why is the "
398 "process stopped?",
399 m_session_data->m_debugger->GetProcess().GetProcessId());
400 return;
401 }
402
403 StopInfoSP stop_info;
404 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
405 ThreadSP stop_thread = m_thread_list.GetSelectedThread();
406 if (!stop_thread)
407 return;
408
409 RegisterContextSP register_context = stop_thread->GetRegisterContext();
410 uint64_t pc = register_context->GetPC();
411
412 // If we're at a BreakpointSite, mark this as an Unexecuted Breakpoint.
413 // We'll clear that state if we've actually executed the breakpoint.
414 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
415 if (site && site->IsEnabled())
416 stop_thread->SetThreadStoppedAtUnexecutedBP(pc);
417
418 switch (active_exception->GetExceptionCode()) {
419 case EXCEPTION_SINGLE_STEP: {
420 auto *reg_ctx = static_cast<RegisterContextWindows *>(
421 stop_thread->GetRegisterContext().get());
422 uint32_t slot_id = reg_ctx->GetTriggeredHardwareBreakpointSlotId();
423 if (slot_id != LLDB_INVALID_INDEX32) {
424 int id = m_watchpoint_ids[slot_id];
425 LLDB_LOG(log,
426 "Single-stepped onto a watchpoint in process {0} at address "
427 "{1:x} with watchpoint {2}",
428 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, id);
429
430 stop_info = StopInfo::CreateStopReasonWithWatchpointID(*stop_thread, id);
431 stop_thread->SetStopInfo(stop_info);
432
433 return;
434 }
435
436 LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
437 stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
438 stop_thread->SetStopInfo(stop_info);
439
440 return;
441 }
442
443 case EXCEPTION_BREAKPOINT: {
444 int breakpoint_size = 1;
445 switch (GetTarget().GetArchitecture().GetMachine()) {
446 case llvm::Triple::aarch64:
447 breakpoint_size = 4;
448 break;
449
450 case llvm::Triple::arm:
451 case llvm::Triple::thumb:
452 breakpoint_size = 2;
453 break;
454
455 case llvm::Triple::x86:
456 case llvm::Triple::x86_64:
457 breakpoint_size = 1;
458 break;
459
460 default:
461 LLDB_LOG(log, "Unknown breakpoint size for architecture");
462 break;
463 }
464
465 // The current PC is AFTER the BP opcode, on all architectures.
466 pc = register_context->GetPC() - breakpoint_size;
467
469 if (site) {
470 LLDB_LOG(log,
471 "detected breakpoint in process {0} at address {1:x} with "
472 "breakpoint site {2}",
473 m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
474 site->GetID());
475
476 stop_thread->SetThreadHitBreakpointSite();
477 if (site->ValidForThisThread(*stop_thread)) {
478 LLDB_LOG(log,
479 "Breakpoint site {0} is valid for this thread ({1:x}), "
480 "creating stop info.",
481 site->GetID(), stop_thread->GetID());
482
484 *stop_thread, site->GetID());
485 register_context->SetPC(pc);
486 } else {
487 LLDB_LOG(log,
488 "Breakpoint site {0} is not valid for this thread, "
489 "creating empty stop info.",
490 site->GetID());
491 }
492 stop_thread->SetStopInfo(stop_info);
493 return;
494 } else {
495 // The thread hit a hard-coded breakpoint like an `int 3` or
496 // `__debugbreak()`.
497 LLDB_LOG(log,
498 "No breakpoint site matches for this thread. __debugbreak()? "
499 "Creating stop info with the exception.");
500 // FALLTHROUGH: We'll treat this as a generic exception record in the
501 // default case.
502 [[fallthrough]];
503 }
504 }
505
506 default: {
507 std::string desc;
508 llvm::raw_string_ostream desc_stream(desc);
509 desc_stream << "Exception "
510 << llvm::format_hex(active_exception->GetExceptionCode(), 8)
511 << " encountered at address "
512 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
513 DumpAdditionalExceptionInformation(desc_stream, active_exception);
514
515 stop_info =
516 StopInfo::CreateStopReasonWithException(*stop_thread, desc.c_str());
517 stop_thread->SetStopInfo(stop_info);
518 LLDB_LOG(log, "{0}", desc);
519 return;
520 }
521 }
522}
523
525 bool plugin_specified_by_name) {
526 if (plugin_specified_by_name)
527 return true;
528
529 // For now we are just making sure the file exists for a given module
530 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
531 if (exe_module_sp.get())
532 return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
533 // However, if there is no executable module, we return true since we might
534 // be preparing to attach.
535 return true;
536}
537
539 ThreadList &new_thread_list) {
541 // Add all the threads that were previously running and for which we did not
542 // detect a thread exited event.
543 int new_size = 0;
544 int continued_threads = 0;
545 int exited_threads = 0;
546 int new_threads = 0;
547
548 for (ThreadSP old_thread : old_thread_list.Threads()) {
549 lldb::tid_t old_thread_id = old_thread->GetID();
550 auto exited_thread_iter =
551 m_session_data->m_exited_threads.find(old_thread_id);
552 if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
553 new_thread_list.AddThread(old_thread);
554 ++new_size;
555 ++continued_threads;
556 LLDB_LOGV(log, "Thread {0} was running and is still running.",
557 old_thread_id);
558 } else {
559 LLDB_LOGV(log, "Thread {0} was running and has exited.", old_thread_id);
560 ++exited_threads;
561 }
562 }
563
564 // Also add all the threads that are new since the last time we broke into
565 // the debugger.
566 for (const auto &thread_info : m_session_data->m_new_threads) {
567 new_thread_list.AddThread(thread_info.second);
568 ++new_size;
569 ++new_threads;
570 LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
571 }
572
573 LLDB_LOG(log, "{0} new threads, {1} old threads, {2} exited threads.",
574 new_threads, continued_threads, exited_threads);
575
576 m_session_data->m_new_threads.clear();
577 m_session_data->m_exited_threads.clear();
578
579 return new_size > 0;
580}
581
583 StateType state = GetPrivateState();
584 switch (state) {
585 case eStateCrashed:
586 case eStateDetached:
587 case eStateUnloaded:
588 case eStateExited:
589 case eStateInvalid:
590 return false;
591 default:
592 return true;
593 }
594}
595
597 return HostInfo::GetArchitecture();
598}
599
601 size_t size, Status &error) {
602 size_t bytes_read = 0;
603 error = ProcessDebugger::ReadMemory(vm_addr, buf, size, bytes_read);
604 return bytes_read;
605}
606
607size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
608 size_t size, Status &error) {
609 size_t bytes_written = 0;
610 error = ProcessDebugger::WriteMemory(vm_addr, buf, size, bytes_written);
611 return bytes_written;
612}
613
614lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions,
615 Status &error) {
617 error = ProcessDebugger::AllocateMemory(size, permissions, vm_addr);
618 return vm_addr;
619}
620
624
629
631 Target &target = GetTarget();
632 ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
633 Address addr = obj_file->GetImageInfoAddress(&target);
634 if (addr.IsValid())
635 return addr.GetLoadAddress(&target);
636 else
638}
639
646
647void ProcessWindows::OnExitProcess(uint32_t exit_code) {
648 // No need to acquire the lock since m_session_data isn't accessed.
650 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
651
652 if (m_pty) {
653 m_pty->SetStopping(true);
654 m_stdio_communication.InterruptRead();
655 m_pty->Close();
656 }
657
658 TargetSP target = CalculateTarget();
659 if (target) {
660 ModuleSP executable_module = target->GetExecutableModule();
661 ModuleList unloaded_modules;
662 unloaded_modules.Append(executable_module);
663 target->ModulesDidUnload(unloaded_modules, true);
664 }
665
666 SetExitStatus(exit_code, /*exit_string=*/"");
668
670}
671
673 DebuggerThreadSP debugger = m_session_data->m_debugger;
675 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
676 debugger->GetProcess().GetProcessId(), image_base);
677
678 ModuleSP module;
679 // During attach, we won't have the executable module, so find it now.
680 const DWORD pid = debugger->GetProcess().GetProcessId();
681 const std::string file_name = GetProcessExecutableName(pid);
682 if (file_name.empty()) {
683 return;
684 }
685
686 FileSpec executable_file(file_name);
687 FileSystem::Instance().Resolve(executable_file);
688 ModuleSpec module_spec(executable_file);
690 module =
691 GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
692 if (!module) {
693 return;
694 }
695
697
698 if (auto dyld = GetDynamicLoader())
699 dyld->OnLoadModule(module, ModuleSpec(), image_base);
700
701 // Add the main executable module to the list of pending module loads. We
702 // can't call GetTarget().ModulesDidLoad() here because we still haven't
703 // returned from DoLaunch() / DoAttach() yet so the target may not have set
704 // the process instance to `this` yet.
705 llvm::sys::ScopedLock lock(m_mutex);
706
707 const HostThread &host_main_thread = debugger->GetMainThread();
708 ThreadSP main_thread =
709 std::make_shared<TargetThreadWindows>(*this, host_main_thread);
710
711 tid_t id = host_main_thread.GetNativeThread().GetThreadId();
712 main_thread->SetID(id);
713
714 m_session_data->m_new_threads[id] = main_thread;
715}
716
719 const ExceptionRecord &record) {
721 llvm::sys::ScopedLock lock(m_mutex);
722
723 // FIXME: Without this check, occasionally when running the test suite there
724 // is
725 // an issue where m_session_data can be null. It's not clear how this could
726 // happen but it only surfaces while running the test suite. In order to
727 // properly diagnose this, we probably need to first figure allow the test
728 // suite to print out full lldb logs, and then add logging to the process
729 // plugin.
730 if (!m_session_data) {
731 LLDB_LOG(log,
732 "Debugger thread reported exception {0:x} at address {1:x}, "
733 "but there is no session.",
734 record.GetExceptionCode(), record.GetExceptionAddress());
736 }
737
738 if (!first_chance) {
739 // Not any second chance exception is an application crash by definition.
740 // It may be an expression evaluation crash.
742 }
743
745 switch (record.GetExceptionCode()) {
746 case EXCEPTION_BREAKPOINT:
747 // Handle breakpoints at the first chance.
749
750 if (!m_session_data->m_initial_stop_received) {
751 LLDB_LOG(
752 log,
753 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
754 record.GetExceptionAddress());
755 m_session_data->m_initial_stop_received = true;
756 ::SetEvent(m_session_data->m_initial_stop_event);
757 } else {
758 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
759 record.GetExceptionAddress());
760 }
762 break;
763 case EXCEPTION_SINGLE_STEP:
766 break;
767 default:
768 LLDB_LOG(log,
769 "Debugger thread reported exception {0:x} at address {1:x} "
770 "(first_chance={2})",
771 record.GetExceptionCode(), record.GetExceptionAddress(),
772 first_chance);
773 // For non-breakpoints, give the application a chance to handle the
774 // exception first.
775 if (first_chance)
777 else
779 }
780
781 return result;
782}
783
785 llvm::sys::ScopedLock lock(m_mutex);
786
787 ThreadSP thread = std::make_shared<TargetThreadWindows>(*this, new_thread);
788
789 const HostNativeThread &native_new_thread = new_thread.GetNativeThread();
790 tid_t id = native_new_thread.GetThreadId();
791 thread->SetID(id);
792
793 m_session_data->m_new_threads[id] = thread;
794
795 for (const std::map<int, WatchpointInfo>::value_type &p : m_watchpoints) {
796 auto *reg_ctx = static_cast<RegisterContextWindows *>(
797 thread->GetRegisterContext().get());
798 reg_ctx->AddHardwareBreakpoint(p.second.slot_id, p.second.address,
799 p.second.size, p.second.read,
800 p.second.write);
801 }
802}
803
804void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
805 llvm::sys::ScopedLock lock(m_mutex);
806
807 // On a forced termination, we may get exit thread events after the session
808 // data has been cleaned up.
809 if (!m_session_data)
810 return;
811
812 // A thread may have started and exited before the debugger stopped allowing a
813 // refresh.
814 // Just remove it from the new threads list in that case.
815 auto iter = m_session_data->m_new_threads.find(thread_id);
816 if (iter != m_session_data->m_new_threads.end())
817 m_session_data->m_new_threads.erase(iter);
818 else
819 m_session_data->m_exited_threads.insert(thread_id);
820}
821
822void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
823 lldb::addr_t module_addr) {
824 if (auto dyld = GetDynamicLoader())
825 dyld->OnLoadModule(nullptr, module_spec, module_addr);
826}
827
829 if (auto dyld = GetDynamicLoader())
830 dyld->OnUnloadModule(module_addr);
831}
832
833void ProcessWindows::OnDebugString(const std::string &string) {}
834
835void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) {
836 llvm::sys::ScopedLock lock(m_mutex);
838
839 if (m_session_data->m_initial_stop_received) {
840 // This happened while debugging. Do we shutdown the debugging session,
841 // try to continue, or do something else?
842 LLDB_LOG(log,
843 "Error {0} occurred during debugging. Unexpected behavior "
844 "may result. {1}",
845 error.GetError(), error);
846 } else {
847 // If we haven't actually launched the process yet, this was an error
848 // launching the process. Set the internal error and signal the initial
849 // stop event so that the DoLaunch method wakes up and returns a failure.
850 m_session_data->m_launch_error = error.Clone();
851 ::SetEvent(m_session_data->m_initial_stop_event);
852 LLDB_LOG(
853 log,
854 "Error {0} occurred launching the process before the initial stop. {1}",
855 error.GetError(), error);
856 return;
857 }
858}
859
863
866
867 if (wp_sp->IsEnabled()) {
868 wp_sp->SetEnabled(true, notify);
869 return error;
870 }
871
872 WatchpointInfo info;
873 for (info.slot_id = 0;
875 info.slot_id++)
877 break;
880 "Can't find free slot for watchpoint %i", wp_sp->GetID());
881 return error;
882 }
883 info.address = wp_sp->GetLoadAddress();
884 info.size = wp_sp->GetByteSize();
885 info.read = wp_sp->WatchpointRead();
886 info.write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
887
888 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
889 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
890 auto *reg_ctx = static_cast<RegisterContextWindows *>(
891 thread->GetRegisterContext().get());
892 if (!reg_ctx->AddHardwareBreakpoint(info.slot_id, info.address, info.size,
893 info.read, info.write)) {
895 "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
896 thread->GetID());
897 break;
898 }
899 }
900 if (error.Fail()) {
901 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
902 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
903 auto *reg_ctx = static_cast<RegisterContextWindows *>(
904 thread->GetRegisterContext().get());
905 reg_ctx->RemoveHardwareBreakpoint(info.slot_id);
906 }
907 return error;
908 }
909
910 m_watchpoints[wp_sp->GetID()] = info;
911 m_watchpoint_ids[info.slot_id] = wp_sp->GetID();
912
913 wp_sp->SetEnabled(true, notify);
914
915 return error;
916}
917
920
921 if (!wp_sp->IsEnabled()) {
922 wp_sp->SetEnabled(false, notify);
923 return error;
924 }
925
926 auto it = m_watchpoints.find(wp_sp->GetID());
927 if (it == m_watchpoints.end()) {
929 "Info about watchpoint %i is not found", wp_sp->GetID());
930 return error;
931 }
932
933 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
934 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
935 auto *reg_ctx = static_cast<RegisterContextWindows *>(
936 thread->GetRegisterContext().get());
937 if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
939 "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
940 thread->GetID());
941 break;
942 }
943 }
944 if (error.Fail())
945 return error;
946
947 m_watchpoint_ids[it->second.slot_id] = LLDB_INVALID_BREAK_ID;
948 m_watchpoints.erase(it);
949
950 wp_sp->SetEnabled(false, notify);
951
952 return error;
953}
954
956public:
958 : IOHandler(process->GetTarget().GetDebugger(),
960 m_process(process),
961 m_read_file(GetInputFD(), File::eOpenOptionReadOnly, false),
962 m_write_file(conpty_input),
964 CreateEvent(/*lpEventAttributes=*/NULL, /*bManualReset=*/FALSE,
965 /*bInitialState=*/FALSE, /*lpName=*/NULL)) {}
966
968 if (m_interrupt_event != INVALID_HANDLE_VALUE)
969 ::CloseHandle(m_interrupt_event);
970 }
971
972 void SetIsRunning(bool running) {
973 std::lock_guard<std::mutex> guard(m_mutex);
974 SetIsDone(!running);
975 m_is_running = running;
976 }
977
978 /// Peek the console for input. If it has any, drain the pipe until text input
979 /// is found or the pipe is empty.
980 ///
981 /// \param hStdin
982 /// The handle to the standard input's pipe.
983 ///
984 /// \return
985 /// true if the pipe has text input.
986 llvm::Expected<bool> ConsoleHasTextInput(const HANDLE hStdin) {
987 // Check if there are already characters buffered. Pressing enter counts as
988 // 2 characters '\r\n' and only one of them is a keyDown event.
989 DWORD bytesAvailable = 0;
990 if (PeekNamedPipe(hStdin, NULL, 0, NULL, &bytesAvailable, NULL)) {
991 if (bytesAvailable > 0)
992 return true;
993 }
994
995 while (true) {
996 INPUT_RECORD inputRecord;
997 DWORD numRead = 0;
998 if (!PeekConsoleInput(hStdin, &inputRecord, 1, &numRead))
999 return llvm::createStringError("Failed to peek standard input.");
1000
1001 if (numRead == 0)
1002 return false;
1003
1004 if (inputRecord.EventType == KEY_EVENT &&
1005 inputRecord.Event.KeyEvent.bKeyDown &&
1006 inputRecord.Event.KeyEvent.uChar.AsciiChar != 0)
1007 return true;
1008
1009 if (!ReadConsoleInput(hStdin, &inputRecord, 1, &numRead))
1010 return llvm::createStringError("Failed to read standard input.");
1011 }
1012 }
1013
1014 void Run() override {
1015 if (!m_read_file.IsValid() || m_write_file == INVALID_HANDLE_VALUE) {
1016 SetIsDone(true);
1017 return;
1018 }
1019
1020 SetIsDone(false);
1021 SetIsRunning(true);
1022
1023 HANDLE hStdin = m_read_file.GetWaitableHandle();
1024 HANDLE waitHandles[2] = {hStdin, m_interrupt_event};
1025
1026 DWORD consoleMode;
1027 bool isConsole = GetConsoleMode(hStdin, &consoleMode) != 0;
1028 // With ENABLE_LINE_INPUT, ReadFile returns only when a carriage return is
1029 // read. This will block lldb in ReadFile until the user hits enter. Save
1030 // the previous console mode to restore it later and remove
1031 // ENABLE_LINE_INPUT.
1032 DWORD oldConsoleMode = consoleMode;
1033 SetConsoleMode(hStdin,
1034 consoleMode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT);
1035
1036 while (true) {
1037 {
1038 std::lock_guard<std::mutex> guard(m_mutex);
1039 if (GetIsDone())
1040 goto exit_loop;
1041 }
1042
1043 DWORD result = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);
1044 switch (result) {
1045 case WAIT_FAILED:
1046 goto exit_loop;
1047 case WAIT_OBJECT_0: {
1048 if (isConsole) {
1049 auto hasInputOrErr = ConsoleHasTextInput(hStdin);
1050 if (!hasInputOrErr) {
1052 LLDB_LOG_ERROR(log, hasInputOrErr.takeError(),
1053 "failed to process debuggee's IO: {0}");
1054 goto exit_loop;
1055 }
1056
1057 // If no text input is ready, go back to waiting.
1058 if (!*hasInputOrErr)
1059 continue;
1060 }
1061
1062 char ch = 0;
1063 DWORD read = 0;
1064 if (!ReadFile(hStdin, &ch, 1, &read, nullptr) || read != 1)
1065 goto exit_loop;
1066
1067 DWORD written = 0;
1068 if (!WriteFile(m_write_file, &ch, 1, &written, nullptr) || written != 1)
1069 goto exit_loop;
1070 break;
1071 }
1072 case WAIT_OBJECT_0 + 1: {
1073 ControlOp op = m_pending_op.exchange(eControlOpNone);
1074 if (op == eControlOpQuit)
1075 goto exit_loop;
1076 if (op == eControlOpInterrupt &&
1077 StateIsRunningState(m_process->GetState()))
1078 m_process->SendAsyncInterrupt();
1079 break;
1080 }
1081 default:
1082 goto exit_loop;
1083 }
1084 }
1085
1086 exit_loop:;
1087 SetIsRunning(false);
1088 SetIsDone(true);
1089 SetConsoleMode(hStdin, oldConsoleMode);
1090 }
1091
1092 void Cancel() override {
1093 std::lock_guard<std::mutex> guard(m_mutex);
1094 SetIsDone(true);
1095 if (m_is_running) {
1097 ::SetEvent(m_interrupt_event);
1098 }
1099 }
1100
1101 bool Interrupt() override {
1102 if (m_active) {
1104 ::SetEvent(m_interrupt_event);
1105 return true;
1106 }
1107 if (StateIsRunningState(m_process->GetState())) {
1108 m_process->SendAsyncInterrupt();
1109 return true;
1110 }
1111 return false;
1112 }
1113
1114 void GotEOF() override {}
1115
1116private:
1122
1124 /// Read from this file (usually actual STDIN for LLDB)
1126 /// Write to this file (usually the primary pty for getting io to debuggee)
1127 HANDLE m_write_file = INVALID_HANDLE_VALUE;
1128 HANDLE m_interrupt_event = INVALID_HANDLE_VALUE;
1129 std::atomic<ControlOp> m_pending_op{eControlOpNone};
1130 std::mutex m_mutex;
1131 bool m_is_running = false;
1132};
1133
1135 if (m_pty == nullptr)
1136 return;
1137 m_stdio_communication.SetConnection(
1138 std::make_unique<ConnectionConPTY>(m_pty));
1139 if (m_stdio_communication.IsConnected()) {
1140 m_stdio_communication.SetReadThreadBytesReceivedCallback(
1142 m_stdio_communication.StartReadThread();
1143
1144 // Now read thread is set up, set up input reader.
1145 {
1146 std::lock_guard<std::mutex> guard(m_process_input_reader_mutex);
1148 m_process_input_reader = std::make_shared<IOHandlerProcessSTDIOWindows>(
1149 this, m_pty->GetSTDINHandle());
1150 }
1151 }
1152}
1153} // namespace lldb_private
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:369
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
#define LLDB_LOGV(log,...)
Definition Log.h:383
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
void * HANDLE
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition Address.cpp:301
bool IsValid() const
Check if the object state is valid.
Definition Address.h:355
An architecture specification class.
Definition ArchSpec.h:32
Class that manages the actual breakpoint that will be inserted into the running program.
static DynamicLoader * FindPlugin(Process *process, llvm::StringRef plugin_name)
Find a dynamic loader plugin for a given process.
lldb::addr_t GetExceptionAddress() const
A file utility class.
Definition FileSpec.h:57
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
void Resolve(llvm::SmallVectorImpl< char > &path, bool force_make_absolute=false)
Resolve path to make it canonical.
An abstract base class for files.
Definition File.h:36
HostNativeThread & GetNativeThread()
NativeFile m_read_file
Read from this file (usually actual STDIN for LLDB)
llvm::Expected< bool > ConsoleHasTextInput(const HANDLE hStdin)
Peek the console for input.
HANDLE m_write_file
Write to this file (usually the primary pty for getting io to debuggee)
IOHandlerProcessSTDIOWindows(Process *process, HANDLE conpty_input)
Debugger & GetDebugger()
Definition IOHandler.h:130
IOHandler(Debugger &debugger, IOHandler::Type type)
Definition IOHandler.cpp:55
void SetIsDone(bool b)
Definition IOHandler.h:81
A collection class for Module objects.
Definition ModuleList.h:125
void Append(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list.
A class that describes an executable image and its associated object and symbol files.
Definition Module.h:90
A plug-in interface definition class for object file parsers.
Definition ObjectFile.h:46
virtual lldb_private::Address GetImageInfoAddress(Target *target)
Similar to Process::GetImageInfoAddress().
Definition ObjectFile.h:444
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
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)
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)
Status HaltProcess(bool &caused_stop)
Status DeallocateMemory(lldb::addr_t addr)
lldb::pid_t GetProcessID() const
Definition ProcessInfo.h:68
std::shared_ptr< PTY > TakePTY()
void OnLoadDll(const ModuleSpec &module_spec, lldb::addr_t module_addr) override
void OnDebugString(const std::string &string) override
ProcessWindows(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
bool DoUpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override
Update the thread list following process plug-in's specific logic.
void RefreshStateAfterStop() override
Currently called as part of ShouldStop.
void OnDebuggerConnected(lldb::addr_t image_base) override
Status DoDeallocateMemory(lldb::addr_t ptr) override
Actually deallocate memory in the process.
std::shared_ptr< PTY > m_pty
Status EnableBreakpointSite(BreakpointSite *bp_site) override
void DidLaunch() override
Called after launching a process.
std::optional< uint32_t > GetWatchpointSlotCount() override
Get the number of watchpoints supported by this target.
Status DoResume(lldb::RunDirection direction) override
Resumes all of a process's threads as configured using the Thread run control functions.
void OnUnloadDll(lldb::addr_t module_addr) override
DynamicLoaderWindowsDYLD * GetDynamicLoader() override
Get the dynamic loader plug-in for this process.
Status DisableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
bool IsAlive() override
Check if a process is still alive.
Status DoGetMemoryRegionInfo(lldb::addr_t vm_addr, MemoryRegionInfo &info) override
DoGetMemoryRegionInfo is called by GetMemoryRegionInfo after it has removed non address bits from loa...
void OnCreateThread(const HostThread &thread) override
static llvm::StringRef GetPluginDescriptionStatic()
size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, Status &error) override
Actually do the writing of memory to a process.
llvm::StringRef GetPluginName() override
Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override
Launch a new process.
size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, Status &error) override
Actually do the reading of memory from a process.
bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override
Check if a plug-in instance can debug the file in module.
static llvm::StringRef GetPluginNameStatic()
void DidAttach(lldb_private::ArchSpec &arch_spec) override
Called after attaching a process.
void OnExitProcess(uint32_t exit_code) override
static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *, bool can_connect)
void OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) override
Status DoAttachToProcessWithID(lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override
Attach to an existing process using a process ID.
lldb::addr_t GetImageInfoAddress() override
Get the image information address for the current process.
ExceptionResult OnDebugException(bool first_chance, const ExceptionRecord &record) override
std::map< lldb::break_id_t, WatchpointInfo > m_watchpoints
void OnDebuggerError(const Status &error, uint32_t type) override
ArchSpec GetSystemArchitecture() override
Get the system architecture for this process.
Status DoDetach(bool keep_stopped) override
Detaches from a running or stopped process.
std::vector< lldb::break_id_t > m_watchpoint_ids
lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, Status &error) override
Actually allocate memory in the process.
Status DisableBreakpointSite(BreakpointSite *bp_site) override
Status DoHalt(bool &caused_stop) override
Halts a running process.
Status EnableWatchpoint(lldb::WatchpointSP wp_sp, bool notify=true) override
A plug-in interface definition class for debugging a process.
Definition Process.h:354
lldb::IOHandlerSP m_process_input_reader
Definition Process.h:3419
std::mutex m_process_input_reader_mutex
Definition Process.h:3420
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
Definition Process.cpp:1536
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1810
lldb::pid_t GetID() const
Returns the pid of the process or LLDB_INVALID_PROCESS_ID if there is no known pid.
Definition Process.h:537
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
Definition Process.cpp:425
lldb::StateType GetPrivateState() const
Definition Process.h:3329
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3407
lldb::TargetSP CalculateTarget() override
Definition Process.cpp:4618
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1730
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
Definition Process.h:542
friend class Target
Definition Process.h:360
virtual bool SetExitStatus(int exit_status, llvm::StringRef exit_string)
Set accessor for the process exit status (return code).
Definition Process.cpp:1023
static void STDIOReadThreadBytesReceived(void *baton, const void *src, size_t src_len)
Definition Process.cpp:4752
void SetPrivateState(lldb::StateType state)
Definition Process.cpp:1377
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3380
ThreadedCommunication m_stdio_communication
Definition Process.h:3421
friend class ThreadList
Definition Process.h:361
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1250
static constexpr uint32_t GetNumHardwareBreakpointSlots()
bool AddHardwareBreakpoint(uint32_t slot, lldb::addr_t address, uint32_t size, bool read, bool write)
An error handling class.
Definition Status.h:118
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
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
StopPointSiteSP FindByAddress(lldb::addr_t addr)
Returns a shared pointer to the site at address addr.
lldb::break_id_t GetID() const
virtual lldb::addr_t GetLoadAddress() const
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition Target.cpp:1525
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition Target.cpp:1576
void AddThread(const lldb::ThreadSP &thread_sp)
virtual ThreadIterable Threads()
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_ADDRESS
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:332
std::shared_ptr< ExceptionRecord > ExceptionRecordSP
Definition ForwardDecl.h:37
HostThreadPosix HostNativeThread
bool StateIsRunningState(lldb::StateType state)
Check if a state represents a state where the process or thread is running.
Definition State.cpp:68
std::shared_ptr< IDebugDelegate > DebugDelegateSP
Definition ForwardDecl.h:35
std::shared_ptr< DebuggerThread > DebuggerThreadSP
Definition ForwardDecl.h:36
static void DumpAdditionalExceptionInformation(llvm::raw_ostream &stream, const ExceptionRecordSP &exception)
static bool ShouldUseLLDBServer()
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
RunDirection
Execution directions.
std::shared_ptr< lldb_private::Thread > ThreadSP
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.
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateExited
Process has exited and can't be examined.
@ eStateCrashed
Process or thread has crashed and can be examined.
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t pid_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::Listener > ListenerSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
uint64_t addr_t
Definition lldb-types.h:80
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
uint64_t tid_t
Definition lldb-types.h:84
std::shared_ptr< lldb_private::Module > ModuleSP