blob: 20ce582d973ec9e7f72afe4732e95b76e7b9843c [file] [log] [blame]
Johnny Chen9ed5b492012-01-05 21:48:15 +00001//===-- ProcessMonitor.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_ProcessMonitor_H_
11#define liblldb_ProcessMonitor_H_
12
13// C Includes
14#include <semaphore.h>
15#include <signal.h>
16
17// C++ Includes
18// Other libraries and framework includes
19#include "lldb/lldb-types.h"
Ed Maste41fba2b2015-06-01 15:24:37 +000020#include "lldb/Host/FileSpec.h"
Zachary Turner39de3112014-09-09 20:54:56 +000021#include "lldb/Host/HostThread.h"
Johnny Chen9ed5b492012-01-05 21:48:15 +000022#include "lldb/Host/Mutex.h"
23
24namespace lldb_private
25{
26class Error;
27class Module;
28class Scalar;
29} // End lldb_private namespace.
30
31class ProcessFreeBSD;
32class Operation;
33
34/// @class ProcessMonitor
35/// @brief Manages communication with the inferior (debugee) process.
36///
37/// Upon construction, this class prepares and launches an inferior process for
38/// debugging.
39///
40/// Changes in the inferior process state are propagated to the associated
41/// ProcessFreeBSD instance by calling ProcessFreeBSD::SendMessage with the
42/// appropriate ProcessMessage events.
43///
44/// A purposely minimal set of operations are provided to interrogate and change
45/// the inferior process state.
46class ProcessMonitor
47{
48public:
49
50 /// Launches an inferior process ready for debugging. Forms the
51 /// implementation of Process::DoLaunch.
Andrew Kaylor6578cb62013-07-09 22:36:48 +000052 ProcessMonitor(ProcessPOSIX *process,
Johnny Chen9ed5b492012-01-05 21:48:15 +000053 lldb_private::Module *module,
54 char const *argv[],
55 char const *envp[],
Ed Maste41fba2b2015-06-01 15:24:37 +000056 const lldb_private::FileSpec &stdin_file_spec,
57 const lldb_private::FileSpec &stdout_file_spec,
58 const lldb_private::FileSpec &stderr_file_spec,
59 const lldb_private::FileSpec &working_dir,
Todd Fiala0bce1b62014-08-17 00:10:50 +000060 const lldb_private::ProcessLaunchInfo &launch_info,
Johnny Chen9ed5b492012-01-05 21:48:15 +000061 lldb_private::Error &error);
62
Andrew Kaylor6578cb62013-07-09 22:36:48 +000063 ProcessMonitor(ProcessPOSIX *process,
Johnny Chen9ed5b492012-01-05 21:48:15 +000064 lldb::pid_t pid,
65 lldb_private::Error &error);
66
67 ~ProcessMonitor();
68
69 /// Provides the process number of debugee.
70 lldb::pid_t
71 GetPID() const { return m_pid; }
72
73 /// Returns the process associated with this ProcessMonitor.
74 ProcessFreeBSD &
75 GetProcess() { return *m_process; }
76
77 /// Returns a file descriptor to the controlling terminal of the inferior
78 /// process.
79 ///
80 /// Reads from this file descriptor yield both the standard output and
81 /// standard error of this debugee. Even if stderr and stdout were
82 /// redirected on launch it may still happen that data is available on this
Pavel Labath3a2da9e2015-02-06 11:32:52 +000083 /// descriptor (if the inferior process opens /dev/tty, for example). This descriptor is
84 /// closed after a call to StopMonitor().
Johnny Chen9ed5b492012-01-05 21:48:15 +000085 ///
86 /// If this monitor was attached to an existing process this method returns
87 /// -1.
88 int
89 GetTerminalFD() const { return m_terminal_fd; }
90
91 /// Reads @p size bytes from address @vm_adder in the inferior process
92 /// address space.
93 ///
94 /// This method is provided to implement Process::DoReadMemory.
95 size_t
96 ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
97 lldb_private::Error &error);
98
99 /// Writes @p size bytes from address @p vm_adder in the inferior process
100 /// address space.
101 ///
102 /// This method is provided to implement Process::DoWriteMemory.
103 size_t
104 WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
105 lldb_private::Error &error);
106
107 /// Reads the contents from the register identified by the given (architecture
108 /// dependent) offset.
109 ///
110 /// This method is provided for use by RegisterContextFreeBSD derivatives.
111 bool
Ashok Thirumurthiacbb1a52013-05-09 19:59:47 +0000112 ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
Daniel Maleaf0da3712012-12-18 19:50:15 +0000113 unsigned size, lldb_private::RegisterValue &value);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000114
115 /// Writes the given value to the register identified by the given
116 /// (architecture dependent) offset.
117 ///
118 /// This method is provided for use by RegisterContextFreeBSD derivatives.
119 bool
Ashok Thirumurthiacbb1a52013-05-09 19:59:47 +0000120 WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name,
Daniel Maleaf0da3712012-12-18 19:50:15 +0000121 const lldb_private::RegisterValue &value);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000122
Ed Mastea4be2c52014-02-19 18:34:06 +0000123 /// Reads the contents from the debug register identified by the given
124 /// (architecture dependent) offset.
125 ///
126 /// This method is provided for use by RegisterContextFreeBSD derivatives.
127 bool
128 ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
129 const char *reg_name, unsigned size,
130 lldb_private::RegisterValue &value);
131
132 /// Writes the given value to the debug register identified by the given
133 /// (architecture dependent) offset.
134 ///
135 /// This method is provided for use by RegisterContextFreeBSD derivatives.
136 bool
137 WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
138 const char *reg_name,
139 const lldb_private::RegisterValue &value);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000140 /// Reads all general purpose registers into the specified buffer.
141 bool
Matt Kopec7de48462013-03-06 17:20:48 +0000142 ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000143
Matt Kopecc6672c82013-03-15 20:00:39 +0000144 /// Reads all floating point registers into the specified buffer.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000145 bool
Matt Kopec7de48462013-03-06 17:20:48 +0000146 ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000147
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000148 /// Reads the specified register set into the specified buffer.
149 ///
150 /// This method is provided for use by RegisterContextFreeBSD derivatives.
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000151 bool
152 ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
153
Johnny Chen9ed5b492012-01-05 21:48:15 +0000154 /// Writes all general purpose registers into the specified buffer.
155 bool
Matt Kopec7de48462013-03-06 17:20:48 +0000156 WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000157
Matt Kopecc6672c82013-03-15 20:00:39 +0000158 /// Writes all floating point registers into the specified buffer.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000159 bool
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000160 WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
161
162 /// Writes the specified register set into the specified buffer.
163 ///
164 /// This method is provided for use by RegisterContextFreeBSD derivatives.
Ashok Thirumurthi0f3b9b82013-05-01 20:38:19 +0000165 bool
166 WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000167
Ed Maste68f51792013-10-18 19:16:44 +0000168 /// Reads the value of the thread-specific pointer for a given thread ID.
169 bool
170 ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value);
171
Ed Maste7fd845c2013-12-09 15:51:17 +0000172 /// Returns current thread IDs in process
173 size_t
174 GetCurrentThreadIDs(std::vector<lldb::tid_t> &thread_ids);
175
Ed Maste819e3992013-07-17 14:02:20 +0000176 /// Writes a ptrace_lwpinfo structure corresponding to the given thread ID
177 /// to the memory region pointed to by @p lwpinfo.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000178 bool
Ed Maste819e3992013-07-17 14:02:20 +0000179 GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &error_no);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000180
Ed Maste7fd845c2013-12-09 15:51:17 +0000181 /// Suspends or unsuspends a thread prior to process resume or step.
182 bool
183 ThreadSuspend(lldb::tid_t tid, bool suspend);
184
Johnny Chen9ed5b492012-01-05 21:48:15 +0000185 /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
186 /// corresponding to the given thread IDto the memory pointed to by @p
187 /// message.
188 bool
189 GetEventMessage(lldb::tid_t tid, unsigned long *message);
190
Ed Maste502f9022013-11-25 16:31:23 +0000191 /// Resumes the process. If @p signo is anything but
192 /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000193 bool
Ed Maste502f9022013-11-25 16:31:23 +0000194 Resume(lldb::tid_t unused, uint32_t signo);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000195
Ed Maste502f9022013-11-25 16:31:23 +0000196 /// Single steps the process. If @p signo is anything but
197 /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the process.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000198 bool
Ed Maste502f9022013-11-25 16:31:23 +0000199 SingleStep(lldb::tid_t unused, uint32_t signo);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000200
Ed Maste70882932014-04-01 14:30:56 +0000201 /// Terminate the traced process.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000202 bool
Ed Maste70882932014-04-01 14:30:56 +0000203 Kill();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000204
205 lldb_private::Error
Matt Kopecedee1822013-06-03 19:48:53 +0000206 Detach(lldb::tid_t tid);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000207
Andrew Kaylorbc68b432013-07-10 21:57:27 +0000208 void
209 StopMonitor();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000210
Andrew Kaylord4d54992013-09-17 00:30:24 +0000211 // Waits for the initial stop message from a new thread.
212 bool
213 WaitForInitialTIDStop(lldb::tid_t tid);
214
Johnny Chen9ed5b492012-01-05 21:48:15 +0000215private:
Andrew Kaylor6578cb62013-07-09 22:36:48 +0000216 ProcessFreeBSD *m_process;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000217
Ed Maste39677642014-09-10 13:38:47 +0000218 lldb_private::HostThread m_operation_thread;
219 lldb_private::HostThread m_monitor_thread;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000220 lldb::pid_t m_pid;
221
Johnny Chen9ed5b492012-01-05 21:48:15 +0000222 int m_terminal_fd;
Johnny Chen9ed5b492012-01-05 21:48:15 +0000223
Ed Maste756e1ff2013-09-18 19:34:08 +0000224 // current operation which must be executed on the privileged thread
225 Operation *m_operation;
226 lldb_private::Mutex m_operation_mutex;
227
228 // semaphores notified when Operation is ready to be processed and when
229 // the operation is complete.
230 sem_t m_operation_pending;
231 sem_t m_operation_done;
Ed Maste41fba2b2015-06-01 15:24:37 +0000232
Johnny Chen9ed5b492012-01-05 21:48:15 +0000233 struct OperationArgs
234 {
235 OperationArgs(ProcessMonitor *monitor);
236
237 ~OperationArgs();
238
239 ProcessMonitor *m_monitor; // The monitor performing the attach.
240 sem_t m_semaphore; // Posted to once operation complete.
241 lldb_private::Error m_error; // Set if process operation failed.
242 };
243
244 /// @class LauchArgs
245 ///
246 /// @brief Simple structure to pass data to the thread responsible for
247 /// launching a child process.
248 struct LaunchArgs : OperationArgs
249 {
250 LaunchArgs(ProcessMonitor *monitor,
251 lldb_private::Module *module,
252 char const **argv,
253 char const **envp,
Ed Maste41fba2b2015-06-01 15:24:37 +0000254 const lldb_private::FileSpec &stdin_file_spec,
255 const lldb_private::FileSpec &stdout_file_spec,
256 const lldb_private::FileSpec &stderr_file_spec,
257 const lldb_private::FileSpec &working_dir);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000258
259 ~LaunchArgs();
260
Ed Maste41fba2b2015-06-01 15:24:37 +0000261 lldb_private::Module *m_module; // The executable image to launch.
262 char const **m_argv; // Process arguments.
263 char const **m_envp; // Process environment.
264 const lldb_private::FileSpec m_stdin_file_spec; // Redirect stdin or empty.
265 const lldb_private::FileSpec m_stdout_file_spec; // Redirect stdout or empty.
266 const lldb_private::FileSpec m_stderr_file_spec; // Redirect stderr or empty.
267 const lldb_private::FileSpec m_working_dir; // Working directory or empty.
Johnny Chen9ed5b492012-01-05 21:48:15 +0000268 };
269
270 void
271 StartLaunchOpThread(LaunchArgs *args, lldb_private::Error &error);
272
Johnny Chen9ed5b492012-01-05 21:48:15 +0000273 static void *
274 LaunchOpThread(void *arg);
275
276 static bool
277 Launch(LaunchArgs *args);
278
Johnny Chen9ed5b492012-01-05 21:48:15 +0000279 struct AttachArgs : OperationArgs
280 {
281 AttachArgs(ProcessMonitor *monitor,
282 lldb::pid_t pid);
283
284 ~AttachArgs();
285
286 lldb::pid_t m_pid; // pid of the process to be attached.
287 };
288
289 void
290 StartAttachOpThread(AttachArgs *args, lldb_private::Error &error);
291
Johnny Chen9ed5b492012-01-05 21:48:15 +0000292 static void *
293 AttachOpThread(void *args);
294
Oleksiy Vyalov5d064742014-11-19 18:27:45 +0000295 static void
Johnny Chen9ed5b492012-01-05 21:48:15 +0000296 Attach(AttachArgs *args);
297
298 static void
299 ServeOperation(OperationArgs *args);
300
301 static bool
Ed Maste41fba2b2015-06-01 15:24:37 +0000302 DupDescriptor(const lldb_private::FileSpec &file_spec, int fd, int flags);
Johnny Chen9ed5b492012-01-05 21:48:15 +0000303
304 static bool
305 MonitorCallback(void *callback_baton,
306 lldb::pid_t pid, bool exited, int signal, int status);
307
308 static ProcessMessage
309 MonitorSIGTRAP(ProcessMonitor *monitor,
310 const siginfo_t *info, lldb::pid_t pid);
311
312 static ProcessMessage
313 MonitorSignal(ProcessMonitor *monitor,
314 const siginfo_t *info, lldb::pid_t pid);
315
Johnny Chen9ed5b492012-01-05 21:48:15 +0000316 void
317 DoOperation(Operation *op);
318
319 /// Stops the child monitor thread.
320 void
321 StopMonitoringChildProcess();
322
Ed Mastea02f5532013-07-02 16:45:16 +0000323 /// Stops the operation thread used to attach/launch a process.
324 void
325 StopOpThread();
Johnny Chen9ed5b492012-01-05 21:48:15 +0000326};
327
328#endif // #ifndef liblldb_ProcessMonitor_H_