1 //===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "ProcessWindows.h"
11 
12 // Windows includes
13 #include "lldb/Host/windows/windows.h"
14 #include <psapi.h>
15 
16 // Other libraries and framework includes
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/ModuleSpec.h"
19 #include "lldb/Core/PluginManager.h"
20 #include "lldb/Core/Section.h"
21 #include "lldb/Core/State.h"
22 #include "lldb/Host/HostNativeProcessBase.h"
23 #include "lldb/Host/HostProcess.h"
24 #include "lldb/Host/windows/HostThreadWindows.h"
25 #include "lldb/Host/windows/windows.h"
26 #include "lldb/Symbol/ObjectFile.h"
27 #include "lldb/Target/DynamicLoader.h"
28 #include "lldb/Target/MemoryRegionInfo.h"
29 #include "lldb/Target/StopInfo.h"
30 #include "lldb/Target/Target.h"
31 
32 #include "llvm/Support/ConvertUTF.h"
33 #include "llvm/Support/Format.h"
34 #include "llvm/Support/Threading.h"
35 #include "llvm/Support/raw_ostream.h"
36 
37 #include "DebuggerThread.h"
38 #include "ExceptionRecord.h"
39 #include "ForwardDecl.h"
40 #include "LocalDebugDelegate.h"
41 #include "ProcessWindowsLog.h"
42 #include "TargetThreadWindows.h"
43 
44 using namespace lldb;
45 using namespace lldb_private;
46 
47 namespace {
48 std::string GetProcessExecutableName(HANDLE process_handle) {
49   std::vector<wchar_t> file_name;
50   DWORD file_name_size = MAX_PATH; // first guess, not an absolute limit
51   DWORD copied = 0;
52   do {
53     file_name_size *= 2;
54     file_name.resize(file_name_size);
55     copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(),
56                                     file_name_size);
57   } while (copied >= file_name_size);
58   file_name.resize(copied);
59   std::string result;
60   llvm::convertWideToUTF8(file_name.data(), result);
61   return result;
62 }
63 
64 std::string GetProcessExecutableName(DWORD pid) {
65   std::string file_name;
66   HANDLE process_handle =
67       ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
68   if (process_handle != NULL) {
69     file_name = GetProcessExecutableName(process_handle);
70     ::CloseHandle(process_handle);
71   }
72   return file_name;
73 }
74 
75 } // anonymous namespace
76 
77 namespace lldb_private {
78 
79 // We store a pointer to this class in the ProcessWindows, so that we don't
80 // expose Windows-specific types and implementation details from a public
81 // header file.
82 class ProcessWindowsData {
83 public:
84   ProcessWindowsData(bool stop_at_entry) : m_stop_at_entry(stop_at_entry) {
85     m_initial_stop_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
86   }
87 
88   ~ProcessWindowsData() { ::CloseHandle(m_initial_stop_event); }
89 
90   Status m_launch_error;
91   DebuggerThreadSP m_debugger;
92   StopInfoSP m_pending_stop_info;
93   HANDLE m_initial_stop_event = nullptr;
94   bool m_initial_stop_received = false;
95   bool m_stop_at_entry;
96   std::map<lldb::tid_t, HostThread> m_new_threads;
97   std::set<lldb::tid_t> m_exited_threads;
98 };
99 
100 ProcessSP ProcessWindows::CreateInstance(lldb::TargetSP target_sp,
101                                          lldb::ListenerSP listener_sp,
102                                          const FileSpec *) {
103   return ProcessSP(new ProcessWindows(target_sp, listener_sp));
104 }
105 
106 void ProcessWindows::Initialize() {
107   static llvm::once_flag g_once_flag;
108 
109   llvm::call_once(g_once_flag, []() {
110     PluginManager::RegisterPlugin(GetPluginNameStatic(),
111                                   GetPluginDescriptionStatic(), CreateInstance);
112   });
113 }
114 
115 void ProcessWindows::Terminate() {}
116 
117 lldb_private::ConstString ProcessWindows::GetPluginNameStatic() {
118   static ConstString g_name("windows");
119   return g_name;
120 }
121 
122 const char *ProcessWindows::GetPluginDescriptionStatic() {
123   return "Process plugin for Windows";
124 }
125 
126 //------------------------------------------------------------------------------
127 // Constructors and destructors.
128 
129 ProcessWindows::ProcessWindows(lldb::TargetSP target_sp,
130                                lldb::ListenerSP listener_sp)
131     : lldb_private::Process(target_sp, listener_sp) {}
132 
133 ProcessWindows::~ProcessWindows() {}
134 
135 size_t ProcessWindows::GetSTDOUT(char *buf, size_t buf_size, Status &error) {
136   error.SetErrorString("GetSTDOUT unsupported on Windows");
137   return 0;
138 }
139 
140 size_t ProcessWindows::GetSTDERR(char *buf, size_t buf_size, Status &error) {
141   error.SetErrorString("GetSTDERR unsupported on Windows");
142   return 0;
143 }
144 
145 size_t ProcessWindows::PutSTDIN(const char *buf, size_t buf_size,
146                                 Status &error) {
147   error.SetErrorString("PutSTDIN unsupported on Windows");
148   return 0;
149 }
150 
151 //------------------------------------------------------------------------------
152 // ProcessInterface protocol.
153 
154 lldb_private::ConstString ProcessWindows::GetPluginName() {
155   return GetPluginNameStatic();
156 }
157 
158 uint32_t ProcessWindows::GetPluginVersion() { return 1; }
159 
160 Status ProcessWindows::EnableBreakpointSite(BreakpointSite *bp_site) {
161   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
162   LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
163            bp_site->GetID(), bp_site->GetLoadAddress());
164 
165   Status error = EnableSoftwareBreakpoint(bp_site);
166   if (!error.Success())
167     LLDB_LOG(log, "error: {0}", error);
168   return error;
169 }
170 
171 Status ProcessWindows::DisableBreakpointSite(BreakpointSite *bp_site) {
172   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_BREAKPOINTS);
173   LLDB_LOG(log, "bp_site = {0:x}, id={1}, addr={2:x}", bp_site,
174            bp_site->GetID(), bp_site->GetLoadAddress());
175 
176   Status error = DisableSoftwareBreakpoint(bp_site);
177 
178   if (!error.Success())
179     LLDB_LOG(log, "error: {0}", error);
180   return error;
181 }
182 
183 Status ProcessWindows::DoDetach(bool keep_stopped) {
184   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
185   DebuggerThreadSP debugger_thread;
186   StateType private_state;
187   {
188     // Acquire the lock only long enough to get the DebuggerThread.
189     // StopDebugging() will trigger a call back into ProcessWindows which will
190     // also acquire the lock.  Thus we have to release the lock before calling
191     // StopDebugging().
192     llvm::sys::ScopedLock lock(m_mutex);
193 
194     private_state = GetPrivateState();
195 
196     if (!m_session_data) {
197       LLDB_LOG(log, "state = {0}, but there is no active session.",
198                private_state);
199       return Status();
200     }
201 
202     debugger_thread = m_session_data->m_debugger;
203   }
204 
205   Status error;
206   if (private_state != eStateExited && private_state != eStateDetached) {
207     LLDB_LOG(log, "detaching from process {0} while state = {1}.",
208              debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
209              private_state);
210     error = debugger_thread->StopDebugging(false);
211     if (error.Success()) {
212       SetPrivateState(eStateDetached);
213     }
214 
215     // By the time StopDebugging returns, there is no more debugger thread, so
216     // we can be assured that no other thread will race for the session data.
217     m_session_data.reset();
218   } else {
219     LLDB_LOG(
220         log,
221         "error: process {0} in state = {1}, but cannot destroy in this state.",
222         debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
223         private_state);
224   }
225 
226   return error;
227 }
228 
229 Status ProcessWindows::DoLaunch(Module *exe_module,
230                                 ProcessLaunchInfo &launch_info) {
231   // Even though m_session_data is accessed here, it is before a debugger
232   // thread has been kicked off.  So there's no race conditions, and it
233   // shouldn't be necessary to acquire the mutex.
234 
235   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
236   Status result;
237   if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
238     StreamString stream;
239     stream.Printf("ProcessWindows unable to launch '%s'.  ProcessWindows can "
240                   "only be used for debug launches.",
241                   launch_info.GetExecutableFile().GetPath().c_str());
242     std::string message = stream.GetString();
243     result.SetErrorString(message.c_str());
244 
245     LLDB_LOG(log, "error: {0}", message);
246     return result;
247   }
248 
249   bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
250   m_session_data.reset(new ProcessWindowsData(stop_at_entry));
251 
252   SetPrivateState(eStateLaunching);
253   DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
254   m_session_data->m_debugger.reset(new DebuggerThread(delegate));
255   DebuggerThreadSP debugger = m_session_data->m_debugger;
256 
257   // Kick off the DebugLaunch asynchronously and wait for it to complete.
258   result = debugger->DebugLaunch(launch_info);
259   if (result.Fail()) {
260     LLDB_LOG(log, "failed launching '{0}'. {1}",
261              launch_info.GetExecutableFile().GetPath(), result);
262     return result;
263   }
264 
265   HostProcess process;
266   Status error = WaitForDebuggerConnection(debugger, process);
267   if (error.Fail()) {
268     LLDB_LOG(log, "failed launching '{0}'. {1}",
269              launch_info.GetExecutableFile().GetPath(), error);
270     return error;
271   }
272 
273   LLDB_LOG(log, "successfully launched '{0}'",
274            launch_info.GetExecutableFile().GetPath());
275 
276   // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the
277   // private state should already be set to eStateStopped as a result of
278   // hitting the initial breakpoint.  If it was not set, the breakpoint should
279   // have already been resumed from and the private state should already be
280   // eStateRunning.
281   launch_info.SetProcessID(process.GetProcessId());
282   SetID(process.GetProcessId());
283 
284   return result;
285 }
286 
287 Status
288 ProcessWindows::DoAttachToProcessWithID(lldb::pid_t pid,
289                                         const ProcessAttachInfo &attach_info) {
290   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
291   m_session_data.reset(
292       new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
293 
294   DebugDelegateSP delegate(new LocalDebugDelegate(shared_from_this()));
295   DebuggerThreadSP debugger(new DebuggerThread(delegate));
296 
297   m_session_data->m_debugger = debugger;
298 
299   DWORD process_id = static_cast<DWORD>(pid);
300   Status error = debugger->DebugAttach(process_id, attach_info);
301   if (error.Fail()) {
302     LLDB_LOG(
303         log,
304         "encountered an error occurred initiating the asynchronous attach. {0}",
305         error);
306     return error;
307   }
308 
309   HostProcess process;
310   error = WaitForDebuggerConnection(debugger, process);
311   if (error.Fail()) {
312     LLDB_LOG(log,
313              "encountered an error waiting for the debugger to connect. {0}",
314              error);
315     return error;
316   }
317 
318   LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
319 
320   // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the
321   // private state should already be set to eStateStopped as a result of
322   // hitting the initial breakpoint.  If it was not set, the breakpoint should
323   // have already been resumed from and the private state should already be
324   // eStateRunning.
325   SetID(process.GetProcessId());
326   return error;
327 }
328 
329 Status ProcessWindows::DoResume() {
330   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
331   llvm::sys::ScopedLock lock(m_mutex);
332   Status error;
333 
334   StateType private_state = GetPrivateState();
335   if (private_state == eStateStopped || private_state == eStateCrashed) {
336     LLDB_LOG(log, "process {0} is in state {1}.  Resuming...",
337              m_session_data->m_debugger->GetProcess().GetProcessId(),
338              GetPrivateState());
339 
340     ExceptionRecordSP active_exception =
341         m_session_data->m_debugger->GetActiveException().lock();
342     if (active_exception) {
343       // Resume the process and continue processing debug events.  Mask the
344       // exception so that from the process's view, there is no indication that
345       // anything happened.
346       m_session_data->m_debugger->ContinueAsyncException(
347           ExceptionResult::MaskException);
348     }
349 
350     LLDB_LOG(log, "resuming {0} threads.", m_thread_list.GetSize());
351 
352     for (uint32_t i = 0; i < m_thread_list.GetSize(); ++i) {
353       auto thread = std::static_pointer_cast<TargetThreadWindows>(
354           m_thread_list.GetThreadAtIndex(i));
355       thread->DoResume();
356     }
357 
358     SetPrivateState(eStateRunning);
359   } else {
360     LLDB_LOG(log, "error: process %I64u is in state %u.  Returning...",
361              m_session_data->m_debugger->GetProcess().GetProcessId(),
362              GetPrivateState());
363   }
364   return error;
365 }
366 
367 Status ProcessWindows::DoDestroy() {
368   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
369   DebuggerThreadSP debugger_thread;
370   StateType private_state;
371   {
372     // Acquire this lock inside an inner scope, only long enough to get the
373     // DebuggerThread. StopDebugging() will trigger a call back into
374     // ProcessWindows which will acquire the lock again, so we need to not
375     // deadlock.
376     llvm::sys::ScopedLock lock(m_mutex);
377 
378     private_state = GetPrivateState();
379 
380     if (!m_session_data) {
381       LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
382                private_state);
383       return Status();
384     }
385 
386     debugger_thread = m_session_data->m_debugger;
387   }
388 
389   Status error;
390   if (private_state != eStateExited && private_state != eStateDetached) {
391     LLDB_LOG(log, "Shutting down process {0} while state = {1}.",
392              debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
393              private_state);
394     error = debugger_thread->StopDebugging(true);
395 
396     // By the time StopDebugging returns, there is no more debugger thread, so
397     // we can be assured that no other thread will race for the session data.
398     m_session_data.reset();
399   } else {
400     LLDB_LOG(log, "cannot destroy process {0} while state = {1}",
401              debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle(),
402              private_state);
403   }
404 
405   return error;
406 }
407 
408 Status ProcessWindows::DoHalt(bool &caused_stop) {
409   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
410   Status error;
411   StateType state = GetPrivateState();
412   if (state == eStateStopped)
413     caused_stop = false;
414   else {
415     llvm::sys::ScopedLock lock(m_mutex);
416     caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
417                                           .GetNativeProcess()
418                                           .GetSystemHandle());
419     if (!caused_stop) {
420       error.SetError(::GetLastError(), eErrorTypeWin32);
421       LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
422     }
423   }
424   return error;
425 }
426 
427 void ProcessWindows::DidLaunch() {
428   ArchSpec arch_spec;
429   DidAttach(arch_spec);
430 }
431 
432 void ProcessWindows::DidAttach(ArchSpec &arch_spec) {
433   llvm::sys::ScopedLock lock(m_mutex);
434 
435   // The initial stop won't broadcast the state change event, so account for
436   // that here.
437   if (m_session_data && GetPrivateState() == eStateStopped &&
438       m_session_data->m_stop_at_entry)
439     RefreshStateAfterStop();
440 }
441 
442 void ProcessWindows::RefreshStateAfterStop() {
443   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
444   llvm::sys::ScopedLock lock(m_mutex);
445 
446   if (!m_session_data) {
447     LLDB_LOG(log, "no active session.  Returning...");
448     return;
449   }
450 
451   m_thread_list.RefreshStateAfterStop();
452 
453   std::weak_ptr<ExceptionRecord> exception_record =
454       m_session_data->m_debugger->GetActiveException();
455   ExceptionRecordSP active_exception = exception_record.lock();
456   if (!active_exception) {
457     LLDB_LOG(log, "there is no active exception in process {0}.  Why is the "
458                   "process stopped?",
459              m_session_data->m_debugger->GetProcess().GetProcessId());
460     return;
461   }
462 
463   StopInfoSP stop_info;
464   m_thread_list.SetSelectedThreadByID(active_exception->GetThreadID());
465   ThreadSP stop_thread = m_thread_list.GetSelectedThread();
466   if (!stop_thread)
467     return;
468 
469   switch (active_exception->GetExceptionCode()) {
470   case EXCEPTION_SINGLE_STEP: {
471     RegisterContextSP register_context = stop_thread->GetRegisterContext();
472     const uint64_t pc = register_context->GetPC();
473     BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
474     if (site && site->ValidForThisThread(stop_thread.get())) {
475       LLDB_LOG(log, "Single-stepped onto a breakpoint in process {0} at "
476                     "address {1:x} with breakpoint site {2}",
477                m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
478                site->GetID());
479       stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(*stop_thread,
480                                                                  site->GetID());
481       stop_thread->SetStopInfo(stop_info);
482     } else {
483       LLDB_LOG(log, "single stepping thread {0}", stop_thread->GetID());
484       stop_info = StopInfo::CreateStopReasonToTrace(*stop_thread);
485       stop_thread->SetStopInfo(stop_info);
486     }
487     return;
488   }
489 
490   case EXCEPTION_BREAKPOINT: {
491     RegisterContextSP register_context = stop_thread->GetRegisterContext();
492 
493     // The current EIP is AFTER the BP opcode, which is one byte.
494     uint64_t pc = register_context->GetPC() - 1;
495 
496     BreakpointSiteSP site(GetBreakpointSiteList().FindByAddress(pc));
497     if (site) {
498       LLDB_LOG(log, "detected breakpoint in process {0} at address {1:x} with "
499                     "breakpoint site {2}",
500                m_session_data->m_debugger->GetProcess().GetProcessId(), pc,
501                site->GetID());
502 
503       if (site->ValidForThisThread(stop_thread.get())) {
504         LLDB_LOG(log, "Breakpoint site {0} is valid for this thread ({1:x}), "
505                       "creating stop info.",
506                  site->GetID(), stop_thread->GetID());
507 
508         stop_info = StopInfo::CreateStopReasonWithBreakpointSiteID(
509             *stop_thread, site->GetID());
510         register_context->SetPC(pc);
511       } else {
512         LLDB_LOG(log, "Breakpoint site {0} is not valid for this thread, "
513                       "creating empty stop info.",
514                  site->GetID());
515       }
516       stop_thread->SetStopInfo(stop_info);
517       return;
518     } else {
519       // The thread hit a hard-coded breakpoint like an `int 3` or
520       // `__debugbreak()`.
521       LLDB_LOG(log,
522                "No breakpoint site matches for this thread. __debugbreak()?  "
523                "Creating stop info with the exception.");
524       // FALLTHROUGH:  We'll treat this as a generic exception record in the
525       // default case.
526     }
527   }
528 
529   default: {
530     std::string desc;
531     llvm::raw_string_ostream desc_stream(desc);
532     desc_stream << "Exception "
533                 << llvm::format_hex(active_exception->GetExceptionCode(), 8)
534                 << " encountered at address "
535                 << llvm::format_hex(active_exception->GetExceptionAddress(), 8);
536     stop_info = StopInfo::CreateStopReasonWithException(
537         *stop_thread, desc_stream.str().c_str());
538     stop_thread->SetStopInfo(stop_info);
539     LLDB_LOG(log, "{0}", desc_stream.str());
540     return;
541   }
542   }
543 }
544 
545 bool ProcessWindows::CanDebug(lldb::TargetSP target_sp,
546                               bool plugin_specified_by_name) {
547   if (plugin_specified_by_name)
548     return true;
549 
550   // For now we are just making sure the file exists for a given module
551   ModuleSP exe_module_sp(target_sp->GetExecutableModule());
552   if (exe_module_sp.get())
553     return exe_module_sp->GetFileSpec().Exists();
554   // However, if there is no executable module, we return true since we might
555   // be preparing to attach.
556   return true;
557 }
558 
559 bool ProcessWindows::UpdateThreadList(ThreadList &old_thread_list,
560                                       ThreadList &new_thread_list) {
561   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_THREAD);
562   // Add all the threads that were previously running and for which we did not
563   // detect a thread exited event.
564   int new_size = 0;
565   int continued_threads = 0;
566   int exited_threads = 0;
567   int new_threads = 0;
568 
569   for (ThreadSP old_thread : old_thread_list.Threads()) {
570     lldb::tid_t old_thread_id = old_thread->GetID();
571     auto exited_thread_iter =
572         m_session_data->m_exited_threads.find(old_thread_id);
573     if (exited_thread_iter == m_session_data->m_exited_threads.end()) {
574       new_thread_list.AddThread(old_thread);
575       ++new_size;
576       ++continued_threads;
577       LLDB_LOGV(log, "Thread {0} was running and is still running.",
578                 old_thread_id);
579     } else {
580       LLDB_LOGV(log, "Thread {0} was running and has exited.", old_thread_id);
581       ++exited_threads;
582     }
583   }
584 
585   // Also add all the threads that are new since the last time we broke into
586   // the debugger.
587   for (const auto &thread_info : m_session_data->m_new_threads) {
588     ThreadSP thread(new TargetThreadWindows(*this, thread_info.second));
589     thread->SetID(thread_info.first);
590     new_thread_list.AddThread(thread);
591     ++new_size;
592     ++new_threads;
593     LLDB_LOGV(log, "Thread {0} is new since last update.", thread_info.first);
594   }
595 
596   LLDB_LOG(log, "{0} new threads, {1} old threads, {2} exited threads.",
597            new_threads, continued_threads, exited_threads);
598 
599   m_session_data->m_new_threads.clear();
600   m_session_data->m_exited_threads.clear();
601 
602   return new_size > 0;
603 }
604 
605 bool ProcessWindows::IsAlive() {
606   StateType state = GetPrivateState();
607   switch (state) {
608   case eStateCrashed:
609   case eStateDetached:
610   case eStateUnloaded:
611   case eStateExited:
612   case eStateInvalid:
613     return false;
614   default:
615     return true;
616   }
617 }
618 
619 size_t ProcessWindows::DoReadMemory(lldb::addr_t vm_addr, void *buf,
620                                     size_t size, Status &error) {
621   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
622   llvm::sys::ScopedLock lock(m_mutex);
623 
624   if (!m_session_data)
625     return 0;
626 
627   LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
628            vm_addr);
629 
630   HostProcess process = m_session_data->m_debugger->GetProcess();
631   void *addr = reinterpret_cast<void *>(vm_addr);
632   SIZE_T bytes_read = 0;
633   if (!ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
634                          buf, size, &bytes_read)) {
635     error.SetError(GetLastError(), eErrorTypeWin32);
636     LLDB_LOG(log, "reading failed with error: {0}", error);
637   }
638   return bytes_read;
639 }
640 
641 size_t ProcessWindows::DoWriteMemory(lldb::addr_t vm_addr, const void *buf,
642                                      size_t size, Status &error) {
643   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
644   llvm::sys::ScopedLock lock(m_mutex);
645   LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
646            vm_addr);
647 
648   if (!m_session_data) {
649     LLDB_LOG(log, "cannot write, there is no active debugger connection.");
650     return 0;
651   }
652 
653   HostProcess process = m_session_data->m_debugger->GetProcess();
654   void *addr = reinterpret_cast<void *>(vm_addr);
655   SIZE_T bytes_written = 0;
656   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
657   if (WriteProcessMemory(handle, addr, buf, size, &bytes_written))
658     FlushInstructionCache(handle, addr, bytes_written);
659   else {
660     error.SetError(GetLastError(), eErrorTypeWin32);
661     LLDB_LOG(log, "writing failed with error: {0}", error);
662   }
663   return bytes_written;
664 }
665 
666 Status ProcessWindows::GetMemoryRegionInfo(lldb::addr_t vm_addr,
667                                            MemoryRegionInfo &info) {
668   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
669   Status error;
670   llvm::sys::ScopedLock lock(m_mutex);
671   info.Clear();
672 
673   if (!m_session_data) {
674     error.SetErrorString(
675         "GetMemoryRegionInfo called with no debugging session.");
676     LLDB_LOG(log, "error: {0}", error);
677     return error;
678   }
679   HostProcess process = m_session_data->m_debugger->GetProcess();
680   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
681   if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
682     error.SetErrorString(
683         "GetMemoryRegionInfo called with an invalid target process.");
684     LLDB_LOG(log, "error: {0}", error);
685     return error;
686   }
687 
688   LLDB_LOG(log, "getting info for address {0:x}", vm_addr);
689 
690   void *addr = reinterpret_cast<void *>(vm_addr);
691   MEMORY_BASIC_INFORMATION mem_info = {};
692   SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
693   if (result == 0) {
694     if (::GetLastError() == ERROR_INVALID_PARAMETER) {
695       // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
696       // an address past the highest accessible address. We should return a
697       // range from the vm_addr to LLDB_INVALID_ADDRESS
698       info.GetRange().SetRangeBase(vm_addr);
699       info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
700       info.SetReadable(MemoryRegionInfo::eNo);
701       info.SetExecutable(MemoryRegionInfo::eNo);
702       info.SetWritable(MemoryRegionInfo::eNo);
703       info.SetMapped(MemoryRegionInfo::eNo);
704       return error;
705     } else {
706       error.SetError(::GetLastError(), eErrorTypeWin32);
707       LLDB_LOG(log, "VirtualQueryEx returned error {0} while getting memory "
708                     "region info for address {1:x}",
709                error, vm_addr);
710       return error;
711     }
712   }
713 
714   // Protect bits are only valid for MEM_COMMIT regions.
715   if (mem_info.State == MEM_COMMIT) {
716     const bool readable = IsPageReadable(mem_info.Protect);
717     const bool executable = IsPageExecutable(mem_info.Protect);
718     const bool writable = IsPageWritable(mem_info.Protect);
719     info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
720     info.SetExecutable(executable ? MemoryRegionInfo::eYes
721                                   : MemoryRegionInfo::eNo);
722     info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
723   } else {
724     info.SetReadable(MemoryRegionInfo::eNo);
725     info.SetExecutable(MemoryRegionInfo::eNo);
726     info.SetWritable(MemoryRegionInfo::eNo);
727   }
728 
729   // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
730   if (mem_info.State != MEM_FREE) {
731     info.GetRange().SetRangeBase(
732         reinterpret_cast<addr_t>(mem_info.AllocationBase));
733     info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
734                                 mem_info.RegionSize);
735     info.SetMapped(MemoryRegionInfo::eYes);
736   } else {
737     // In the unmapped case we need to return the distance to the next block of
738     // memory. VirtualQueryEx nearly does that except that it gives the
739     // distance from the start of the page containing vm_addr.
740     SYSTEM_INFO data;
741     GetSystemInfo(&data);
742     DWORD page_offset = vm_addr % data.dwPageSize;
743     info.GetRange().SetRangeBase(vm_addr);
744     info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
745     info.SetMapped(MemoryRegionInfo::eNo);
746   }
747 
748   error.SetError(::GetLastError(), eErrorTypeWin32);
749   LLDB_LOGV(log, "Memory region info for address {0}: readable={1}, "
750                  "executable={2}, writable={3}",
751             vm_addr, info.GetReadable(), info.GetExecutable(),
752             info.GetWritable());
753   return error;
754 }
755 
756 lldb::addr_t ProcessWindows::GetImageInfoAddress() {
757   Target &target = GetTarget();
758   ObjectFile *obj_file = target.GetExecutableModule()->GetObjectFile();
759   Address addr = obj_file->GetImageInfoAddress(&target);
760   if (addr.IsValid())
761     return addr.GetLoadAddress(&target);
762   else
763     return LLDB_INVALID_ADDRESS;
764 }
765 
766 void ProcessWindows::OnExitProcess(uint32_t exit_code) {
767   // No need to acquire the lock since m_session_data isn't accessed.
768   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
769   LLDB_LOG(log, "Process {0} exited with code {1}", GetID(), exit_code);
770 
771   TargetSP target = m_target_sp.lock();
772   if (target) {
773     ModuleSP executable_module = target->GetExecutableModule();
774     ModuleList unloaded_modules;
775     unloaded_modules.Append(executable_module);
776     target->ModulesDidUnload(unloaded_modules, true);
777   }
778 
779   SetProcessExitStatus(GetID(), true, 0, exit_code);
780   SetPrivateState(eStateExited);
781 }
782 
783 void ProcessWindows::OnDebuggerConnected(lldb::addr_t image_base) {
784   DebuggerThreadSP debugger = m_session_data->m_debugger;
785   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
786   LLDB_LOG(log, "Debugger connected to process {0}.  Image base = {1:x}",
787            debugger->GetProcess().GetProcessId(), image_base);
788 
789   ModuleSP module = GetTarget().GetExecutableModule();
790   if (!module) {
791     // During attach, we won't have the executable module, so find it now.
792     const DWORD pid = debugger->GetProcess().GetProcessId();
793     const std::string file_name = GetProcessExecutableName(pid);
794     if (file_name.empty()) {
795       return;
796     }
797 
798     FileSpec executable_file(file_name, true);
799     ModuleSpec module_spec(executable_file);
800     Status error;
801     module = GetTarget().GetSharedModule(module_spec, &error);
802     if (!module) {
803       return;
804     }
805 
806     GetTarget().SetExecutableModule(module, false);
807   }
808 
809   bool load_addr_changed;
810   module->SetLoadAddress(GetTarget(), image_base, false, load_addr_changed);
811 
812   ModuleList loaded_modules;
813   loaded_modules.Append(module);
814   GetTarget().ModulesDidLoad(loaded_modules);
815 
816   // Add the main executable module to the list of pending module loads.  We
817   // can't call GetTarget().ModulesDidLoad() here because we still haven't
818   // returned from DoLaunch() / DoAttach() yet so the target may not have set
819   // the process instance to `this` yet.
820   llvm::sys::ScopedLock lock(m_mutex);
821   const HostThreadWindows &wmain_thread =
822       debugger->GetMainThread().GetNativeThread();
823   m_session_data->m_new_threads[wmain_thread.GetThreadId()] =
824       debugger->GetMainThread();
825 }
826 
827 ExceptionResult
828 ProcessWindows::OnDebugException(bool first_chance,
829                                  const ExceptionRecord &record) {
830   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
831   llvm::sys::ScopedLock lock(m_mutex);
832 
833   // FIXME: Without this check, occasionally when running the test suite there
834   // is
835   // an issue where m_session_data can be null.  It's not clear how this could
836   // happen but it only surfaces while running the test suite.  In order to
837   // properly diagnose this, we probably need to first figure allow the test
838   // suite to print out full lldb logs, and then add logging to the process
839   // plugin.
840   if (!m_session_data) {
841     LLDB_LOG(log, "Debugger thread reported exception {0:x} at address {1:x}, "
842                   "but there is no session.",
843              record.GetExceptionCode(), record.GetExceptionAddress());
844     return ExceptionResult::SendToApplication;
845   }
846 
847   if (!first_chance) {
848     // Any second chance exception is an application crash by definition.
849     SetPrivateState(eStateCrashed);
850   }
851 
852   ExceptionResult result = ExceptionResult::SendToApplication;
853   switch (record.GetExceptionCode()) {
854   case EXCEPTION_BREAKPOINT:
855     // Handle breakpoints at the first chance.
856     result = ExceptionResult::BreakInDebugger;
857 
858     if (!m_session_data->m_initial_stop_received) {
859       LLDB_LOG(
860           log,
861           "Hit loader breakpoint at address {0:x}, setting initial stop event.",
862           record.GetExceptionAddress());
863       m_session_data->m_initial_stop_received = true;
864       ::SetEvent(m_session_data->m_initial_stop_event);
865     } else {
866       LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
867                record.GetExceptionAddress());
868     }
869     SetPrivateState(eStateStopped);
870     break;
871   case EXCEPTION_SINGLE_STEP:
872     result = ExceptionResult::BreakInDebugger;
873     SetPrivateState(eStateStopped);
874     break;
875   default:
876     LLDB_LOG(log, "Debugger thread reported exception {0:x} at address {1:x} "
877                   "(first_chance={2})",
878              record.GetExceptionCode(), record.GetExceptionAddress(),
879              first_chance);
880     // For non-breakpoints, give the application a chance to handle the
881     // exception first.
882     if (first_chance)
883       result = ExceptionResult::SendToApplication;
884     else
885       result = ExceptionResult::BreakInDebugger;
886   }
887 
888   return result;
889 }
890 
891 void ProcessWindows::OnCreateThread(const HostThread &new_thread) {
892   llvm::sys::ScopedLock lock(m_mutex);
893   const HostThreadWindows &wnew_thread = new_thread.GetNativeThread();
894   m_session_data->m_new_threads[wnew_thread.GetThreadId()] = new_thread;
895 }
896 
897 void ProcessWindows::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
898   llvm::sys::ScopedLock lock(m_mutex);
899 
900   // On a forced termination, we may get exit thread events after the session
901   // data has been cleaned up.
902   if (!m_session_data)
903     return;
904 
905   // A thread may have started and exited before the debugger stopped allowing a
906   // refresh.
907   // Just remove it from the new threads list in that case.
908   auto iter = m_session_data->m_new_threads.find(thread_id);
909   if (iter != m_session_data->m_new_threads.end())
910     m_session_data->m_new_threads.erase(iter);
911   else
912     m_session_data->m_exited_threads.insert(thread_id);
913 }
914 
915 void ProcessWindows::OnLoadDll(const ModuleSpec &module_spec,
916                                lldb::addr_t module_addr) {
917   // Confusingly, there is no Target::AddSharedModule.  Instead, calling
918   // GetSharedModule() with a new module will add it to the module list and
919   // return a corresponding ModuleSP.
920   Status error;
921   ModuleSP module = GetTarget().GetSharedModule(module_spec, &error);
922   bool load_addr_changed = false;
923   module->SetLoadAddress(GetTarget(), module_addr, false, load_addr_changed);
924 
925   ModuleList loaded_modules;
926   loaded_modules.Append(module);
927   GetTarget().ModulesDidLoad(loaded_modules);
928 }
929 
930 void ProcessWindows::OnUnloadDll(lldb::addr_t module_addr) {
931   Address resolved_addr;
932   if (GetTarget().ResolveLoadAddress(module_addr, resolved_addr)) {
933     ModuleSP module = resolved_addr.GetModule();
934     if (module) {
935       ModuleList unloaded_modules;
936       unloaded_modules.Append(module);
937       GetTarget().ModulesDidUnload(unloaded_modules, false);
938     }
939   }
940 }
941 
942 void ProcessWindows::OnDebugString(const std::string &string) {}
943 
944 void ProcessWindows::OnDebuggerError(const Status &error, uint32_t type) {
945   llvm::sys::ScopedLock lock(m_mutex);
946   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
947 
948   if (m_session_data->m_initial_stop_received) {
949     // This happened while debugging.  Do we shutdown the debugging session,
950     // try to continue, or do something else?
951     LLDB_LOG(log, "Error {0} occurred during debugging.  Unexpected behavior "
952                   "may result.  {1}",
953              error.GetError(), error);
954   } else {
955     // If we haven't actually launched the process yet, this was an error
956     // launching the process.  Set the internal error and signal the initial
957     // stop event so that the DoLaunch method wakes up and returns a failure.
958     m_session_data->m_launch_error = error;
959     ::SetEvent(m_session_data->m_initial_stop_event);
960     LLDB_LOG(
961         log,
962         "Error {0} occurred launching the process before the initial stop. {1}",
963         error.GetError(), error);
964     return;
965   }
966 }
967 
968 Status ProcessWindows::WaitForDebuggerConnection(DebuggerThreadSP debugger,
969                                                  HostProcess &process) {
970   Status result;
971   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
972                                             WINDOWS_LOG_BREAKPOINTS);
973   LLDB_LOG(log, "Waiting for loader breakpoint.");
974 
975   // Block this function until we receive the initial stop from the process.
976   if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
977       WAIT_OBJECT_0) {
978     LLDB_LOG(log, "hit loader breakpoint, returning.");
979 
980     process = debugger->GetProcess();
981     return m_session_data->m_launch_error;
982   } else
983     return Status(::GetLastError(), eErrorTypeWin32);
984 }
985 
986 // The Windows page protection bits are NOT independent masks that can be
987 // bitwise-ORed together.  For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
988 // | PAGE_READ).  To test for an access type, it's necessary to test for any of
989 // the bits that provide that access type.
990 bool ProcessWindows::IsPageReadable(uint32_t protect) {
991   return (protect & PAGE_NOACCESS) == 0;
992 }
993 
994 bool ProcessWindows::IsPageWritable(uint32_t protect) {
995   return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
996                      PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
997 }
998 
999 bool ProcessWindows::IsPageExecutable(uint32_t protect) {
1000   return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
1001                      PAGE_EXECUTE_WRITECOPY)) != 0;
1002 }
1003 
1004 } // namespace lldb_private
1005