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