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         bool
131         SupportHardwareSingleStepping() const;
132 
133     protected:
134         // ---------------------------------------------------------------------
135         // NativeProcessProtocol protected interface
136         // ---------------------------------------------------------------------
137         Error
138         GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;
139 
140     private:
141 
142         MainLoop::SignalHandleUP m_sigchld_handle;
143         ArchSpec m_arch;
144 
145         LazyBool m_supports_mem_region;
146         std::vector<MemoryRegionInfo> m_mem_region_cache;
147         Mutex m_mem_region_cache_mutex;
148 
149         lldb::tid_t m_pending_notification_tid;
150 
151         // List of thread ids stepping with a breakpoint with the address of
152         // the relevan breakpoint
153         std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
154 
155         /// @class LauchArgs
156         ///
157         /// @brief Simple structure to pass data to the thread responsible for
158         /// launching a child process.
159         struct LaunchArgs
160         {
161             LaunchArgs(Module *module,
162                     char const **argv,
163                     char const **envp,
164                     const FileSpec &stdin_file_spec,
165                     const FileSpec &stdout_file_spec,
166                     const FileSpec &stderr_file_spec,
167                     const FileSpec &working_dir,
168                     const ProcessLaunchInfo &launch_info);
169 
170             ~LaunchArgs();
171 
172             Module *m_module;                  // The executable image to launch.
173             char const **m_argv;               // Process arguments.
174             char const **m_envp;               // Process environment.
175             const FileSpec m_stdin_file_spec;  // Redirect stdin if not empty.
176             const FileSpec m_stdout_file_spec; // Redirect stdout if not empty.
177             const FileSpec m_stderr_file_spec; // Redirect stderr if not empty.
178             const FileSpec m_working_dir;      // Working directory or empty.
179             const ProcessLaunchInfo &m_launch_info;
180         };
181 
182         typedef std::function< ::pid_t(Error &)> InitialOperation;
183 
184         // ---------------------------------------------------------------------
185         // Private Instance Methods
186         // ---------------------------------------------------------------------
187         NativeProcessLinux ();
188 
189         /// Launches an inferior process ready for debugging.  Forms the
190         /// implementation of Process::DoLaunch.
191         void
192         LaunchInferior (
193             MainLoop &mainloop,
194             Module *module,
195             char const *argv[],
196             char const *envp[],
197             const FileSpec &stdin_file_spec,
198             const FileSpec &stdout_file_spec,
199             const FileSpec &stderr_file_spec,
200             const FileSpec &working_dir,
201             const ProcessLaunchInfo &launch_info,
202             Error &error);
203 
204         /// Attaches to an existing process.  Forms the
205         /// implementation of Process::DoAttach
206         void
207         AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
208 
209         ::pid_t
210         Launch(LaunchArgs *args, Error &error);
211 
212         ::pid_t
213         Attach(lldb::pid_t pid, Error &error);
214 
215         static Error
216         SetDefaultPtraceOpts(const lldb::pid_t);
217 
218         static bool
219         DupDescriptor(const FileSpec &file_spec, int fd, int flags);
220 
221         static void *
222         MonitorThread(void *baton);
223 
224         void
225         MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
226 
227         void
228         WaitForNewThread(::pid_t tid);
229 
230         void
231         MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
232 
233         void
234         MonitorTrace(NativeThreadLinux &thread);
235 
236         void
237         MonitorBreakpoint(NativeThreadLinux &thread);
238 
239         void
240         MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
241 
242         void
243         MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
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         void
289         NotifyThreadDeath (lldb::tid_t tid);
290 
291         Error
292         Detach(lldb::tid_t tid);
293 
294 
295         // This method is requests a stop on all threads which are still running. It sets up a
296         // deferred delegate notification, which will fire once threads report as stopped. The
297         // triggerring_tid will be set as the current thread (main stop reason).
298         void
299         StopRunningThreads(lldb::tid_t triggering_tid);
300 
301         // Notify the delegate if all threads have stopped.
302         void SignalIfAllThreadsStopped();
303 
304         // Resume the given thread, optionally passing it the given signal. The type of resume
305         // operation (continue, single-step) depends on the state parameter.
306         Error
307         ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
308 
309         void
310         ThreadWasCreated(NativeThreadLinux &thread);
311 
312         void
313         SigchldHandler();
314     };
315 
316 } // namespace process_linux
317 } // namespace lldb_private
318 
319 #endif // #ifndef liblldb_NativeProcessLinux_H_
320