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