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