1 //===-- NativeProcessDarwin.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 NativeProcessDarwin_h 11 #define NativeProcessDarwin_h 12 13 // NOTE: this code should only be compiled on Apple Darwin systems. It is 14 // not cross-platform code and is not intended to build on any other platform. 15 // Therefore, platform-specific headers and code are okay here. 16 17 // C includes 18 #include <mach/mach_types.h> 19 20 // C++ includes 21 #include <mutex> 22 #include <unordered_set> 23 24 #include "lldb/Host/Debug.h" 25 #include "lldb/Host/HostThread.h" 26 #include "lldb/Host/Pipe.h" 27 #include "lldb/Host/common/NativeProcessProtocol.h" 28 #include "lldb/Target/MemoryRegionInfo.h" 29 #include "lldb/Utility/ArchSpec.h" 30 #include "lldb/Utility/FileSpec.h" 31 #include "lldb/lldb-types.h" 32 33 #include "LaunchFlavor.h" 34 #include "MachException.h" 35 #include "NativeThreadDarwin.h" 36 #include "NativeThreadListDarwin.h" 37 38 namespace lldb_private { 39 class Status; 40 class Scalar; 41 42 namespace process_darwin { 43 44 /// @class NativeProcessDarwin 45 /// Manages communication with the inferior (debugee) process. 46 /// 47 /// Upon construction, this class prepares and launches an inferior process 48 /// for debugging. 49 /// 50 /// Changes in the inferior process state are broadcasted. 51 class NativeProcessDarwin : public NativeProcessProtocol { 52 friend Status NativeProcessProtocol::Launch( 53 ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, 54 MainLoop &mainloop, NativeProcessProtocolSP &process_sp); 55 56 friend Status NativeProcessProtocol::Attach( 57 lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, 58 MainLoop &mainloop, NativeProcessProtocolSP &process_sp); 59 60 public: 61 ~NativeProcessDarwin() override; 62 63 // ----------------------------------------------------------------- 64 // NativeProcessProtocol Interface 65 // ----------------------------------------------------------------- 66 Status Resume(const ResumeActionList &resume_actions) override; 67 68 Status Halt() override; 69 70 Status Detach() override; 71 72 Status Signal(int signo) override; 73 74 Status Interrupt() override; 75 76 Status Kill() override; 77 78 Status GetMemoryRegionInfo(lldb::addr_t load_addr, 79 MemoryRegionInfo &range_info) override; 80 81 Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, 82 size_t &bytes_read) override; 83 84 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, 85 size_t &bytes_read) override; 86 87 Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, 88 size_t &bytes_written) override; 89 90 Status AllocateMemory(size_t size, uint32_t permissions, 91 lldb::addr_t &addr) override; 92 93 Status DeallocateMemory(lldb::addr_t addr) override; 94 95 lldb::addr_t GetSharedLibraryInfoAddress() override; 96 97 size_t UpdateThreads() override; 98 99 bool GetArchitecture(ArchSpec &arch) const override; 100 101 Status SetBreakpoint(lldb::addr_t addr, uint32_t size, 102 bool hardware) override; 103 104 void DoStopIDBumped(uint32_t newBumpId) override; 105 106 Status GetLoadedModuleFileSpec(const char *module_path, 107 FileSpec &file_spec) override; 108 109 Status GetFileLoadAddress(const llvm::StringRef &file_name, 110 lldb::addr_t &load_addr) override; 111 112 NativeThreadDarwinSP GetThreadByID(lldb::tid_t id); 113 GetTask()114 task_t GetTask() const { return m_task; } 115 116 // ----------------------------------------------------------------- 117 // Interface used by NativeRegisterContext-derived classes. 118 // ----------------------------------------------------------------- 119 static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, 120 void *data = nullptr, size_t data_size = 0, 121 long *result = nullptr); 122 123 bool SupportHardwareSingleStepping() const; 124 125 protected: 126 // ----------------------------------------------------------------- 127 // NativeProcessProtocol protected interface 128 // ----------------------------------------------------------------- 129 Status 130 GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, 131 size_t &actual_opcode_size, 132 const uint8_t *&trap_opcode_bytes) override; 133 134 private: 135 // ----------------------------------------------------------------- 136 /// Mach task-related Member Variables 137 // ----------------------------------------------------------------- 138 139 // The task port for the inferior process. 140 mutable task_t m_task; 141 142 // True if the inferior process did an exec since we started 143 // monitoring it. 144 bool m_did_exec; 145 146 // The CPU type of this process. 147 mutable cpu_type_t m_cpu_type; 148 149 // ----------------------------------------------------------------- 150 /// Exception/Signal Handling Member Variables 151 // ----------------------------------------------------------------- 152 153 // Exception port on which we will receive child exceptions 154 mach_port_t m_exception_port; 155 156 // Saved state of the child exception port prior to us installing 157 // our own intercepting port. 158 MachException::PortInfo m_exc_port_info; 159 160 // The thread that runs the Mach exception read and reply handler. 161 pthread_t m_exception_thread; 162 163 // TODO see if we can remove this if we get the exception collection 164 // and distribution to happen in a single-threaded fashion. 165 std::recursive_mutex m_exception_messages_mutex; 166 167 // A collection of exception messages caught when listening to the 168 // exception port. 169 MachException::Message::collection m_exception_messages; 170 171 // When we call MachProcess::Interrupt(), we want to send this 172 // signal (if non-zero). 173 int m_sent_interrupt_signo; 174 175 // If we resume the process and still haven't received our 176 // interrupt signal (if this is non-zero). 177 int m_auto_resume_signo; 178 179 // ----------------------------------------------------------------- 180 /// Thread-related Member Variables 181 // ----------------------------------------------------------------- 182 NativeThreadListDarwin m_thread_list; 183 ResumeActionList m_thread_actions; 184 185 // ----------------------------------------------------------------- 186 /// Process Lifetime Member Variable 187 // ----------------------------------------------------------------- 188 189 // The pipe over which the waitpid thread and the main loop will 190 // communicate. 191 Pipe m_waitpid_pipe; 192 193 // The thread that runs the waitpid handler. 194 pthread_t m_waitpid_thread; 195 196 // waitpid reader callback handle. 197 MainLoop::ReadHandleUP m_waitpid_reader_handle; 198 199 // ----------------------------------------------------------------- 200 // Private Instance Methods 201 // ----------------------------------------------------------------- 202 NativeProcessDarwin(lldb::pid_t pid, int pty_master_fd); 203 204 // ----------------------------------------------------------------- 205 /// Finalize the launch. 206 /// 207 /// This method associates the NativeProcessDarwin instance with the host 208 /// process that was just launched. It peforms actions like attaching a 209 /// listener to the inferior exception port, ptracing the process, and the 210 /// like. 211 /// 212 /// @param[in] launch_flavor 213 /// The launch flavor that was used to launch the process. 214 /// 215 /// @param[in] main_loop 216 /// The main loop that will run the process monitor. Work 217 /// that needs to be done (e.g. reading files) gets registered 218 /// here along with callbacks to process the work. 219 /// 220 /// @return 221 /// Any error that occurred during the aforementioned 222 /// operations. Failure here will force termination of the 223 /// launched process and debugging session. 224 // ----------------------------------------------------------------- 225 Status FinalizeLaunch(LaunchFlavor launch_flavor, MainLoop &main_loop); 226 227 Status SaveExceptionPortInfo(); 228 229 void ExceptionMessageReceived(const MachException::Message &message); 230 231 void MaybeRaiseThreadPriority(); 232 233 Status StartExceptionThread(); 234 235 Status SendInferiorExitStatusToMainLoop(::pid_t pid, int status); 236 237 Status HandleWaitpidResult(); 238 239 bool ProcessUsingSpringBoard() const; 240 241 bool ProcessUsingBackBoard() const; 242 243 static void *ExceptionThread(void *arg); 244 245 void *DoExceptionThread(); 246 247 lldb::addr_t GetDYLDAllImageInfosAddress(Status &error) const; 248 249 static uint32_t GetCPUTypeForLocalProcess(::pid_t pid); 250 251 uint32_t GetCPUType() const; 252 253 task_t ExceptionMessageBundleComplete(); 254 255 void StartSTDIOThread(); 256 257 Status StartWaitpidThread(MainLoop &main_loop); 258 259 static void *WaitpidThread(void *arg); 260 261 void *DoWaitpidThread(); 262 263 task_t TaskPortForProcessID(Status &error, bool force = false) const; 264 265 /// Attaches to an existing process. Forms the implementation of 266 /// Process::DoAttach. 267 void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error); 268 269 ::pid_t Attach(lldb::pid_t pid, Status &error); 270 271 Status PrivateResume(); 272 273 Status ReplyToAllExceptions(); 274 275 Status ResumeTask(); 276 277 bool IsTaskValid() const; 278 279 bool IsTaskValid(task_t task) const; 280 281 mach_port_t GetExceptionPort() const; 282 283 bool IsExceptionPortValid() const; 284 285 Status GetTaskBasicInfo(task_t task, struct task_basic_info *info) const; 286 287 Status SuspendTask(); 288 289 static Status SetDefaultPtraceOpts(const lldb::pid_t); 290 291 static void *MonitorThread(void *baton); 292 293 void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); 294 295 void WaitForNewThread(::pid_t tid); 296 297 void MonitorSIGTRAP(const siginfo_t &info, NativeThreadDarwin &thread); 298 299 void MonitorTrace(NativeThreadDarwin &thread); 300 301 void MonitorBreakpoint(NativeThreadDarwin &thread); 302 303 void MonitorWatchpoint(NativeThreadDarwin &thread, uint32_t wp_index); 304 305 void MonitorSignal(const siginfo_t &info, NativeThreadDarwin &thread, 306 bool exited); 307 308 Status SetupSoftwareSingleStepping(NativeThreadDarwin &thread); 309 310 bool HasThreadNoLock(lldb::tid_t thread_id); 311 312 bool StopTrackingThread(lldb::tid_t thread_id); 313 314 NativeThreadDarwinSP AddThread(lldb::tid_t thread_id); 315 316 Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); 317 318 Status FixupBreakpointPCAsNeeded(NativeThreadDarwin &thread); 319 320 /// Writes a siginfo_t structure corresponding to the given thread 321 /// ID to the memory region pointed to by @p siginfo. 322 Status GetSignalInfo(lldb::tid_t tid, void *siginfo); 323 324 /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) 325 /// corresponding to the given thread ID to the memory pointed to by @p 326 /// message. 327 Status GetEventMessage(lldb::tid_t tid, unsigned long *message); 328 329 void NotifyThreadDeath(lldb::tid_t tid); 330 331 Status Detach(lldb::tid_t tid); 332 333 // This method is requests a stop on all threads which are still 334 // running. It sets up a deferred delegate notification, which will 335 // fire once threads report as stopped. The triggerring_tid will be 336 // set as the current thread (main stop reason). 337 void StopRunningThreads(lldb::tid_t triggering_tid); 338 339 // Notify the delegate if all threads have stopped. 340 void SignalIfAllThreadsStopped(); 341 342 // Resume the given thread, optionally passing it the given signal. 343 // The type of resume operation (continue, single-step) depends on 344 // the state parameter. 345 Status ResumeThread(NativeThreadDarwin &thread, lldb::StateType state, 346 int signo); 347 348 void ThreadWasCreated(NativeThreadDarwin &thread); 349 350 void SigchldHandler(); 351 }; 352 353 } // namespace process_darwin 354 } // namespace lldb_private 355 356 #endif /* NativeProcessDarwin_h */ 357