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