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