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