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/lldb-types.h"
19 #include "lldb/Host/Debug.h"
20 #include "lldb/Host/FileSpec.h"
21 #include "lldb/Host/HostThread.h"
22 #include "lldb/Host/Mutex.h"
23 #include "lldb/Target/MemoryRegionInfo.h"
24 
25 #include "lldb/Host/common/NativeProcessProtocol.h"
26 #include "NativeThreadLinux.h"
27 
28 namespace lldb_private {
29     class Error;
30     class Module;
31     class Scalar;
32 
33 namespace process_linux {
34     /// @class NativeProcessLinux
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 broadcasted.
41     class NativeProcessLinux: public NativeProcessProtocol
42     {
43         friend Error
44         NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info,
45                 NativeDelegate &native_delegate,
46                 MainLoop &mainloop,
47                 NativeProcessProtocolSP &process_sp);
48 
49         friend Error
50         NativeProcessProtocol::Attach (lldb::pid_t pid,
51                 NativeProcessProtocol::NativeDelegate &native_delegate,
52                 MainLoop &mainloop,
53                 NativeProcessProtocolSP &process_sp);
54 
55     public:
56         // ---------------------------------------------------------------------
57         // NativeProcessProtocol Interface
58         // ---------------------------------------------------------------------
59         Error
60         Resume (const ResumeActionList &resume_actions) override;
61 
62         Error
63         Halt () override;
64 
65         Error
66         Detach () override;
67 
68         Error
69         Signal (int signo) override;
70 
71         Error
72         Interrupt () override;
73 
74         Error
75         Kill () override;
76 
77         Error
78         GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override;
79 
80         Error
81         ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
82 
83         Error
84         ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
85 
86         Error
87         WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override;
88 
89         Error
90         AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override;
91 
92         Error
93         DeallocateMemory (lldb::addr_t addr) override;
94 
95         lldb::addr_t
96         GetSharedLibraryInfoAddress () override;
97 
98         size_t
99         UpdateThreads () override;
100 
101         bool
102         GetArchitecture (ArchSpec &arch) const override;
103 
104         Error
105         SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;
106 
107         void
108         DoStopIDBumped (uint32_t newBumpId) override;
109 
110         Error
111         GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
112 
113         Error
114         GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override;
115 
116         NativeThreadLinuxSP
117         GetThreadByID(lldb::tid_t id);
118 
119         // ---------------------------------------------------------------------
120         // Interface used by NativeRegisterContext-derived classes.
121         // ---------------------------------------------------------------------
122         static Error
123         PtraceWrapper(int req,
124                       lldb::pid_t pid,
125                       void *addr = nullptr,
126                       void *data = nullptr,
127                       size_t data_size = 0,
128                       long *result = nullptr);
129 
130     protected:
131         // ---------------------------------------------------------------------
132         // NativeProcessProtocol protected interface
133         // ---------------------------------------------------------------------
134         Error
135         GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;
136 
137     private:
138 
139         MainLoop::SignalHandleUP m_sigchld_handle;
140         ArchSpec m_arch;
141 
142         LazyBool m_supports_mem_region;
143         std::vector<MemoryRegionInfo> m_mem_region_cache;
144         Mutex m_mem_region_cache_mutex;
145 
146         lldb::tid_t m_pending_notification_tid;
147 
148         // List of thread ids stepping with a breakpoint with the address of
149         // the relevan breakpoint
150         std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
151 
152         /// @class LauchArgs
153         ///
154         /// @brief Simple structure to pass data to the thread responsible for
155         /// launching a child process.
156         struct LaunchArgs
157         {
158             LaunchArgs(Module *module,
159                     char const **argv,
160                     char const **envp,
161                     const FileSpec &stdin_file_spec,
162                     const FileSpec &stdout_file_spec,
163                     const FileSpec &stderr_file_spec,
164                     const FileSpec &working_dir,
165                     const ProcessLaunchInfo &launch_info);
166 
167             ~LaunchArgs();
168 
169             Module *m_module;                  // The executable image to launch.
170             char const **m_argv;               // Process arguments.
171             char const **m_envp;               // Process environment.
172             const FileSpec m_stdin_file_spec;  // Redirect stdin if not empty.
173             const FileSpec m_stdout_file_spec; // Redirect stdout if not empty.
174             const FileSpec m_stderr_file_spec; // Redirect stderr if not empty.
175             const FileSpec m_working_dir;      // Working directory or empty.
176             const ProcessLaunchInfo &m_launch_info;
177         };
178 
179         typedef std::function< ::pid_t(Error &)> InitialOperation;
180 
181         // ---------------------------------------------------------------------
182         // Private Instance Methods
183         // ---------------------------------------------------------------------
184         NativeProcessLinux ();
185 
186         /// Launches an inferior process ready for debugging.  Forms the
187         /// implementation of Process::DoLaunch.
188         void
189         LaunchInferior (
190             MainLoop &mainloop,
191             Module *module,
192             char const *argv[],
193             char const *envp[],
194             const FileSpec &stdin_file_spec,
195             const FileSpec &stdout_file_spec,
196             const FileSpec &stderr_file_spec,
197             const FileSpec &working_dir,
198             const ProcessLaunchInfo &launch_info,
199             Error &error);
200 
201         /// Attaches to an existing process.  Forms the
202         /// implementation of Process::DoAttach
203         void
204         AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
205 
206         ::pid_t
207         Launch(LaunchArgs *args, Error &error);
208 
209         ::pid_t
210         Attach(lldb::pid_t pid, Error &error);
211 
212         static Error
213         SetDefaultPtraceOpts(const lldb::pid_t);
214 
215         static bool
216         DupDescriptor(const FileSpec &file_spec, int fd, int flags);
217 
218         static void *
219         MonitorThread(void *baton);
220 
221         void
222         MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
223 
224         void
225         WaitForNewThread(::pid_t tid);
226 
227         void
228         MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
229 
230         void
231         MonitorTrace(NativeThreadLinux &thread);
232 
233         void
234         MonitorBreakpoint(NativeThreadLinux &thread);
235 
236         void
237         MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
238 
239         void
240         MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
241 
242         bool
243         SupportHardwareSingleStepping() const;
244 
245         Error
246         SetupSoftwareSingleStepping(NativeThreadLinux &thread);
247 
248 #if 0
249         static ::ProcessMessage::CrashReason
250         GetCrashReasonForSIGSEGV(const siginfo_t *info);
251 
252         static ::ProcessMessage::CrashReason
253         GetCrashReasonForSIGILL(const siginfo_t *info);
254 
255         static ::ProcessMessage::CrashReason
256         GetCrashReasonForSIGFPE(const siginfo_t *info);
257 
258         static ::ProcessMessage::CrashReason
259         GetCrashReasonForSIGBUS(const siginfo_t *info);
260 #endif
261 
262         bool
263         HasThreadNoLock (lldb::tid_t thread_id);
264 
265         bool
266         StopTrackingThread (lldb::tid_t thread_id);
267 
268         NativeThreadLinuxSP
269         AddThread (lldb::tid_t thread_id);
270 
271         Error
272         GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
273 
274         Error
275         FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
276 
277         /// Writes a siginfo_t structure corresponding to the given thread ID to the
278         /// memory region pointed to by @p siginfo.
279         Error
280         GetSignalInfo(lldb::tid_t tid, void *siginfo);
281 
282         /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
283         /// corresponding to the given thread ID to the memory pointed to by @p
284         /// message.
285         Error
286         GetEventMessage(lldb::tid_t tid, unsigned long *message);
287 
288         /// Resumes the given thread.  If @p signo is anything but
289         /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
290         Error
291         Resume(lldb::tid_t tid, uint32_t signo);
292 
293         /// Single steps the given thread.  If @p signo is anything but
294         /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread.
295         Error
296         SingleStep(lldb::tid_t tid, uint32_t signo);
297 
298         void
299         NotifyThreadDeath (lldb::tid_t tid);
300 
301         Error
302         Detach(lldb::tid_t tid);
303 
304 
305         // This method is requests a stop on all threads which are still running. It sets up a
306         // deferred delegate notification, which will fire once threads report as stopped. The
307         // triggerring_tid will be set as the current thread (main stop reason).
308         void
309         StopRunningThreads(lldb::tid_t triggering_tid);
310 
311         // Notify the delegate if all threads have stopped.
312         void SignalIfAllThreadsStopped();
313 
314         // Resume the given thread, optionally passing it the given signal. The type of resume
315         // operation (continue, single-step) depends on the state parameter.
316         Error
317         ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
318 
319         void
320         ThreadWasCreated(NativeThreadLinux &thread);
321 
322         void
323         SigchldHandler();
324     };
325 
326 } // namespace process_linux
327 } // namespace lldb_private
328 
329 #endif // #ifndef liblldb_NativeProcessLinux_H_
330