1 //===-- DebuggerThread.h ----------------------------------------*- C++ -*-===//
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 #ifndef liblldb_Plugins_Process_Windows_DebuggerThread_H_
10 #define liblldb_Plugins_Process_Windows_DebuggerThread_H_
11 
12 #include <atomic>
13 #include <memory>
14 
15 #include "ForwardDecl.h"
16 #include "lldb/Host/HostProcess.h"
17 #include "lldb/Host/HostThread.h"
18 #include "lldb/Host/windows/windows.h"
19 #include "lldb/Utility/Predicate.h"
20 
21 namespace lldb_private {
22 
23 //----------------------------------------------------------------------
24 // DebuggerThread
25 //
26 // Debugs a single process, notifying listeners as appropriate when interesting
27 // things occur.
28 //----------------------------------------------------------------------
29 class DebuggerThread : public std::enable_shared_from_this<DebuggerThread> {
30 public:
31   DebuggerThread(DebugDelegateSP debug_delegate);
32   virtual ~DebuggerThread();
33 
34   Status DebugLaunch(const ProcessLaunchInfo &launch_info);
35   Status DebugAttach(lldb::pid_t pid, const ProcessAttachInfo &attach_info);
36 
37   HostProcess GetProcess() const { return m_process; }
38   HostThread GetMainThread() const { return m_main_thread; }
39   std::weak_ptr<ExceptionRecord> GetActiveException() {
40     return m_active_exception;
41   }
42 
43   Status StopDebugging(bool terminate);
44 
45   void ContinueAsyncException(ExceptionResult result);
46 
47 private:
48   void FreeProcessHandles();
49   void DebugLoop();
50   ExceptionResult HandleExceptionEvent(const EXCEPTION_DEBUG_INFO &info,
51                                        DWORD thread_id);
52   DWORD HandleCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO &info,
53                                 DWORD thread_id);
54   DWORD HandleCreateProcessEvent(const CREATE_PROCESS_DEBUG_INFO &info,
55                                  DWORD thread_id);
56   DWORD HandleExitThreadEvent(const EXIT_THREAD_DEBUG_INFO &info,
57                               DWORD thread_id);
58   DWORD HandleExitProcessEvent(const EXIT_PROCESS_DEBUG_INFO &info,
59                                DWORD thread_id);
60   DWORD HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info, DWORD thread_id);
61   DWORD HandleUnloadDllEvent(const UNLOAD_DLL_DEBUG_INFO &info,
62                              DWORD thread_id);
63   DWORD HandleODSEvent(const OUTPUT_DEBUG_STRING_INFO &info, DWORD thread_id);
64   DWORD HandleRipEvent(const RIP_INFO &info, DWORD thread_id);
65 
66   DebugDelegateSP m_debug_delegate;
67 
68   HostProcess m_process;    // The process being debugged.
69   HostThread m_main_thread; // The main thread of the inferior.
70 
71   // The image file of the process being debugged.
72   HANDLE m_image_file = nullptr;
73 
74   // The current exception waiting to be handled
75   ExceptionRecordSP m_active_exception;
76 
77   // A predicate which gets signalled when an exception is finished processing
78   // and the debug loop can be continued.
79   Predicate<ExceptionResult> m_exception_pred;
80 
81   // An event which gets signalled by the debugger thread when it exits the
82   // debugger loop and is detached from the inferior.
83   HANDLE m_debugging_ended_event = nullptr;
84 
85   // Signals the loop to detach from the process (specified by pid).
86   std::atomic<DWORD> m_pid_to_detach;
87 
88   // Signals the debug loop to stop processing certain types of events that
89   // block shutdown.
90   std::atomic<bool> m_is_shutting_down;
91 
92   // Indicates we've detached from the inferior process and the debug loop can
93   // exit.
94   bool m_detached = false;
95 
96   static lldb::thread_result_t DebuggerThreadLaunchRoutine(void *data);
97   lldb::thread_result_t
98   DebuggerThreadLaunchRoutine(const ProcessLaunchInfo &launch_info);
99   static lldb::thread_result_t DebuggerThreadAttachRoutine(void *data);
100   lldb::thread_result_t
101   DebuggerThreadAttachRoutine(lldb::pid_t pid,
102                               const ProcessAttachInfo &launch_info);
103 };
104 }
105 #endif
106