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