1 //===-- DebuggerThread.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 "DebuggerThread.h"
10 #include "ExceptionRecord.h"
11 #include "IDebugDelegate.h"
12 
13 #include "lldb/Core/ModuleSpec.h"
14 #include "lldb/Host/ProcessLaunchInfo.h"
15 #include "lldb/Host/ThreadLauncher.h"
16 #include "lldb/Host/windows/HostProcessWindows.h"
17 #include "lldb/Host/windows/HostThreadWindows.h"
18 #include "lldb/Host/windows/ProcessLauncherWindows.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Utility/FileSpec.h"
21 #include "lldb/Utility/Log.h"
22 #include "lldb/Utility/Predicate.h"
23 #include "lldb/Utility/Status.h"
24 
25 #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
26 
27 #include "llvm/ADT/STLExtras.h"
28 #include "llvm/Support/ConvertUTF.h"
29 #include "llvm/Support/Threading.h"
30 #include "llvm/Support/raw_ostream.h"
31 
32 #ifndef STATUS_WX86_BREAKPOINT
33 #define STATUS_WX86_BREAKPOINT 0x4000001FL // For WOW64
34 #endif
35 
36 using namespace lldb;
37 using namespace lldb_private;
38 
39 DebuggerThread::DebuggerThread(DebugDelegateSP debug_delegate)
40     : m_debug_delegate(debug_delegate), m_pid_to_detach(0),
41       m_is_shutting_down(false) {
42   m_debugging_ended_event = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
43 }
44 
45 DebuggerThread::~DebuggerThread() { ::CloseHandle(m_debugging_ended_event); }
46 
47 Status DebuggerThread::DebugLaunch(const ProcessLaunchInfo &launch_info) {
48   Log *log = GetLog(WindowsLog::Process);
49   LLDB_LOG(log, "launching '{0}'", launch_info.GetExecutableFile().GetPath());
50 
51   Status result;
52   llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
53       "lldb.plugin.process-windows.secondary[?]",
54       [this, launch_info] { return DebuggerThreadLaunchRoutine(launch_info); });
55   if (!secondary_thread) {
56     result = Status(secondary_thread.takeError());
57     LLDB_LOG(log, "couldn't launch debugger thread. {0}", result);
58   }
59 
60   return result;
61 }
62 
63 Status DebuggerThread::DebugAttach(lldb::pid_t pid,
64                                    const ProcessAttachInfo &attach_info) {
65   Log *log = GetLog(WindowsLog::Process);
66   LLDB_LOG(log, "attaching to '{0}'", pid);
67 
68   Status result;
69   llvm::Expected<HostThread> secondary_thread = ThreadLauncher::LaunchThread(
70       "lldb.plugin.process-windows.secondary[?]", [this, pid, attach_info] {
71         return DebuggerThreadAttachRoutine(pid, attach_info);
72       });
73   if (!secondary_thread) {
74     result = Status(secondary_thread.takeError());
75     LLDB_LOG(log, "couldn't attach to process '{0}'. {1}", pid, result);
76   }
77 
78   return result;
79 }
80 
81 lldb::thread_result_t DebuggerThread::DebuggerThreadLaunchRoutine(
82     const ProcessLaunchInfo &launch_info) {
83   // Grab a shared_ptr reference to this so that we know it won't get deleted
84   // until after the thread routine has exited.
85   std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
86 
87   Log *log = GetLog(WindowsLog::Process);
88   LLDB_LOG(log, "preparing to launch '{0}' on background thread.",
89            launch_info.GetExecutableFile().GetPath());
90 
91   Status error;
92   ProcessLauncherWindows launcher;
93   HostProcess process(launcher.LaunchProcess(launch_info, error));
94   // If we couldn't create the process, notify waiters immediately.  Otherwise
95   // enter the debug loop and wait until we get the create process debug
96   // notification.  Note that if the process was created successfully, we can
97   // throw away the process handle we got from CreateProcess because Windows
98   // will give us another (potentially more useful?) handle when it sends us
99   // the CREATE_PROCESS_DEBUG_EVENT.
100   if (error.Success())
101     DebugLoop();
102   else
103     m_debug_delegate->OnDebuggerError(error, 0);
104 
105   return {};
106 }
107 
108 lldb::thread_result_t DebuggerThread::DebuggerThreadAttachRoutine(
109     lldb::pid_t pid, const ProcessAttachInfo &attach_info) {
110   // Grab a shared_ptr reference to this so that we know it won't get deleted
111   // until after the thread routine has exited.
112   std::shared_ptr<DebuggerThread> this_ref(shared_from_this());
113 
114   Log *log = GetLog(WindowsLog::Process);
115   LLDB_LOG(log, "preparing to attach to process '{0}' on background thread.",
116            pid);
117 
118   if (!DebugActiveProcess((DWORD)pid)) {
119     Status error(::GetLastError(), eErrorTypeWin32);
120     m_debug_delegate->OnDebuggerError(error, 0);
121     return {};
122   }
123 
124   // The attach was successful, enter the debug loop.  From here on out, this
125   // is no different than a create process operation, so all the same comments
126   // in DebugLaunch should apply from this point out.
127   DebugLoop();
128 
129   return {};
130 }
131 
132 Status DebuggerThread::StopDebugging(bool terminate) {
133   Status error;
134 
135   lldb::pid_t pid = m_process.GetProcessId();
136 
137   Log *log = GetLog(WindowsLog::Process);
138   LLDB_LOG(log, "terminate = {0}, inferior={1}.", terminate, pid);
139 
140   // Set m_is_shutting_down to true if it was false.  Return if it was already
141   // true.
142   bool expected = false;
143   if (!m_is_shutting_down.compare_exchange_strong(expected, true))
144     return error;
145 
146   // Make a copy of the process, since the termination sequence will reset
147   // DebuggerThread's internal copy and it needs to remain open for the Wait
148   // operation.
149   HostProcess process_copy = m_process;
150   lldb::process_t handle = m_process.GetNativeProcess().GetSystemHandle();
151 
152   if (terminate) {
153     if (handle != nullptr && handle != LLDB_INVALID_PROCESS) {
154       // Initiate the termination before continuing the exception, so that the
155       // next debug event we get is the exit process event, and not some other
156       // event.
157       BOOL terminate_suceeded = TerminateProcess(handle, 0);
158       LLDB_LOG(log,
159                "calling TerminateProcess({0}, 0) (inferior={1}), success={2}",
160                handle, pid, terminate_suceeded);
161     } else {
162       LLDB_LOG(log,
163                "NOT calling TerminateProcess because the inferior is not valid "
164                "({0}, 0) (inferior={1})",
165                handle, pid);
166     }
167   }
168 
169   // If we're stuck waiting for an exception to continue (e.g. the user is at a
170   // breakpoint messing around in the debugger), continue it now.  But only
171   // AFTER calling TerminateProcess to make sure that the very next call to
172   // WaitForDebugEvent is an exit process event.
173   if (m_active_exception.get()) {
174     LLDB_LOG(log, "masking active exception");
175     ContinueAsyncException(ExceptionResult::MaskException);
176   }
177 
178   if (!terminate) {
179     // Indicate that we want to detach.
180     m_pid_to_detach = GetProcess().GetProcessId();
181 
182     // Force a fresh break so that the detach can happen from the debugger
183     // thread.
184     if (!::DebugBreakProcess(
185             GetProcess().GetNativeProcess().GetSystemHandle())) {
186       error.SetError(::GetLastError(), eErrorTypeWin32);
187     }
188   }
189 
190   LLDB_LOG(log, "waiting for detach from process {0} to complete.", pid);
191 
192   DWORD wait_result = WaitForSingleObject(m_debugging_ended_event, 5000);
193   if (wait_result != WAIT_OBJECT_0) {
194     error.SetError(GetLastError(), eErrorTypeWin32);
195     LLDB_LOG(log, "error: WaitForSingleObject({0}, 5000) returned {1}",
196              m_debugging_ended_event, wait_result);
197   } else
198     LLDB_LOG(log, "detach from process {0} completed successfully.", pid);
199 
200   if (!error.Success()) {
201     LLDB_LOG(log, "encountered an error while trying to stop process {0}. {1}",
202              pid, error);
203   }
204   return error;
205 }
206 
207 void DebuggerThread::ContinueAsyncException(ExceptionResult result) {
208   if (!m_active_exception.get())
209     return;
210 
211   Log *log = GetLog(WindowsLog::Process | WindowsLog::Exception);
212   LLDB_LOG(log, "broadcasting for inferior process {0}.",
213            m_process.GetProcessId());
214 
215   m_active_exception.reset();
216   m_exception_pred.SetValue(result, eBroadcastAlways);
217 }
218 
219 void DebuggerThread::FreeProcessHandles() {
220   m_process = HostProcess();
221   m_main_thread = HostThread();
222   if (m_image_file) {
223     ::CloseHandle(m_image_file);
224     m_image_file = nullptr;
225   }
226 }
227 
228 void DebuggerThread::DebugLoop() {
229   Log *log = GetLog(WindowsLog::Event);
230   DEBUG_EVENT dbe = {};
231   bool should_debug = true;
232   LLDB_LOGV(log, "Entering WaitForDebugEvent loop");
233   while (should_debug) {
234     LLDB_LOGV(log, "Calling WaitForDebugEvent");
235     BOOL wait_result = WaitForDebugEvent(&dbe, INFINITE);
236     if (wait_result) {
237       DWORD continue_status = DBG_CONTINUE;
238       switch (dbe.dwDebugEventCode) {
239       default:
240         llvm_unreachable("Unhandle debug event code!");
241       case EXCEPTION_DEBUG_EVENT: {
242         ExceptionResult status =
243             HandleExceptionEvent(dbe.u.Exception, dbe.dwThreadId);
244 
245         if (status == ExceptionResult::MaskException)
246           continue_status = DBG_CONTINUE;
247         else if (status == ExceptionResult::SendToApplication)
248           continue_status = DBG_EXCEPTION_NOT_HANDLED;
249 
250         break;
251       }
252       case CREATE_THREAD_DEBUG_EVENT:
253         continue_status =
254             HandleCreateThreadEvent(dbe.u.CreateThread, dbe.dwThreadId);
255         break;
256       case CREATE_PROCESS_DEBUG_EVENT:
257         continue_status =
258             HandleCreateProcessEvent(dbe.u.CreateProcessInfo, dbe.dwThreadId);
259         break;
260       case EXIT_THREAD_DEBUG_EVENT:
261         continue_status =
262             HandleExitThreadEvent(dbe.u.ExitThread, dbe.dwThreadId);
263         break;
264       case EXIT_PROCESS_DEBUG_EVENT:
265         continue_status =
266             HandleExitProcessEvent(dbe.u.ExitProcess, dbe.dwThreadId);
267         should_debug = false;
268         break;
269       case LOAD_DLL_DEBUG_EVENT:
270         continue_status = HandleLoadDllEvent(dbe.u.LoadDll, dbe.dwThreadId);
271         break;
272       case UNLOAD_DLL_DEBUG_EVENT:
273         continue_status = HandleUnloadDllEvent(dbe.u.UnloadDll, dbe.dwThreadId);
274         break;
275       case OUTPUT_DEBUG_STRING_EVENT:
276         continue_status = HandleODSEvent(dbe.u.DebugString, dbe.dwThreadId);
277         break;
278       case RIP_EVENT:
279         continue_status = HandleRipEvent(dbe.u.RipInfo, dbe.dwThreadId);
280         if (dbe.u.RipInfo.dwType == SLE_ERROR)
281           should_debug = false;
282         break;
283       }
284 
285       LLDB_LOGV(log, "calling ContinueDebugEvent({0}, {1}, {2}) on thread {3}.",
286                 dbe.dwProcessId, dbe.dwThreadId, continue_status,
287                 ::GetCurrentThreadId());
288 
289       ::ContinueDebugEvent(dbe.dwProcessId, dbe.dwThreadId, continue_status);
290 
291       if (m_detached) {
292         should_debug = false;
293       }
294     } else {
295       LLDB_LOG(log, "returned FALSE from WaitForDebugEvent.  Error = {0}",
296                ::GetLastError());
297 
298       should_debug = false;
299     }
300   }
301   FreeProcessHandles();
302 
303   LLDB_LOG(log, "WaitForDebugEvent loop completed, exiting.");
304   ::SetEvent(m_debugging_ended_event);
305 }
306 
307 ExceptionResult
308 DebuggerThread::HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
309                                      DWORD thread_id) {
310   Log *log = GetLog(WindowsLog::Event | WindowsLog::Exception);
311   if (m_is_shutting_down) {
312     // A breakpoint that occurs while `m_pid_to_detach` is non-zero is a magic
313     // exception that
314     // we use simply to wake up the DebuggerThread so that we can close out the
315     // debug loop.
316     if (m_pid_to_detach != 0 &&
317         (info.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT ||
318          info.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT)) {
319       LLDB_LOG(log, "Breakpoint exception is cue to detach from process {0:x}",
320                m_pid_to_detach.load());
321       ::DebugActiveProcessStop(m_pid_to_detach);
322       m_detached = true;
323     }
324 
325     // Don't perform any blocking operations while we're shutting down.  That
326     // will cause TerminateProcess -> WaitForSingleObject to time out.
327     return ExceptionResult::SendToApplication;
328   }
329 
330   bool first_chance = (info.dwFirstChance != 0);
331 
332   m_active_exception.reset(
333       new ExceptionRecord(info.ExceptionRecord, thread_id));
334   LLDB_LOG(log, "encountered {0} chance exception {1:x} on thread {2:x}",
335            first_chance ? "first" : "second",
336            info.ExceptionRecord.ExceptionCode, thread_id);
337 
338   ExceptionResult result =
339       m_debug_delegate->OnDebugException(first_chance, *m_active_exception);
340   m_exception_pred.SetValue(result, eBroadcastNever);
341 
342   LLDB_LOG(log, "waiting for ExceptionPred != BreakInDebugger");
343   result = *m_exception_pred.WaitForValueNotEqualTo(
344       ExceptionResult::BreakInDebugger);
345 
346   LLDB_LOG(log, "got ExceptionPred = {0}", (int)m_exception_pred.GetValue());
347   return result;
348 }
349 
350 DWORD
351 DebuggerThread::HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
352                                         DWORD thread_id) {
353   Log *log = GetLog(WindowsLog::Event | WindowsLog::Thread);
354   LLDB_LOG(log, "Thread {0} spawned in process {1}", thread_id,
355            m_process.GetProcessId());
356   HostThread thread(info.hThread);
357   thread.GetNativeThread().SetOwnsHandle(false);
358   m_debug_delegate->OnCreateThread(thread);
359   return DBG_CONTINUE;
360 }
361 
362 DWORD
363 DebuggerThread::HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
364                                          DWORD thread_id) {
365   Log *log = GetLog(WindowsLog::Event | WindowsLog::Process);
366   uint32_t process_id = ::GetProcessId(info.hProcess);
367 
368   LLDB_LOG(log, "process {0} spawned", process_id);
369 
370   std::string thread_name;
371   llvm::raw_string_ostream name_stream(thread_name);
372   name_stream << "lldb.plugin.process-windows.secondary[" << process_id << "]";
373   name_stream.flush();
374   llvm::set_thread_name(thread_name);
375 
376   // info.hProcess and info.hThread are closed automatically by Windows when
377   // EXIT_PROCESS_DEBUG_EVENT is received.
378   m_process = HostProcess(info.hProcess);
379   ((HostProcessWindows &)m_process.GetNativeProcess()).SetOwnsHandle(false);
380   m_main_thread = HostThread(info.hThread);
381   m_main_thread.GetNativeThread().SetOwnsHandle(false);
382   m_image_file = info.hFile;
383 
384   lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfImage);
385   m_debug_delegate->OnDebuggerConnected(load_addr);
386 
387   return DBG_CONTINUE;
388 }
389 
390 DWORD
391 DebuggerThread::HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
392                                       DWORD thread_id) {
393   Log *log = GetLog(WindowsLog::Event | WindowsLog::Thread);
394   LLDB_LOG(log, "Thread {0} exited with code {1} in process {2}", thread_id,
395            info.dwExitCode, m_process.GetProcessId());
396   m_debug_delegate->OnExitThread(thread_id, info.dwExitCode);
397   return DBG_CONTINUE;
398 }
399 
400 DWORD
401 DebuggerThread::HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
402                                        DWORD thread_id) {
403   Log *log = GetLog(WindowsLog::Event | WindowsLog::Thread);
404   LLDB_LOG(log, "process {0} exited with code {1}", m_process.GetProcessId(),
405            info.dwExitCode);
406 
407   m_debug_delegate->OnExitProcess(info.dwExitCode);
408 
409   return DBG_CONTINUE;
410 }
411 
412 DWORD
413 DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
414                                    DWORD thread_id) {
415   Log *log = GetLog(WindowsLog::Event);
416   if (info.hFile == nullptr) {
417     // Not sure what this is, so just ignore it.
418     LLDB_LOG(log, "Warning: Inferior {0} has a NULL file handle, returning...",
419              m_process.GetProcessId());
420     return DBG_CONTINUE;
421   }
422 
423   std::vector<wchar_t> buffer(1);
424   DWORD required_size =
425       GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
426   if (required_size > 0) {
427     buffer.resize(required_size + 1);
428     required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0],
429                                               required_size, VOLUME_NAME_DOS);
430     std::string path_str_utf8;
431     llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
432     llvm::StringRef path_str = path_str_utf8;
433     const char *path = path_str.data();
434     if (path_str.startswith("\\\\?\\"))
435       path += 4;
436 
437     FileSpec file_spec(path);
438     ModuleSpec module_spec(file_spec);
439     lldb::addr_t load_addr = reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll);
440 
441     LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
442              m_process.GetProcessId(), path, info.lpBaseOfDll);
443 
444     m_debug_delegate->OnLoadDll(module_spec, load_addr);
445   } else {
446     LLDB_LOG(
447         log,
448         "Inferior {0} - Error {1} occurred calling GetFinalPathNameByHandle",
449         m_process.GetProcessId(), ::GetLastError());
450   }
451   // Windows does not automatically close info.hFile, so we need to do it.
452   ::CloseHandle(info.hFile);
453   return DBG_CONTINUE;
454 }
455 
456 DWORD
457 DebuggerThread::HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
458                                      DWORD thread_id) {
459   Log *log = GetLog(WindowsLog::Event);
460   LLDB_LOG(log, "process {0} unloading DLL at addr {1:x}.",
461            m_process.GetProcessId(), info.lpBaseOfDll);
462 
463   m_debug_delegate->OnUnloadDll(
464       reinterpret_cast<lldb::addr_t>(info.lpBaseOfDll));
465   return DBG_CONTINUE;
466 }
467 
468 DWORD
469 DebuggerThread::HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info,
470                                DWORD thread_id) {
471   return DBG_CONTINUE;
472 }
473 
474 DWORD
475 DebuggerThread::HandleRipEvent(const RIP_INFO &info, DWORD thread_id) {
476   Log *log = GetLog(WindowsLog::Event);
477   LLDB_LOG(log, "encountered error {0} (type={1}) in process {2} thread {3}",
478            info.dwError, info.dwType, m_process.GetProcessId(), thread_id);
479 
480   Status error(info.dwError, eErrorTypeWin32);
481   m_debug_delegate->OnDebuggerError(error, info.dwType);
482 
483   return DBG_CONTINUE;
484 }
485