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