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