• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- ProcessDebugger.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 "ProcessDebugger.h"
10 
11 // Windows includes
12 #include "lldb/Host/windows/windows.h"
13 #include <psapi.h>
14 
15 #include "lldb/Host/FileSystem.h"
16 #include "lldb/Host/HostNativeProcessBase.h"
17 #include "lldb/Host/HostProcess.h"
18 #include "lldb/Host/HostThread.h"
19 #include "lldb/Host/ProcessLaunchInfo.h"
20 #include "lldb/Target/MemoryRegionInfo.h"
21 #include "lldb/Target/Process.h"
22 #include "llvm/Support/ConvertUTF.h"
23 #include "llvm/Support/Error.h"
24 
25 #include "DebuggerThread.h"
26 #include "ExceptionRecord.h"
27 #include "ProcessWindowsLog.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
ConvertLldbToWinApiProtect(uint32_t protect)32 static DWORD ConvertLldbToWinApiProtect(uint32_t protect) {
33   // We also can process a read / write permissions here, but if the debugger
34   // will make later a write into the allocated memory, it will fail. To get
35   // around it is possible inside DoWriteMemory to remember memory permissions,
36   // allow write, write and restore permissions, but for now we process only
37   // the executable permission.
38   //
39   // TODO: Process permissions other than executable
40   if (protect & ePermissionsExecutable)
41     return PAGE_EXECUTE_READWRITE;
42 
43   return PAGE_READWRITE;
44 }
45 
46 // The Windows page protection bits are NOT independent masks that can be
47 // bitwise-ORed together.  For example, PAGE_EXECUTE_READ is not (PAGE_EXECUTE
48 // | PAGE_READ).  To test for an access type, it's necessary to test for any of
49 // the bits that provide that access type.
IsPageReadable(uint32_t protect)50 static bool IsPageReadable(uint32_t protect) {
51   return (protect & PAGE_NOACCESS) == 0;
52 }
53 
IsPageWritable(uint32_t protect)54 static bool IsPageWritable(uint32_t protect) {
55   return (protect & (PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY |
56                      PAGE_READWRITE | PAGE_WRITECOPY)) != 0;
57 }
58 
IsPageExecutable(uint32_t protect)59 static bool IsPageExecutable(uint32_t protect) {
60   return (protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE |
61                      PAGE_EXECUTE_WRITECOPY)) != 0;
62 }
63 
64 namespace lldb_private {
65 
~ProcessDebugger()66 ProcessDebugger::~ProcessDebugger() {}
67 
GetDebuggedProcessId() const68 lldb::pid_t ProcessDebugger::GetDebuggedProcessId() const {
69   if (m_session_data)
70     return m_session_data->m_debugger->GetProcess().GetProcessId();
71   return LLDB_INVALID_PROCESS_ID;
72 }
73 
DetachProcess()74 Status ProcessDebugger::DetachProcess() {
75   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
76   DebuggerThreadSP debugger_thread;
77   {
78     // Acquire the lock only long enough to get the DebuggerThread.
79     // StopDebugging() will trigger a call back into ProcessDebugger which will
80     // also acquire the lock.  Thus we have to release the lock before calling
81     // StopDebugging().
82     llvm::sys::ScopedLock lock(m_mutex);
83 
84     if (!m_session_data) {
85       LLDB_LOG(log, "there is no active session.");
86       return Status();
87     }
88 
89     debugger_thread = m_session_data->m_debugger;
90   }
91 
92   Status error;
93 
94   LLDB_LOG(log, "detaching from process {0}.",
95            debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
96   error = debugger_thread->StopDebugging(false);
97 
98   // By the time StopDebugging returns, there is no more debugger thread, so
99   // we can be assured that no other thread will race for the session data.
100   m_session_data.reset();
101 
102   return error;
103 }
104 
LaunchProcess(ProcessLaunchInfo & launch_info,DebugDelegateSP delegate)105 Status ProcessDebugger::LaunchProcess(ProcessLaunchInfo &launch_info,
106                                       DebugDelegateSP delegate) {
107   // Even though m_session_data is accessed here, it is before a debugger
108   // thread has been kicked off.  So there's no race conditions, and it
109   // shouldn't be necessary to acquire the mutex.
110 
111   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
112   Status result;
113 
114   FileSpec working_dir = launch_info.GetWorkingDirectory();
115   namespace fs = llvm::sys::fs;
116   if (working_dir) {
117     FileSystem::Instance().Resolve(working_dir);
118     if (!FileSystem::Instance().IsDirectory(working_dir)) {
119       result.SetErrorStringWithFormat("No such file or directory: %s",
120                                       working_dir.GetCString());
121       return result;
122     }
123   }
124 
125   if (!launch_info.GetFlags().Test(eLaunchFlagDebug)) {
126     StreamString stream;
127     stream.Printf("ProcessDebugger unable to launch '%s'.  ProcessDebugger can "
128                   "only be used for debug launches.",
129                   launch_info.GetExecutableFile().GetPath().c_str());
130     std::string message = stream.GetString().str();
131     result.SetErrorString(message.c_str());
132 
133     LLDB_LOG(log, "error: {0}", message);
134     return result;
135   }
136 
137   bool stop_at_entry = launch_info.GetFlags().Test(eLaunchFlagStopAtEntry);
138   m_session_data.reset(new ProcessWindowsData(stop_at_entry));
139   m_session_data->m_debugger.reset(new DebuggerThread(delegate));
140   DebuggerThreadSP debugger = m_session_data->m_debugger;
141 
142   // Kick off the DebugLaunch asynchronously and wait for it to complete.
143   result = debugger->DebugLaunch(launch_info);
144   if (result.Fail()) {
145     LLDB_LOG(log, "failed launching '{0}'. {1}",
146              launch_info.GetExecutableFile().GetPath(), result);
147     return result;
148   }
149 
150   HostProcess process;
151   Status error = WaitForDebuggerConnection(debugger, process);
152   if (error.Fail()) {
153     LLDB_LOG(log, "failed launching '{0}'. {1}",
154              launch_info.GetExecutableFile().GetPath(), error);
155     return error;
156   }
157 
158   LLDB_LOG(log, "successfully launched '{0}'",
159            launch_info.GetExecutableFile().GetPath());
160 
161   // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the
162   // private state should already be set to eStateStopped as a result of
163   // hitting the initial breakpoint.  If it was not set, the breakpoint should
164   // have already been resumed from and the private state should already be
165   // eStateRunning.
166   launch_info.SetProcessID(process.GetProcessId());
167 
168   return result;
169 }
170 
AttachProcess(lldb::pid_t pid,const ProcessAttachInfo & attach_info,DebugDelegateSP delegate)171 Status ProcessDebugger::AttachProcess(lldb::pid_t pid,
172                                       const ProcessAttachInfo &attach_info,
173                                       DebugDelegateSP delegate) {
174   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
175   m_session_data.reset(
176       new ProcessWindowsData(!attach_info.GetContinueOnceAttached()));
177   DebuggerThreadSP debugger(new DebuggerThread(delegate));
178 
179   m_session_data->m_debugger = debugger;
180 
181   DWORD process_id = static_cast<DWORD>(pid);
182   Status error = debugger->DebugAttach(process_id, attach_info);
183   if (error.Fail()) {
184     LLDB_LOG(
185         log,
186         "encountered an error occurred initiating the asynchronous attach. {0}",
187         error);
188     return error;
189   }
190 
191   HostProcess process;
192   error = WaitForDebuggerConnection(debugger, process);
193   if (error.Fail()) {
194     LLDB_LOG(log,
195              "encountered an error waiting for the debugger to connect. {0}",
196              error);
197     return error;
198   }
199 
200   LLDB_LOG(log, "successfully attached to process with pid={0}", process_id);
201 
202   // We've hit the initial stop.  If eLaunchFlagsStopAtEntry was specified, the
203   // private state should already be set to eStateStopped as a result of
204   // hitting the initial breakpoint.  If it was not set, the breakpoint should
205   // have already been resumed from and the private state should already be
206   // eStateRunning.
207 
208   return error;
209 }
210 
DestroyProcess(const lldb::StateType state)211 Status ProcessDebugger::DestroyProcess(const lldb::StateType state) {
212   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
213   DebuggerThreadSP debugger_thread;
214   {
215     // Acquire this lock inside an inner scope, only long enough to get the
216     // DebuggerThread. StopDebugging() will trigger a call back into
217     // ProcessDebugger which will acquire the lock again, so we need to not
218     // deadlock.
219     llvm::sys::ScopedLock lock(m_mutex);
220 
221     if (!m_session_data) {
222       LLDB_LOG(log, "warning: state = {0}, but there is no active session.",
223                state);
224       return Status();
225     }
226 
227     debugger_thread = m_session_data->m_debugger;
228   }
229 
230   if (state == eStateExited || state == eStateDetached) {
231     LLDB_LOG(log, "warning: cannot destroy process {0} while state = {1}.",
232              GetDebuggedProcessId(), state);
233     return Status();
234   }
235 
236   LLDB_LOG(log, "Shutting down process {0}.",
237            debugger_thread->GetProcess().GetNativeProcess().GetSystemHandle());
238   auto error = debugger_thread->StopDebugging(true);
239 
240   // By the time StopDebugging returns, there is no more debugger thread, so
241   // we can be assured that no other thread will race for the session data.
242   m_session_data.reset();
243 
244   return error;
245 }
246 
HaltProcess(bool & caused_stop)247 Status ProcessDebugger::HaltProcess(bool &caused_stop) {
248   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
249   Status error;
250   llvm::sys::ScopedLock lock(m_mutex);
251   caused_stop = ::DebugBreakProcess(m_session_data->m_debugger->GetProcess()
252                                         .GetNativeProcess()
253                                         .GetSystemHandle());
254   if (!caused_stop) {
255     error.SetError(::GetLastError(), eErrorTypeWin32);
256     LLDB_LOG(log, "DebugBreakProcess failed with error {0}", error);
257   }
258 
259   return error;
260 }
261 
ReadMemory(lldb::addr_t vm_addr,void * buf,size_t size,size_t & bytes_read)262 Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
263                                    size_t &bytes_read) {
264   Status error;
265   bytes_read = 0;
266   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
267   llvm::sys::ScopedLock lock(m_mutex);
268 
269   if (!m_session_data) {
270     error.SetErrorString(
271         "cannot read, there is no active debugger connection.");
272     LLDB_LOG(log, "error: {0}", error);
273     return error;
274   }
275 
276   LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
277            vm_addr);
278 
279   HostProcess process = m_session_data->m_debugger->GetProcess();
280   void *addr = reinterpret_cast<void *>(vm_addr);
281   SIZE_T num_of_bytes_read = 0;
282   if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
283                            buf, size, &num_of_bytes_read)) {
284     // Reading from the process can fail for a number of reasons - set the
285     // error code and make sure that the number of bytes read is set back to 0
286     // because in some scenarios the value of bytes_read returned from the API
287     // is garbage.
288     error.SetError(GetLastError(), eErrorTypeWin32);
289     LLDB_LOG(log, "reading failed with error: {0}", error);
290   } else {
291     bytes_read = num_of_bytes_read;
292   }
293   return error;
294 }
295 
WriteMemory(lldb::addr_t vm_addr,const void * buf,size_t size,size_t & bytes_written)296 Status ProcessDebugger::WriteMemory(lldb::addr_t vm_addr, const void *buf,
297                                     size_t size, size_t &bytes_written) {
298   Status error;
299   bytes_written = 0;
300   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
301   llvm::sys::ScopedLock lock(m_mutex);
302   LLDB_LOG(log, "attempting to write {0} bytes into address {1:x}", size,
303            vm_addr);
304 
305   if (!m_session_data) {
306     error.SetErrorString(
307         "cannot write, there is no active debugger connection.");
308     LLDB_LOG(log, "error: {0}", error);
309     return error;
310   }
311 
312   HostProcess process = m_session_data->m_debugger->GetProcess();
313   void *addr = reinterpret_cast<void *>(vm_addr);
314   SIZE_T num_of_bytes_written = 0;
315   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
316   if (::WriteProcessMemory(handle, addr, buf, size, &num_of_bytes_written)) {
317     FlushInstructionCache(handle, addr, num_of_bytes_written);
318     bytes_written = num_of_bytes_written;
319   } else {
320     error.SetError(GetLastError(), eErrorTypeWin32);
321     LLDB_LOG(log, "writing failed with error: {0}", error);
322   }
323   return error;
324 }
325 
AllocateMemory(size_t size,uint32_t permissions,lldb::addr_t & addr)326 Status ProcessDebugger::AllocateMemory(size_t size, uint32_t permissions,
327                                        lldb::addr_t &addr) {
328   Status error;
329   addr = LLDB_INVALID_ADDRESS;
330   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
331   llvm::sys::ScopedLock lock(m_mutex);
332   LLDB_LOG(log, "attempting to allocate {0} bytes with permissions {1}", size,
333            permissions);
334 
335   if (!m_session_data) {
336     error.SetErrorString(
337         "cannot allocate, there is no active debugger connection");
338     LLDB_LOG(log, "error: {0}", error);
339     return error;
340   }
341 
342   HostProcess process = m_session_data->m_debugger->GetProcess();
343   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
344   auto protect = ConvertLldbToWinApiProtect(permissions);
345   auto result = ::VirtualAllocEx(handle, nullptr, size, MEM_COMMIT, protect);
346   if (!result) {
347     error.SetError(GetLastError(), eErrorTypeWin32);
348     LLDB_LOG(log, "allocating failed with error: {0}", error);
349   } else {
350     addr = reinterpret_cast<addr_t>(result);
351   }
352   return error;
353 }
354 
DeallocateMemory(lldb::addr_t vm_addr)355 Status ProcessDebugger::DeallocateMemory(lldb::addr_t vm_addr) {
356   Status result;
357 
358   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
359   llvm::sys::ScopedLock lock(m_mutex);
360   LLDB_LOG(log, "attempting to deallocate bytes at address {0}", vm_addr);
361 
362   if (!m_session_data) {
363     result.SetErrorString(
364         "cannot deallocate, there is no active debugger connection");
365     LLDB_LOG(log, "error: {0}", result);
366     return result;
367   }
368 
369   HostProcess process = m_session_data->m_debugger->GetProcess();
370   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
371   if (!::VirtualFreeEx(handle, reinterpret_cast<LPVOID>(vm_addr), 0,
372                        MEM_RELEASE)) {
373     result.SetError(GetLastError(), eErrorTypeWin32);
374     LLDB_LOG(log, "deallocating failed with error: {0}", result);
375   }
376 
377   return result;
378 }
379 
GetMemoryRegionInfo(lldb::addr_t vm_addr,MemoryRegionInfo & info)380 Status ProcessDebugger::GetMemoryRegionInfo(lldb::addr_t vm_addr,
381                                             MemoryRegionInfo &info) {
382   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_MEMORY);
383   Status error;
384   llvm::sys::ScopedLock lock(m_mutex);
385   info.Clear();
386 
387   if (!m_session_data) {
388     error.SetErrorString(
389         "GetMemoryRegionInfo called with no debugging session.");
390     LLDB_LOG(log, "error: {0}", error);
391     return error;
392   }
393   HostProcess process = m_session_data->m_debugger->GetProcess();
394   lldb::process_t handle = process.GetNativeProcess().GetSystemHandle();
395   if (handle == nullptr || handle == LLDB_INVALID_PROCESS) {
396     error.SetErrorString(
397         "GetMemoryRegionInfo called with an invalid target process.");
398     LLDB_LOG(log, "error: {0}", error);
399     return error;
400   }
401 
402   LLDB_LOG(log, "getting info for address {0:x}", vm_addr);
403 
404   void *addr = reinterpret_cast<void *>(vm_addr);
405   MEMORY_BASIC_INFORMATION mem_info = {};
406   SIZE_T result = ::VirtualQueryEx(handle, addr, &mem_info, sizeof(mem_info));
407   if (result == 0) {
408     DWORD last_error = ::GetLastError();
409     if (last_error == ERROR_INVALID_PARAMETER) {
410       // ERROR_INVALID_PARAMETER is returned if VirtualQueryEx is called with
411       // an address past the highest accessible address. We should return a
412       // range from the vm_addr to LLDB_INVALID_ADDRESS
413       info.GetRange().SetRangeBase(vm_addr);
414       info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS);
415       info.SetReadable(MemoryRegionInfo::eNo);
416       info.SetExecutable(MemoryRegionInfo::eNo);
417       info.SetWritable(MemoryRegionInfo::eNo);
418       info.SetMapped(MemoryRegionInfo::eNo);
419       return error;
420     } else {
421       error.SetError(last_error, eErrorTypeWin32);
422       LLDB_LOG(log,
423                "VirtualQueryEx returned error {0} while getting memory "
424                "region info for address {1:x}",
425                error, vm_addr);
426       return error;
427     }
428   }
429 
430   // Protect bits are only valid for MEM_COMMIT regions.
431   if (mem_info.State == MEM_COMMIT) {
432     const bool readable = IsPageReadable(mem_info.Protect);
433     const bool executable = IsPageExecutable(mem_info.Protect);
434     const bool writable = IsPageWritable(mem_info.Protect);
435     info.SetReadable(readable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
436     info.SetExecutable(executable ? MemoryRegionInfo::eYes
437                                   : MemoryRegionInfo::eNo);
438     info.SetWritable(writable ? MemoryRegionInfo::eYes : MemoryRegionInfo::eNo);
439   } else {
440     info.SetReadable(MemoryRegionInfo::eNo);
441     info.SetExecutable(MemoryRegionInfo::eNo);
442     info.SetWritable(MemoryRegionInfo::eNo);
443   }
444 
445   // AllocationBase is defined for MEM_COMMIT and MEM_RESERVE but not MEM_FREE.
446   if (mem_info.State != MEM_FREE) {
447     info.GetRange().SetRangeBase(
448         reinterpret_cast<addr_t>(mem_info.AllocationBase));
449     info.GetRange().SetRangeEnd(reinterpret_cast<addr_t>(mem_info.BaseAddress) +
450                                 mem_info.RegionSize);
451     info.SetMapped(MemoryRegionInfo::eYes);
452   } else {
453     // In the unmapped case we need to return the distance to the next block of
454     // memory. VirtualQueryEx nearly does that except that it gives the
455     // distance from the start of the page containing vm_addr.
456     SYSTEM_INFO data;
457     ::GetSystemInfo(&data);
458     DWORD page_offset = vm_addr % data.dwPageSize;
459     info.GetRange().SetRangeBase(vm_addr);
460     info.GetRange().SetByteSize(mem_info.RegionSize - page_offset);
461     info.SetMapped(MemoryRegionInfo::eNo);
462   }
463 
464   LLDB_LOGV(log,
465             "Memory region info for address {0}: readable={1}, "
466             "executable={2}, writable={3}",
467             vm_addr, info.GetReadable(), info.GetExecutable(),
468             info.GetWritable());
469   return error;
470 }
471 
OnExitProcess(uint32_t exit_code)472 void ProcessDebugger::OnExitProcess(uint32_t exit_code) {
473   // If the process exits before any initial stop then notify the debugger
474   // of the error otherwise WaitForDebuggerConnection() will be blocked.
475   // An example of this issue is when a process fails to load a dependent DLL.
476   if (m_session_data && !m_session_data->m_initial_stop_received) {
477     Status error(exit_code, eErrorTypeWin32);
478     OnDebuggerError(error, 0);
479   }
480 }
481 
OnDebuggerConnected(lldb::addr_t image_base)482 void ProcessDebugger::OnDebuggerConnected(lldb::addr_t image_base) {}
483 
484 ExceptionResult
OnDebugException(bool first_chance,const ExceptionRecord & record)485 ProcessDebugger::OnDebugException(bool first_chance,
486                                   const ExceptionRecord &record) {
487   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_EXCEPTION);
488   llvm::sys::ScopedLock lock(m_mutex);
489   // FIXME: Without this check, occasionally when running the test suite
490   // there is an issue where m_session_data can be null.  It's not clear how
491   // this could happen but it only surfaces while running the test suite.  In
492   // order to properly diagnose this, we probably need to first figure allow the
493   // test suite to print out full lldb logs, and then add logging to the process
494   // plugin.
495   if (!m_session_data) {
496     LLDB_LOG(log,
497              "Debugger thread reported exception {0:x} at address {1:x}, but "
498              "there is no session.",
499              record.GetExceptionCode(), record.GetExceptionAddress());
500     return ExceptionResult::SendToApplication;
501   }
502 
503   ExceptionResult result = ExceptionResult::SendToApplication;
504   if ((record.GetExceptionCode() == EXCEPTION_BREAKPOINT ||
505        record.GetExceptionCode() ==
506            0x4000001FL /*WOW64 STATUS_WX86_BREAKPOINT*/) &&
507       !m_session_data->m_initial_stop_received) {
508     // Handle breakpoints at the first chance.
509     result = ExceptionResult::BreakInDebugger;
510     LLDB_LOG(
511         log,
512         "Hit loader breakpoint at address {0:x}, setting initial stop event.",
513         record.GetExceptionAddress());
514     m_session_data->m_initial_stop_received = true;
515     ::SetEvent(m_session_data->m_initial_stop_event);
516   }
517   return result;
518 }
519 
OnCreateThread(const HostThread & thread)520 void ProcessDebugger::OnCreateThread(const HostThread &thread) {
521   // Do nothing by default
522 }
523 
OnExitThread(lldb::tid_t thread_id,uint32_t exit_code)524 void ProcessDebugger::OnExitThread(lldb::tid_t thread_id, uint32_t exit_code) {
525   // Do nothing by default
526 }
527 
OnLoadDll(const ModuleSpec & module_spec,lldb::addr_t module_addr)528 void ProcessDebugger::OnLoadDll(const ModuleSpec &module_spec,
529                                 lldb::addr_t module_addr) {
530   // Do nothing by default
531 }
532 
OnUnloadDll(lldb::addr_t module_addr)533 void ProcessDebugger::OnUnloadDll(lldb::addr_t module_addr) {
534   // Do nothing by default
535 }
536 
OnDebugString(const std::string & string)537 void ProcessDebugger::OnDebugString(const std::string &string) {}
538 
OnDebuggerError(const Status & error,uint32_t type)539 void ProcessDebugger::OnDebuggerError(const Status &error, uint32_t type) {
540   llvm::sys::ScopedLock lock(m_mutex);
541   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS);
542 
543   if (m_session_data->m_initial_stop_received) {
544     // This happened while debugging.  Do we shutdown the debugging session,
545     // try to continue, or do something else?
546     LLDB_LOG(log,
547              "Error {0} occurred during debugging.  Unexpected behavior "
548              "may result.  {1}",
549              error.GetError(), error);
550   } else {
551     // If we haven't actually launched the process yet, this was an error
552     // launching the process.  Set the internal error and signal the initial
553     // stop event so that the DoLaunch method wakes up and returns a failure.
554     m_session_data->m_launch_error = error;
555     ::SetEvent(m_session_data->m_initial_stop_event);
556     LLDB_LOG(log,
557              "Error {0} occurred launching the process before the initial "
558              "stop. {1}",
559              error.GetError(), error);
560     return;
561   }
562 }
563 
WaitForDebuggerConnection(DebuggerThreadSP debugger,HostProcess & process)564 Status ProcessDebugger::WaitForDebuggerConnection(DebuggerThreadSP debugger,
565                                                   HostProcess &process) {
566   Status result;
567   Log *log = ProcessWindowsLog::GetLogIfAny(WINDOWS_LOG_PROCESS |
568                                             WINDOWS_LOG_BREAKPOINTS);
569   LLDB_LOG(log, "Waiting for loader breakpoint.");
570 
571   // Block this function until we receive the initial stop from the process.
572   if (::WaitForSingleObject(m_session_data->m_initial_stop_event, INFINITE) ==
573       WAIT_OBJECT_0) {
574     LLDB_LOG(log, "hit loader breakpoint, returning.");
575 
576     process = debugger->GetProcess();
577     return m_session_data->m_launch_error;
578   } else
579     return Status(::GetLastError(), eErrorTypeWin32);
580 }
581 
582 } // namespace lldb_private
583