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