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