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