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/Module.h"
19#include "lldb/Core/Section.h"
21#include "lldb/Host/HostInfo.h"
29#include "lldb/Target/Target.h"
30#include "lldb/Utility/State.h"
31
32#include "llvm/Support/ConvertUTF.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 "ForwardDecl.h"
40#include "LocalDebugDelegate.h"
41#include "ProcessWindowsLog.h"
42#include "TargetThreadWindows.h"
43
44using namespace lldb;
45using namespace lldb_private;
46
47LLDB_PLUGIN_DEFINE_ADV(ProcessWindows, ProcessWindowsCommon)
48
49namespace {
50std::string GetProcessExecutableName(HANDLE process_handle) {
51 std::vector<wchar_t> file_name;
52 DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
53 DWORD copied = 0;
54 do {
55 file_name_size *= 2;
56 file_name.resize(file_name_size);
57 copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
58 file_name_size);
59 } while (copied >= file_name_size);
60 file_name.resize(copied);
61 std::string result;
62 llvm::convertWideToUTF8(file_name.data(), result);
63 return result;
64}
65
66std::string GetProcessExecutableName(DWORD pid) {
67 std::string file_name;
68 HANDLE process_handle =
69 ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
70 if (process_handle != NULL) {
71 file_name = GetProcessExecutableName(process_handle);
72 ::CloseHandle(process_handle);
73 }
74 return file_name;
75}
76} // anonymous namespace
77
78namespace lldb_private {
79
81 lldb::ListenerSP listener_sp,
82 const FileSpec *crash_file_path,
83 bool can_connect) {
84 if (crash_file_path)
85 return nullptr; // Cannot create a Windows process from a crash_file.
86 return ProcessSP(new ProcessWindows(target_sp, listener_sp));
87}
88
89static bool ShouldUseLLDBServer() {
90 llvm::StringRef use_lldb_server = ::getenv("LLDB_USE_LLDB_SERVER");
91 return use_lldb_server.equals_insensitive("on") ||
92 use_lldb_server.equals_insensitive("yes") ||
93 use_lldb_server.equals_insensitive("1") ||
94 use_lldb_server.equals_insensitive("true");
95}
96
98 if (!ShouldUseLLDBServer()) {
99 static llvm::once_flag g_once_flag;
100
101 llvm::call_once(g_once_flag, []() {
105 });
106 }
107}
108
110
112 return "Process plugin for Windows";
113}
114
115// Constructors and destructors.
116
118 lldb::ListenerSP listener_sp)
119 : lldb_private::Process(target_sp, listener_sp),
121 RegisterContextWindows::GetNumHardwareBreakpointSlots(),
123
125
126size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
127 error = Status::FromErrorString("GetSTDOUT unsupported on Windows");
128 return 0;
129}
130
131size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Status &error) {
132 error = Status::FromErrorString("GetSTDERR unsupported on Windows");
133 return 0;
134}
135
136size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
137 Status &error) {
138 error = Status::FromErrorString("PutSTDIN unsupported on Windows");
139 return 0;
140}
141
143 if (bp_site->HardwareRequired())
144 return Status::FromErrorString("Hardware breakpoints are not supported.");
145
147 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
148 bp_site->GetID(), bp_site->GetLoadAddress());
149
151 if (!error.Success())
152 LLDB_LOG(log, "error: {0}", error);
153 return error;
154}
155
158 LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
159 bp_site->GetID(), bp_site->GetLoadAddress());
160
162
163 if (!error.Success())
164 LLDB_LOG(log, "error: {0}", error);
165 return error;
166}
167
171 StateType private_state = GetPrivateState();
172 if (private_state != eStateExited && private_state != eStateDetached) {
173 if (!keep_stopped) {
174 // if the thread is suspended by lldb, we have to resume threads before
175 // detaching process. When we do after DetachProcess(), thread handles
176 // become invalid so we do before detach.
177 if (private_state == eStateStopped || private_state == eStateCrashed) {
178 LLDB_LOG(log, "process {0} is in state {1}. Resuming for detach...",
179 m_session_data->m_debugger->GetProcess().GetProcessId(),
181
182 LLDB_LOG(log, "resuming {0} threads for detach.",
183 m_thread_list.GetSize());
184
185 bool failed = false;
186 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
187 auto thread = std::static_pointer_cast<TargetThreadWindows>(
188 m_thread_list.GetThreadAtIndex(i));
189 Status result = thread->DoResume();
190 if (result.Fail()) {
191 failed = true;
192 LLDB_LOG(log,
193 "Trying to resume thread at index {0}, but failed with "
194 "error {1}.",
195 i, result);
196 }
197 }
198
199 if (failed) {
200 error = Status::FromErrorString("Resuming Threads for Detach failed");
201 }
202 }
203 }
204
206 if (error.Success())
208 else
209 LLDB_LOG(log, "Detaching process error: {0}", error);
210 } else {
212 "error: process {0} in state = {1}, but "
213 "cannot detach it in this state.",
214 GetID(), private_state);
215 LLDB_LOG(log, "error: {0}", error);
216 }
217 return error;
218}
219
221 ProcessLaunchInfo &launch_info) {
223 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
224 error = LaunchProcess(launch_info, delegate);
225 if (error.Success())
226 SetID(launch_info.GetProcessID());
227 return error;
228}
229
230Status
232 const ProcessAttachInfo &attach_info) {
233 DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
234 Status error = AttachProcess(pid, attach_info, delegate);
235 if (error.Success())
237 return error;
238}
239
242 llvm::sys::ScopedLock lock(m_mutex);
243
244 if (direction == RunDirection::eRunReverse) {
246 "{0} does not support reverse execution of processes", GetPluginName());
247 }
248
250
251 StateType private_state = GetPrivateState();
252 if (private_state == eStateStopped || private_state == eStateCrashed) {
253 LLDB_LOG(log, "process {0} is in state {1}. Resuming...",
254 m_session_data->m_debugger->GetProcess().GetProcessId(),
256
257 LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
258
259 bool failed = false;
260 for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
261 auto thread = std::static_pointer_cast<TargetThreadWindows>(
262 m_thread_list.GetThreadAtIndex(i));
263 Status result = thread->DoResume();
264 if (result.Fail()) {
265 failed = true;
266 LLDB_LOG(
267 log,
268 "Trying to resume thread at index {0}, but failed with error {1}.",
269 i, result);
270 }
271 }
272
273 if (failed) {
274 error = Status::FromErrorString("ProcessWindows::DoResume failed");
275 } else {
277 }
278
279 ExceptionRecordSP active_exception =
280 m_session_data->m_debugger->GetActiveException().lock();
281 if (active_exception) {
282 // Resume the process and continue processing debug events. Mask the
283 // exception so that from the process's view, there is no indication that
284 // anything happened.
285 m_session_data->m_debugger->ContinueAsyncException(
287 }
288 } else {
289 LLDB_LOG(log, "error: process {0} is in state {1}. Returning...",
290 m_session_data->m_debugger->GetProcess().GetProcessId(),
292 }
293 return error;
294}
295
297 StateType private_state = GetPrivateState();
298 return DestroyProcess(private_state);
299}
300
301Status ProcessWindows::DoHalt(bool &caused_stop) {
302 StateType state = GetPrivateState();
303 if (state != eStateStopped)
304 return HaltProcess(caused_stop);
305 caused_stop = false;
306 return Status();
307}
308
310 ArchSpec arch_spec;
311 DidAttach(arch_spec);
312}
313
315 llvm::sys::ScopedLock lock(m_mutex);
316
317 // The initial stop won't broadcast the state change event, so account for
318 // that here.
320 m_session_data->m_stop_at_entry)
322}
323
324static void
325DumpAdditionalExceptionInformation(llvm::raw_ostream &stream,
326 const ExceptionRecordSP &exception) {
327 // Decode additional exception information for specific exception types based
328 // on
329 // https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_exception_record
330
331 const int addr_min_width = 2 + 8; // "0x" + 4 address bytes
332
333 const std::vector<ULONG_PTR> &args = exception->GetExceptionArguments();
334 switch (exception->GetExceptionCode()) {
335 case EXCEPTION_ACCESS_VIOLATION: {
336 if (args.size() < 2)
337 break;
338
339 stream << ": ";
340 const int access_violation_code = args[0];
341 const lldb::addr_t access_violation_address = args[1];
342 switch (access_violation_code) {
343 case 0:
344 stream << "Access violation reading";
345 break;
346 case 1:
347 stream << "Access violation writing";
348 break;
349 case 8:
350 stream << "User-mode data execution prevention (DEP) violation at";
351 break;
352 default:
353 stream << "Unknown access violation (code " << access_violation_code
354 << ") at";
355 break;
356 }
357 stream << " location "
358 << llvm::format_hex(access_violation_address, addr_min_width);
359 break;
360 }
361 case EXCEPTION_IN_PAGE_ERROR: {
362 if (args.size() < 3)
363 break;
364
365 stream << ": ";
366 const int page_load_error_code = args[0];
367 const lldb::addr_t page_load_error_address = args[1];
368 const DWORD underlying_code = args[2];
369 switch (page_load_error_code) {
370 case 0:
371 stream << "In page error reading";
372 break;
373 case 1:
374 stream << "In page error writing";
375 break;
376 case 8:
377 stream << "User-mode data execution prevention (DEP) violation at";
378 break;
379 default:
380 stream << "Unknown page loading error (code " << page_load_error_code
381 << ") at";
382 break;
383 }
384 stream << " location "
385 << llvm::format_hex(page_load_error_address, addr_min_width)
386 << " (status code " << llvm::format_hex(underlying_code, 8) << ")";
387 break;
388 }
389 }
390}
391
394 llvm::sys::ScopedLock lock(m_mutex);
395
396 if (!m_session_data) {
397 LLDB_LOG(log, "no active session. Returning...");
398 return;
399 }
400
401 m_thread_list.RefreshStateAfterStop();
402
403 std::weak_ptr<ExceptionRecord> exception_record =
404 m_session_data->m_debugger->GetActiveException();
405 ExceptionRecordSP active_exception = exception_record.lock();
406 if (!active_exception) {
407 LLDB_LOG(log,
408 "there is no active exception in process {0}. Why is the "
409 "process stopped?",
410 m_session_data->m_debugger->GetProcess().GetProcessId());
411 return;
412 }
413
414 StopInfoSP stop_info;
415 m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
416 ThreadSP stop_thread = m_thread_list.GetSelectedThread();
417 if (!stop_thread)
418 return;
419
420 RegisterContextSP register_context = stop_thread->GetRegisterContext();
421 uint64_t pc = register_context->GetPC();
422
423 // If we're at a BreakpointSite, mark this as an Unexecuted Breakpoint.
424 // We'll clear that state if we've actually executed the breakpoint.
425 BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
426 if (site && site->IsEnabled())
427 stop_thread->SetThreadStoppedAtUnexecutedBP(pc);
428
429 switch (active_exception->GetExceptionCode()) {
430 case EXCEPTION_SINGLE_STEP: {
431 auto *reg_ctx = static_cast<RegisterContextWindows *>(
432 stop_thread->GetRegisterContext().get());
433 uint32_t slot_id = reg_ctx->GetTriggeredHardwareBreakpointSlotId();
434 if (slot_id != LLDB_INVALID_INDEX32) {
435 int id = m_watchpoint_ids[slot_id];
436 LLDB_LOG(log,
437 "Single-stepped onto a watchpoint in process {0} at address "
438 "{1:x} with watchpoint {2}",
439 m_session_data->m_debugger->GetProcess().GetProcessId(), pc, id);
440
441 stop_info = StopInfo::CreateStopReasonWithWatchpointID(*stop_thread, id);
442 stop_thread->SetStopInfo(stop_info);
443
444 return;
445 }
446
447 LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
448 stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
449 stop_thread->SetStopInfo(stop_info);
450
451 return;
452 }
453
454 case EXCEPTION_BREAKPOINT: {
455 int breakpoint_size = 1;
456 switch (GetTarget().GetArchitecture().GetMachine()) {
457 case llvm::Triple::aarch64:
458 breakpoint_size = 4;
459 break;
460
461 case llvm::Triple::arm:
462 case llvm::Triple::thumb:
463 breakpoint_size = 2;
464 break;
465
466 case llvm::Triple::x86:
467 case llvm::Triple::x86_64:
468 breakpoint_size = 1;
469 break;
470
471 default:
472 LLDB_LOG(log, "Unknown breakpoint size for architecture");
473 break;
474 }
475
476 // The current PC is AFTER the BP opcode, on all architectures.
477 pc = register_context->GetPC() - breakpoint_size;
478
480 if (site) {
481 LLDB_LOG(log,
482 "detected breakpoint in process {0} at address {1:x} with "
483 "breakpoint site {2}",
484 m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
485 site->GetID());
486
487 stop_thread->SetThreadHitBreakpointSite();
488 if (site->ValidForThisThread(*stop_thread)) {
489 LLDB_LOG(log,
490 "Breakpoint site {0} is valid for this thread ({1:x}), "
491 "creating stop info.",
492 site->GetID(), stop_thread->GetID());
493
495 *stop_thread, site->GetID());
496 register_context->SetPC(pc);
497 } else {
498 LLDB_LOG(log,
499 "Breakpoint site {0} is not valid for this thread, "
500 "creating empty stop info.",
501 site->GetID());
502 }
503 stop_thread->SetStopInfo(stop_info);
504 return;
505 } else {
506 // The thread hit a hard-coded breakpoint like an `int 3` or
507 // `__debugbreak()`.
508 LLDB_LOG(log,
509 "No breakpoint site matches for this thread. __debugbreak()? "
510 "Creating stop info with the exception.");
511 // FALLTHROUGH: We'll treat this as a generic exception record in the
512 // default case.
513 [[fallthrough]];
514 }
515 }
516
517 default: {
518 std::string desc;
519 llvm::raw_string_ostream desc_stream(desc);
520 desc_stream << "Exception "
521 << llvm::format_hex(active_exception->GetExceptionCode(), 8)
522 << " encountered at address "
523 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
524 DumpAdditionalExceptionInformation(desc_stream, active_exception);
525
526 stop_info =
527 StopInfo::CreateStopReasonWithException(*stop_thread, desc.c_str());
528 stop_thread->SetStopInfo(stop_info);
529 LLDB_LOG(log, "{0}", desc);
530 return;
531 }
532 }
533}
534
536 bool plugin_specified_by_name) {
537 if (plugin_specified_by_name)
538 return true;
539
540 // For now we are just making sure the file exists for a given module
541 ModuleSP exe_module_sp(target_sp->GetExecutableModule());
542 if (exe_module_sp.get())
543 return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec());
544 // However, if there is no executable module, we return true since we might
545 // be preparing to attach.
546 return true;
547}
548
550 ThreadList &new_thread_list) {
552 // Add all the threads that were previously running and for which we did not
553 // detect a thread exited event.
554 int new_size = 0;
555 int continued_threads = 0;
556 int exited_threads = 0;
557 int new_threads = 0;
558
559 for (ThreadSP old_thread : old_thread_list.Threads()) {
560 lldb::tid_t old_thread_id = old_thread->GetID();
561 auto exited_thread_iter =
562 m_session_data->m_exited_threads.find(old_thread_id);
563 if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
564 new_thread_list.AddThread(old_thread);
565 ++new_size;
566 ++continued_threads;
567 LLDB_LOGV(log, "Thread {0} was running and is still running.",
568 old_thread_id);
569 } else {
570 LLDB_LOGV(log, "Thread {0} was running and has exited.", old_thread_id);
571 ++exited_threads;
572 }
573 }
574
575 // Also add all the threads that are new since the last time we broke into
576 // the debugger.
577 for (const auto &thread_info : m_session_data->m_new_threads) {
578 new_thread_list.AddThread(thread_info.second);
579 ++new_size;
580 ++new_threads;
581 LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
582 }
583
584 LLDB_LOG(log, "{0} new threads, {1} old threads, {2} exited threads.",
585 new_threads, continued_threads, exited_threads);
586
587 m_session_data->m_new_threads.clear();
588 m_session_data->m_exited_threads.clear();
589
590 return new_size > 0;
591}
592
594 StateType state = GetPrivateState();
595 switch (state) {
596 case eStateCrashed:
597 case eStateDetached:
598 case eStateUnloaded:
599 case eStateExited:
600 case eStateInvalid:
601 return false;
602 default:
603 return true;
604 }
605}
606
608 return HostInfo::GetArchitecture();
609}
610
612 size_t size, Status &error) {
613 size_t bytes_read = 0;
614 error = ProcessDebugger::ReadMemory(vm_addr, buf, size, bytes_read);
615 return bytes_read;
616}
617
618size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
619 size_t size, Status &error) {
620 size_t bytes_written = 0;
621 error = ProcessDebugger::WriteMemory(vm_addr, buf, size, bytes_written);
622 return bytes_written;
623}
624
625lldb::addr_t ProcessWindows::DoAllocateMemory(size_t size, uint32_t permissions,
626 Status &error) {
628 error = ProcessDebugger::AllocateMemory(size, permissions, vm_addr);
629 return vm_addr;
630}
631
635
640
642 Target &target = GetTarget();
643 ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
644 Address addr = obj_file->GetImageInfoAddress(&target);
645 if (addr.IsValid())
646 return addr.GetLoadAddress(&target);
647 else
649}
650
657
658void ProcessWindows::OnExitProcess(uint32_t exit_code) {
659 // No need to acquire the lock since m_session_data isn't accessed.
661 LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
662
663 TargetSP target = CalculateTarget();
664 if (target) {
665 ModuleSP executable_module = target->GetExecutableModule();
666 ModuleList unloaded_modules;
667 unloaded_modules.Append(executable_module);
668 target->ModulesDidUnload(unloaded_modules, true);
669 }
670
671 SetExitStatus(exit_code, /*exit_string=*/"");
673
675}
676
678 DebuggerThreadSP debugger = m_session_data->m_debugger;
680 LLDB_LOG(log, "Debugger connected to process {0}. Image base = {1:x}",
681 debugger->GetProcess().GetProcessId(), image_base);
682
683 ModuleSP module;
684 // During attach, we won't have the executable module, so find it now.
685 const DWORD pid = debugger->GetProcess().GetProcessId();
686 const std::string file_name = GetProcessExecutableName(pid);
687 if (file_name.empty()) {
688 return;
689 }
690
691 FileSpec executable_file(file_name);
692 FileSystem::Instance().Resolve(executable_file);
693 ModuleSpec module_spec(executable_file);
695 module =
696 GetTarget().GetOrCreateModule(module_spec, true /* notify */, &error);
697 if (!module) {
698 return;
699 }
700
702
703 if (auto dyld = GetDynamicLoader())
704 dyld->OnLoadModule(module, ModuleSpec(), image_base);
705
706 // Add the main executable module to the list of pending module loads. We
707 // can't call GetTarget().ModulesDidLoad() here because we still haven't
708 // returned from DoLaunch() / DoAttach() yet so the target may not have set
709 // the process instance to `this` yet.
710 llvm::sys::ScopedLock lock(m_mutex);
711
712 const HostThread &host_main_thread = debugger->GetMainThread();
713 ThreadSP main_thread =
714 std::make_shared<TargetThreadWindows>(*this, host_main_thread);
715
716 tid_t id = host_main_thread.GetNativeThread().GetThreadId();
717 main_thread->SetID(id);
718
719 m_session_data->m_new_threads[id] = main_thread;
720}
721
724 const ExceptionRecord &record) {
726 llvm::sys::ScopedLock lock(m_mutex);
727
728 // FIXME: Without this check, occasionally when running the test suite there
729 // is
730 // an issue where m_session_data can be null. It's not clear how this could
731 // happen but it only surfaces while running the test suite. In order to
732 // properly diagnose this, we probably need to first figure allow the test
733 // suite to print out full lldb logs, and then add logging to the process
734 // plugin.
735 if (!m_session_data) {
736 LLDB_LOG(log,
737 "Debugger thread reported exception {0:x} at address {1:x}, "
738 "but there is no session.",
739 record.GetExceptionCode(), record.GetExceptionAddress());
741 }
742
743 if (!first_chance) {
744 // Not any second chance exception is an application crash by definition.
745 // It may be an expression evaluation crash.
747 }
748
750 switch (record.GetExceptionCode()) {
751 case EXCEPTION_BREAKPOINT:
752 // Handle breakpoints at the first chance.
754
755 if (!m_session_data->m_initial_stop_received) {
756 LLDB_LOG(
757 log,
758 "Hit loader breakpoint at address {0:x}, setting initial stop event.",
759 record.GetExceptionAddress());
760 m_session_data->m_initial_stop_received = true;
761 ::SetEvent(m_session_data->m_initial_stop_event);
762 } else {
763 LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
764 record.GetExceptionAddress());
765 }
767 break;
768 case EXCEPTION_SINGLE_STEP:
771 break;
772 default:
773 LLDB_LOG(log,
774 "Debugger thread reported exception {0:x} at address {1:x} "
775 "(first_chance={2})",
776 record.GetExceptionCode(), record.GetExceptionAddress(),
777 first_chance);
778 // For non-breakpoints, give the application a chance to handle the
779 // exception first.
780 if (first_chance)
782 else
784 }
785
786 return result;
787}
788
790 llvm::sys::ScopedLock lock(m_mutex);
791
792 ThreadSP thread = std::make_shared<TargetThreadWindows>(*this, new_thread);
793
794 const HostNativeThread &native_new_thread = new_thread.GetNativeThread();
795 tid_t id = native_new_thread.GetThreadId();
796 thread->SetID(id);
797
798 m_session_data->m_new_threads[id] = thread;
799
800 for (const std::map<int, WatchpointInfo>::value_type &p : m_watchpoints) {
801 auto *reg_ctx = static_cast<RegisterContextWindows *>(
802 thread->GetRegisterContext().get());
803 reg_ctx->AddHardwareBreakpoint(p.second.slot_id, p.second.address,
804 p.second.size, p.second.read,
805 p.second.write);
806 }
807}
808
809void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
810 llvm::sys::ScopedLock lock(m_mutex);
811
812 // On a forced termination, we may get exit thread events after the session
813 // data has been cleaned up.
814 if (!m_session_data)
815 return;
816
817 // A thread may have started and exited before the debugger stopped allowing a
818 // refresh.
819 // Just remove it from the new threads list in that case.
820 auto iter = m_session_data->m_new_threads.find(thread_id);
821 if (iter != m_session_data->m_new_threads.end())
822 m_session_data->m_new_threads.erase(iter);
823 else
824 m_session_data->m_exited_threads.insert(thread_id);
825}
826
827void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
828 lldb::addr_t module_addr) {
829 if (auto dyld = GetDynamicLoader())
830 dyld->OnLoadModule(nullptr, module_spec, module_addr);
831}
832
834 if (auto dyld = GetDynamicLoader())
835 dyld->OnUnloadModule(module_addr);
836}
837
838void ProcessWindows::OnDebugString(const std::string &string) {}
839
840void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) {
841 llvm::sys::ScopedLock lock(m_mutex);
843
844 if (m_session_data->m_initial_stop_received) {
845 // This happened while debugging. Do we shutdown the debugging session,
846 // try to continue, or do something else?
847 LLDB_LOG(log,
848 "Error {0} occurred during debugging. Unexpected behavior "
849 "may result. {1}",
850 error.GetError(), error);
851 } else {
852 // If we haven't actually launched the process yet, this was an error
853 // launching the process. Set the internal error and signal the initial
854 // stop event so that the DoLaunch method wakes up and returns a failure.
855 m_session_data->m_launch_error = error.Clone();
856 ::SetEvent(m_session_data->m_initial_stop_event);
857 LLDB_LOG(
858 log,
859 "Error {0} occurred launching the process before the initial stop. {1}",
860 error.GetError(), error);
861 return;
862 }
863}
864
868
871
872 if (wp_sp->IsEnabled()) {
873 wp_sp->SetEnabled(true, notify);
874 return error;
875 }
876
877 WatchpointInfo info;
878 for (info.slot_id = 0;
880 info.slot_id++)
882 break;
885 "Can't find free slot for watchpoint %i", wp_sp->GetID());
886 return error;
887 }
888 info.address = wp_sp->GetLoadAddress();
889 info.size = wp_sp->GetByteSize();
890 info.read = wp_sp->WatchpointRead();
891 info.write = wp_sp->WatchpointWrite() || wp_sp->WatchpointModify();
892
893 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
894 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
895 auto *reg_ctx = static_cast<RegisterContextWindows *>(
896 thread->GetRegisterContext().get());
897 if (!reg_ctx->AddHardwareBreakpoint(info.slot_id, info.address, info.size,
898 info.read, info.write)) {
900 "Can't enable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
901 thread->GetID());
902 break;
903 }
904 }
905 if (error.Fail()) {
906 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
907 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
908 auto *reg_ctx = static_cast<RegisterContextWindows *>(
909 thread->GetRegisterContext().get());
910 reg_ctx->RemoveHardwareBreakpoint(info.slot_id);
911 }
912 return error;
913 }
914
915 m_watchpoints[wp_sp->GetID()] = info;
916 m_watchpoint_ids[info.slot_id] = wp_sp->GetID();
917
918 wp_sp->SetEnabled(true, notify);
919
920 return error;
921}
922
925
926 if (!wp_sp->IsEnabled()) {
927 wp_sp->SetEnabled(false, notify);
928 return error;
929 }
930
931 auto it = m_watchpoints.find(wp_sp->GetID());
932 if (it == m_watchpoints.end()) {
934 "Info about watchpoint %i is not found", wp_sp->GetID());
935 return error;
936 }
937
938 for (unsigned i = 0U; i < m_thread_list.GetSize(); i++) {
939 Thread *thread = m_thread_list.GetThreadAtIndex(i).get();
940 auto *reg_ctx = static_cast<RegisterContextWindows *>(
941 thread->GetRegisterContext().get());
942 if (!reg_ctx->RemoveHardwareBreakpoint(it->second.slot_id)) {
944 "Can't disable watchpoint %i on thread 0x%llx", wp_sp->GetID(),
945 thread->GetID());
946 break;
947 }
948 }
949 if (error.Fail())
950 return error;
951
952 m_watchpoint_ids[it->second.slot_id] = LLDB_INVALID_BREAK_ID;
953 m_watchpoints.erase(it);
954
955 wp_sp->SetEnabled(false, notify);
956
957 return error;
958}
959} // 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_LOGV(log,...)
Definition Log.h:383
#define LLDB_PLUGIN_DEFINE_ADV(ClassName, PluginName)
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:31
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
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
bool Exists(const FileSpec &file_spec) const
Returns whether the given file exists.
static FileSystem & Instance()
HostNativeThread & GetNativeThread()
A collection class for Module objects.
Definition ModuleList.h:104
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:467
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, 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
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.
size_t PutSTDIN(const char *buf, size_t buf_size, Status &error) override
Puts data into this process's STDIN.
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.
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.
size_t GetSTDOUT(char *buf, size_t buf_size, Status &error) override
Get any available STDOUT.
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
size_t GetSTDERR(char *buf, size_t buf_size, Status &error) override
Get any available STDERR.
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
StopPointSiteList< lldb_private::BreakpointSite > & GetBreakpointSiteList()
Definition Process.cpp:1558
virtual Status DisableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1831
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:553
Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp)
Construct with a shared pointer to a target, and the Process listener.
Definition Process.cpp:426
lldb::StateType GetPrivateState()
Definition Process.cpp:1400
lldb::DynamicLoaderUP m_dyld_up
Definition Process.h:3220
lldb::TargetSP CalculateTarget() override
Definition Process.cpp:4536
virtual Status EnableSoftwareBreakpoint(BreakpointSite *bp_site)
Definition Process.cpp:1751
void SetID(lldb::pid_t new_pid)
Sets the stored pid.
Definition Process.h:558
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:1022
void SetPrivateState(lldb::StateType state)
Definition Process.cpp:1402
ThreadList m_thread_list
The threads for this process as the user will see them.
Definition Process.h:3193
friend class ThreadList
Definition Process.h:361
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1267
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:294
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:1524
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition Target.cpp:1575
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
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