1 //===-- NativeProcessLinux.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_NativeProcessLinux_H_ 11 #define liblldb_NativeProcessLinux_H_ 12 13 // C++ Includes 14 #include <unordered_set> 15 16 // Other libraries and framework includes 17 #include "lldb/Core/ArchSpec.h" 18 #include "lldb/Host/Debug.h" 19 #include "lldb/Host/FileSpec.h" 20 #include "lldb/Host/HostThread.h" 21 #include "lldb/Target/MemoryRegionInfo.h" 22 #include "lldb/lldb-types.h" 23 24 #include "NativeThreadLinux.h" 25 #include "lldb/Host/common/NativeProcessProtocol.h" 26 27 namespace lldb_private { 28 class Error; 29 class Scalar; 30 31 namespace process_linux { 32 /// @class NativeProcessLinux 33 /// @brief Manages communication with the inferior (debugee) process. 34 /// 35 /// Upon construction, this class prepares and launches an inferior process for 36 /// debugging. 37 /// 38 /// Changes in the inferior process state are broadcasted. 39 class NativeProcessLinux : public NativeProcessProtocol { 40 friend Error NativeProcessProtocol::Launch( 41 ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, 42 MainLoop &mainloop, NativeProcessProtocolSP &process_sp); 43 44 friend Error NativeProcessProtocol::Attach( 45 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 46 MainLoop &mainloop, NativeProcessProtocolSP &process_sp); 47 48 public: 49 // --------------------------------------------------------------------- 50 // NativeProcessProtocol Interface 51 // --------------------------------------------------------------------- 52 Error Resume(const ResumeActionList &resume_actions) override; 53 54 Error Halt() override; 55 56 Error Detach() override; 57 58 Error Signal(int signo) override; 59 60 Error Interrupt() override; 61 62 Error Kill() override; 63 64 Error GetMemoryRegionInfo(lldb::addr_t load_addr, 65 MemoryRegionInfo &range_info) override; 66 67 Error ReadMemory(lldb::addr_t addr, void *buf, size_t size, 68 size_t &bytes_read) override; 69 70 Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, 71 size_t &bytes_read) override; 72 73 Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size, 74 size_t &bytes_written) override; 75 76 Error AllocateMemory(size_t size, uint32_t permissions, 77 lldb::addr_t &addr) override; 78 79 Error DeallocateMemory(lldb::addr_t addr) override; 80 81 lldb::addr_t GetSharedLibraryInfoAddress() override; 82 83 size_t UpdateThreads() override; 84 85 bool GetArchitecture(ArchSpec &arch) const override; 86 87 Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override; 88 89 Error RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override; 90 91 void DoStopIDBumped(uint32_t newBumpId) override; 92 93 Error GetLoadedModuleFileSpec(const char *module_path, 94 FileSpec &file_spec) override; 95 96 Error GetFileLoadAddress(const llvm::StringRef &file_name, 97 lldb::addr_t &load_addr) override; 98 99 NativeThreadLinuxSP GetThreadByID(lldb::tid_t id); 100 101 // --------------------------------------------------------------------- 102 // Interface used by NativeRegisterContext-derived classes. 103 // --------------------------------------------------------------------- 104 static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, 105 void *data = nullptr, size_t data_size = 0, 106 long *result = nullptr); 107 108 bool SupportHardwareSingleStepping() const; 109 110 protected: 111 // --------------------------------------------------------------------- 112 // NativeProcessProtocol protected interface 113 // --------------------------------------------------------------------- 114 Error 115 GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, 116 size_t &actual_opcode_size, 117 const uint8_t *&trap_opcode_bytes) override; 118 119 private: 120 MainLoop::SignalHandleUP m_sigchld_handle; 121 ArchSpec m_arch; 122 123 LazyBool m_supports_mem_region; 124 std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache; 125 126 lldb::tid_t m_pending_notification_tid; 127 128 // List of thread ids stepping with a breakpoint with the address of 129 // the relevan breakpoint 130 std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint; 131 132 // --------------------------------------------------------------------- 133 // Private Instance Methods 134 // --------------------------------------------------------------------- 135 NativeProcessLinux(); 136 137 Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info); 138 139 /// Attaches to an existing process. Forms the 140 /// implementation of Process::DoAttach 141 void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error); 142 143 ::pid_t Attach(lldb::pid_t pid, Error &error); 144 145 static Error SetDefaultPtraceOpts(const lldb::pid_t); 146 147 static void *MonitorThread(void *baton); 148 149 void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); 150 151 void WaitForNewThread(::pid_t tid); 152 153 void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread); 154 155 void MonitorTrace(NativeThreadLinux &thread); 156 157 void MonitorBreakpoint(NativeThreadLinux &thread); 158 159 void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index); 160 161 void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, 162 bool exited); 163 164 Error SetupSoftwareSingleStepping(NativeThreadLinux &thread); 165 166 #if 0 167 static ::ProcessMessage::CrashReason 168 GetCrashReasonForSIGSEGV(const siginfo_t *info); 169 170 static ::ProcessMessage::CrashReason 171 GetCrashReasonForSIGILL(const siginfo_t *info); 172 173 static ::ProcessMessage::CrashReason 174 GetCrashReasonForSIGFPE(const siginfo_t *info); 175 176 static ::ProcessMessage::CrashReason 177 GetCrashReasonForSIGBUS(const siginfo_t *info); 178 #endif 179 180 bool HasThreadNoLock(lldb::tid_t thread_id); 181 182 bool StopTrackingThread(lldb::tid_t thread_id); 183 184 NativeThreadLinuxSP AddThread(lldb::tid_t thread_id); 185 186 Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); 187 188 Error FixupBreakpointPCAsNeeded(NativeThreadLinux &thread); 189 190 /// Writes a siginfo_t structure corresponding to the given thread ID to the 191 /// memory region pointed to by @p siginfo. 192 Error GetSignalInfo(lldb::tid_t tid, void *siginfo); 193 194 /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) 195 /// corresponding to the given thread ID to the memory pointed to by @p 196 /// message. 197 Error GetEventMessage(lldb::tid_t tid, unsigned long *message); 198 199 void NotifyThreadDeath(lldb::tid_t tid); 200 201 Error Detach(lldb::tid_t tid); 202 203 // This method is requests a stop on all threads which are still running. It 204 // sets up a 205 // deferred delegate notification, which will fire once threads report as 206 // stopped. The 207 // triggerring_tid will be set as the current thread (main stop reason). 208 void StopRunningThreads(lldb::tid_t triggering_tid); 209 210 // Notify the delegate if all threads have stopped. 211 void SignalIfAllThreadsStopped(); 212 213 // Resume the given thread, optionally passing it the given signal. The type 214 // of resume 215 // operation (continue, single-step) depends on the state parameter. 216 Error ResumeThread(NativeThreadLinux &thread, lldb::StateType state, 217 int signo); 218 219 void ThreadWasCreated(NativeThreadLinux &thread); 220 221 void SigchldHandler(); 222 223 Error PopulateMemoryRegionCache(); 224 }; 225 226 } // namespace process_linux 227 } // namespace lldb_private 228 229 #endif // #ifndef liblldb_NativeProcessLinux_H_ 230