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

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

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