1//===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_NativeProcessLinux_H_
10#define liblldb_NativeProcessLinux_H_
11
12#include <csignal>
13#include <unordered_set>
14
15#include "lldb/Host/Debug.h"
16#include "lldb/Host/HostThread.h"
17#include "lldb/Host/linux/Support.h"
18#include "lldb/Target/MemoryRegionInfo.h"
19#include "lldb/Utility/ArchSpec.h"
20#include "lldb/Utility/FileSpec.h"
21#include "lldb/lldb-types.h"
22#include "llvm/ADT/SmallPtrSet.h"
23
24#include "IntelPTCollector.h"
25#include "NativeThreadLinux.h"
26#include "Plugins/Process/POSIX/NativeProcessELF.h"
27#include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
28
29namespace lldb_private {
30class Status;
31class Scalar;
32
33namespace process_linux {
34/// \class NativeProcessLinux
35/// Manages communication with the inferior (debugee) process.
36///
37/// Upon construction, this class prepares and launches an inferior process
38/// for debugging.
39///
40/// Changes in the inferior process state are broadcasted.
41class NativeProcessLinux : public NativeProcessELF,
42 private NativeProcessSoftwareSingleStep {
43public:
44 class Manager : public NativeProcessProtocol::Manager {
45 public:
46 Manager(MainLoop &mainloop);
47
48 llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
49 Launch(ProcessLaunchInfo &launch_info,
50 NativeDelegate &native_delegate) override;
51
52 llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
53 Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override;
54
55 Extension GetSupportedExtensions() const override;
56
57 void AddProcess(NativeProcessLinux &process) {
58 m_processes.insert(Ptr: &process);
59 }
60
61 void RemoveProcess(NativeProcessLinux &process) {
62 m_processes.erase(Ptr: &process);
63 }
64
65 // Collect an event for the given tid, waiting for it if necessary.
66 void CollectThread(::pid_t tid);
67
68 private:
69 MainLoop::SignalHandleUP m_sigchld_handle;
70
71 llvm::SmallPtrSet<NativeProcessLinux *, 2> m_processes;
72
73 // Threads (events) which haven't been claimed by any process.
74 llvm::DenseSet<::pid_t> m_unowned_threads;
75
76 void SigchldHandler();
77 };
78
79 // NativeProcessProtocol Interface
80
81 ~NativeProcessLinux() override { m_manager.RemoveProcess(process&: *this); }
82
83 Status Resume(const ResumeActionList &resume_actions) override;
84
85 Status Halt() override;
86
87 Status Detach() override;
88
89 Status Signal(int signo) override;
90
91 Status Interrupt() override;
92
93 Status Kill() override;
94
95 Status GetMemoryRegionInfo(lldb::addr_t load_addr,
96 MemoryRegionInfo &range_info) override;
97
98 Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
99 size_t &bytes_read) override;
100
101 Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
102 size_t &bytes_written) override;
103
104 llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
105 uint32_t permissions) override;
106
107 llvm::Error DeallocateMemory(lldb::addr_t addr) override;
108
109 Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
110 std::vector<uint8_t> &tags) override;
111
112 Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
113 const std::vector<uint8_t> &tags) override;
114
115 size_t UpdateThreads() override;
116
117 const ArchSpec &GetArchitecture() const override { return m_arch; }
118
119 Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
120 bool hardware) override;
121
122 Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
123
124 void DoStopIDBumped(uint32_t newBumpId) override;
125
126 Status GetLoadedModuleFileSpec(const char *module_path,
127 FileSpec &file_spec) override;
128
129 Status GetFileLoadAddress(const llvm::StringRef &file_name,
130 lldb::addr_t &load_addr) override;
131
132 NativeThreadLinux *GetThreadByID(lldb::tid_t id);
133 NativeThreadLinux *GetCurrentThread();
134
135 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
136 GetAuxvData() const override {
137 return getProcFile(pid: GetID(), file: "auxv");
138 }
139
140 /// Tracing
141 /// These methods implement the jLLDBTrace packets
142 /// \{
143 llvm::Error TraceStart(llvm::StringRef json_request,
144 llvm::StringRef type) override;
145
146 llvm::Error TraceStop(const TraceStopRequest &request) override;
147
148 llvm::Expected<llvm::json::Value>
149 TraceGetState(llvm::StringRef type) override;
150
151 llvm::Expected<std::vector<uint8_t>>
152 TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
153
154 llvm::Expected<TraceSupportedResponse> TraceSupported() override;
155 /// }
156
157 // Interface used by NativeRegisterContext-derived classes.
158 static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
159 void *data = nullptr, size_t data_size = 0,
160 long *result = nullptr);
161
162 bool SupportHardwareSingleStepping() const;
163
164 /// Writes a siginfo_t structure corresponding to the given thread ID to the
165 /// memory region pointed to by \p siginfo.
166 Status GetSignalInfo(lldb::tid_t tid, void *siginfo) const;
167
168protected:
169 llvm::Expected<llvm::ArrayRef<uint8_t>>
170 GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
171
172 llvm::Expected<uint64_t> Syscall(llvm::ArrayRef<uint64_t> args);
173
174private:
175 Manager &m_manager;
176 ArchSpec m_arch;
177
178 LazyBool m_supports_mem_region = eLazyBoolCalculate;
179 std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
180
181 lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
182
183 /// Inferior memory (allocated by us) and its size.
184 llvm::DenseMap<lldb::addr_t, lldb::addr_t> m_allocated_memory;
185
186 // Private Instance Methods
187 NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
188 const ArchSpec &arch, Manager &manager,
189 llvm::ArrayRef<::pid_t> tids);
190
191 // Returns a list of process threads that we have attached to.
192 static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
193
194 static Status SetDefaultPtraceOpts(const lldb::pid_t);
195
196 bool TryHandleWaitStatus(lldb::pid_t pid, WaitStatus status);
197
198 void MonitorCallback(NativeThreadLinux &thread, WaitStatus status);
199
200 void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
201
202 void MonitorTrace(NativeThreadLinux &thread);
203
204 void MonitorBreakpoint(NativeThreadLinux &thread);
205
206 void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
207
208 void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread);
209
210 bool HasThreadNoLock(lldb::tid_t thread_id);
211
212 void StopTrackingThread(NativeThreadLinux &thread);
213
214 /// Create a new thread.
215 ///
216 /// If process tracing is enabled and the thread can't be traced, then the
217 /// thread is left stopped with a \a eStopReasonProcessorTrace status, and
218 /// then the process is stopped.
219 ///
220 /// \param[in] resume
221 /// If a tracing error didn't happen, then resume the thread after
222 /// creation if \b true, or leave it stopped with SIGSTOP if \b false.
223 NativeThreadLinux &AddThread(lldb::tid_t thread_id, bool resume);
224
225 /// Start tracing a new thread if process tracing is enabled.
226 ///
227 /// Trace mechanisms should modify this method to provide automatic tracing
228 /// for new threads.
229 Status NotifyTracersOfNewThread(lldb::tid_t tid);
230
231 /// Stop tracing threads upon a destroy event.
232 ///
233 /// Trace mechanisms should modify this method to provide automatic trace
234 /// stopping for threads being destroyed.
235 Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid);
236
237 void NotifyTracersProcessWillResume() override;
238
239 void NotifyTracersProcessDidStop() override;
240
241 /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
242 /// corresponding to the given thread ID to the memory pointed to by @p
243 /// message.
244 Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
245
246 void NotifyThreadDeath(lldb::tid_t tid);
247
248 Status Detach(lldb::tid_t tid);
249
250 // This method is requests a stop on all threads which are still running. It
251 // sets up a
252 // deferred delegate notification, which will fire once threads report as
253 // stopped. The
254 // triggerring_tid will be set as the current thread (main stop reason).
255 void StopRunningThreads(lldb::tid_t triggering_tid);
256
257 // Notify the delegate if all threads have stopped.
258 void SignalIfAllThreadsStopped();
259
260 // Resume the given thread, optionally passing it the given signal. The type
261 // of resume
262 // operation (continue, single-step) depends on the state parameter.
263 Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
264 int signo);
265
266 void ThreadWasCreated(NativeThreadLinux &thread);
267
268 void SigchldHandler();
269
270 Status PopulateMemoryRegionCache();
271
272 /// Manages Intel PT process and thread traces.
273 IntelPTCollector m_intel_pt_collector;
274
275 // Handle a clone()-like event.
276 bool MonitorClone(NativeThreadLinux &parent, lldb::pid_t child_pid,
277 int event);
278};
279
280} // namespace process_linux
281} // namespace lldb_private
282
283#endif // #ifndef liblldb_NativeProcessLinux_H_
284

source code of lldb/source/Plugins/Process/Linux/NativeProcessLinux.h