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