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