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