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