LLDB mainline
NativeProcessProtocol.h
Go to the documentation of this file.
1//===-- NativeProcessProtocol.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 LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
10#define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
11
15#include "lldb/Host/Host.h"
16#include "lldb/Host/MainLoop.h"
19#include "lldb/Utility/Status.h"
23#include "lldb/lldb-types.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/DenseSet.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/Support/Error.h"
28#include "llvm/Support/MemoryBuffer.h"
29#include <mutex>
30#include <optional>
31#include <unordered_map>
32#include <vector>
33
34namespace lldb_private {
36
39
41 std::string name;
46};
47
48// NativeProcessProtocol
50public:
51 virtual ~NativeProcessProtocol() = default;
52
53 typedef std::vector<std::unique_ptr<NativeThreadProtocol>> thread_collection;
54 template <typename I>
56 assert(*iter);
57 return **iter;
58 }
60 thread_list_adapter, std::recursive_mutex>
62
63 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
64
65 virtual Status Halt() = 0;
66
67 virtual Status Detach() = 0;
68
69 /// Sends a process a UNIX signal \a signal.
70 ///
71 /// \return
72 /// Returns an error object.
73 virtual Status Signal(int signo) = 0;
74
75 /// Tells a process to interrupt all operations as if by a Ctrl-C.
76 ///
77 /// The default implementation will send a local host's equivalent of
78 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
79 /// operation.
80 ///
81 /// \return
82 /// Returns an error object.
83 virtual Status Interrupt();
84
85 virtual Status Kill() = 0;
86
87 // Tells a process not to stop the inferior on given signals and just
88 // reinject them back.
89 virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
90
91 // Memory and memory region functions
92
93 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
94 MemoryRegionInfo &range_info);
95
96 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
97 size_t &bytes_read) = 0;
98
99 Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
100 size_t &bytes_read);
101
102 virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
103 std::vector<uint8_t> &tags);
104
105 virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
106 const std::vector<uint8_t> &tags);
107
108 /// Reads a null terminated string from memory.
109 ///
110 /// Reads up to \p max_size bytes of memory until it finds a '\0'.
111 /// If a '\0' is not found then it reads max_size-1 bytes as a string and a
112 /// '\0' is added as the last character of the \p buffer.
113 ///
114 /// \param[in] addr
115 /// The address in memory to read from.
116 ///
117 /// \param[in] buffer
118 /// An allocated buffer with at least \p max_size size.
119 ///
120 /// \param[in] max_size
121 /// The maximum number of bytes to read from memory until it reads the
122 /// string.
123 ///
124 /// \param[out] total_bytes_read
125 /// The number of bytes read from memory into \p buffer.
126 ///
127 /// \return
128 /// Returns a StringRef backed up by the \p buffer passed in.
129 llvm::Expected<llvm::StringRef>
130 ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
131 size_t &total_bytes_read);
132
133 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
134 size_t &bytes_written) = 0;
135
136 virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
137 uint32_t permissions) {
138 return llvm::make_error<UnimplementedError>();
139 }
140
141 virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
142 return llvm::make_error<UnimplementedError>();
143 }
144
146
147 virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
149 return llvm::createStringError(llvm::inconvertibleErrorCode(),
150 "Not implemented");
151 }
152
153 virtual bool IsAlive() const;
154
155 virtual size_t UpdateThreads() = 0;
156
157 virtual const ArchSpec &GetArchitecture() const = 0;
158
159 // Breakpoint functions
160 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
161 bool hardware) = 0;
162
163 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
164
165 // Hardware Breakpoint functions
166 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
167
168 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
169
171
172 // Watchpoint functions
174
175 virtual std::optional<std::pair<uint32_t, uint32_t>>
177
178 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
179 uint32_t watch_flags, bool hardware);
180
182
183 // Accessors
184 lldb::pid_t GetID() const { return m_pid; }
185
187
188 bool IsRunning() const {
190 }
191
192 bool IsStepping() const { return m_state == lldb::eStateStepping; }
193
194 bool CanResume() const { return m_state == lldb::eStateStopped; }
195
197 return GetArchitecture().GetByteOrder();
198 }
199
200 uint32_t GetAddressByteSize() const {
202 }
203
204 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
205 GetAuxvData() const = 0;
206
207 // Exit Status
208 virtual std::optional<WaitStatus> GetExitStatus();
209
210 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
211
212 // Access to threads
214
216
218
220
223 }
224
227 }
228
229 // Access to inferior stdio
230 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
231
232 // Stop id interface
233
234 uint32_t GetStopID() const;
235
236 // Callbacks for low-level process state changes
238 public:
239 virtual ~NativeDelegate() = default;
240
241 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
242
244 lldb::StateType state) = 0;
245
246 virtual void DidExec(NativeProcessProtocol *process) = 0;
247
248 virtual void
250 std::unique_ptr<NativeProcessProtocol> child_process) = 0;
251 };
252
253 virtual Status GetLoadedModuleFileSpec(const char *module_path,
254 FileSpec &file_spec) = 0;
255
256 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
257 lldb::addr_t &load_addr) = 0;
258
259 /// Extension flag constants, returned by Manager::GetSupportedExtensions()
260 /// and passed to SetEnabledExtension()
261 enum class Extension {
262 multiprocess = (1u << 0),
263 fork = (1u << 1),
264 vfork = (1u << 2),
265 pass_signals = (1u << 3),
266 auxv = (1u << 4),
267 libraries_svr4 = (1u << 5),
268 memory_tagging = (1u << 6),
269 savecore = (1u << 7),
270 siginfo_read = (1u << 8),
271
273 };
274
275 class Manager {
276 public:
277 Manager(MainLoop &mainloop) : m_mainloop(mainloop) {}
278 Manager(const Manager &) = delete;
279 Manager &operator=(const Manager &) = delete;
280
281 virtual ~Manager();
282
283 /// Launch a process for debugging.
284 ///
285 /// \param[in] launch_info
286 /// Information required to launch the process.
287 ///
288 /// \param[in] native_delegate
289 /// The delegate that will receive messages regarding the
290 /// inferior. Must outlive the NativeProcessProtocol
291 /// instance.
292 ///
293 /// \param[in] mainloop
294 /// The mainloop instance with which the process can register
295 /// callbacks. Must outlive the NativeProcessProtocol
296 /// instance.
297 ///
298 /// \return
299 /// A NativeProcessProtocol shared pointer if the operation succeeded or
300 /// an error object if it failed.
301 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
303 NativeDelegate &native_delegate) = 0;
304
305 /// Attach to an existing process.
306 ///
307 /// \param[in] pid
308 /// pid of the process locatable
309 ///
310 /// \param[in] native_delegate
311 /// The delegate that will receive messages regarding the
312 /// inferior. Must outlive the NativeProcessProtocol
313 /// instance.
314 ///
315 /// \param[in] mainloop
316 /// The mainloop instance with which the process can register
317 /// callbacks. Must outlive the NativeProcessProtocol
318 /// instance.
319 ///
320 /// \return
321 /// A NativeProcessProtocol shared pointer if the operation succeeded or
322 /// an error object if it failed.
323 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
324 Attach(lldb::pid_t pid, NativeDelegate &native_delegate) = 0;
325
326 /// Get the bitmask of extensions supported by this process plugin.
327 ///
328 /// \return
329 /// A NativeProcessProtocol::Extension bitmask.
330 virtual Extension GetSupportedExtensions() const { return {}; }
331
332 protected:
334 };
335
336 /// Notify tracers that the target process will resume
338
339 /// Notify tracers that the target process just stopped
341
342 /// Start tracing a process or its threads.
343 ///
344 /// \param[in] json_params
345 /// JSON object with the information of what and how to trace.
346 /// In the case of gdb-remote, this object should conform to the
347 /// jLLDBTraceStart packet.
348 ///
349 /// This object should have a string entry called "type", which is the
350 /// tracing technology name.
351 ///
352 /// \param[in] type
353 /// Tracing technology type, as described in the \a json_params.
354 ///
355 /// \return
356 /// \a llvm::Error::success if the operation was successful, or an
357 /// \a llvm::Error otherwise.
358 virtual llvm::Error TraceStart(llvm::StringRef json_params,
359 llvm::StringRef type) {
360 return llvm::createStringError(llvm::inconvertibleErrorCode(),
361 "Unsupported tracing type '%s'",
362 type.data());
363 }
364
365 /// \copydoc Process::TraceStop(const TraceStopRequest &)
366 virtual llvm::Error TraceStop(const TraceStopRequest &request) {
367 return llvm::createStringError(llvm::inconvertibleErrorCode(),
368 "Unsupported tracing type '%s'",
369 request.type.data());
370 }
371
372 /// \copydoc Process::TraceGetState(llvm::StringRef type)
373 virtual llvm::Expected<llvm::json::Value>
374 TraceGetState(llvm::StringRef type) {
375 return llvm::createStringError(llvm::inconvertibleErrorCode(),
376 "Unsupported tracing type '%s'",
377 type.data());
378 }
379
380 /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &)
381 virtual llvm::Expected<std::vector<uint8_t>>
383 return llvm::createStringError(
384 llvm::inconvertibleErrorCode(),
385 "Unsupported data kind '%s' for the '%s' tracing technology",
386 request.kind.c_str(), request.type.c_str());
387 }
388
389 /// \copydoc Process::TraceSupported()
390 virtual llvm::Expected<TraceSupportedResponse> TraceSupported() {
391 return llvm::make_error<UnimplementedError>();
392 }
393
394 /// Method called in order to propagate the bitmap of protocol
395 /// extensions supported by the client.
396 ///
397 /// \param[in] flags
398 /// The bitmap of enabled extensions.
399 virtual void SetEnabledExtensions(Extension flags) {
400 m_enabled_extensions = flags;
401 }
402
403 /// Write a core dump (without crashing the program).
404 ///
405 /// \param[in] path_hint
406 /// Suggested core dump path (optional, can be empty).
407 ///
408 /// \return
409 /// Path to the core dump if successfully written, an error
410 /// otherwise.
411 virtual llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) {
412 return llvm::createStringError(llvm::inconvertibleErrorCode(),
413 "Not implemented");
414 }
415
416protected:
418 uint32_t ref_count;
419 llvm::SmallVector<uint8_t, 4> saved_opcodes;
420 llvm::ArrayRef<uint8_t> breakpoint_opcodes;
421 };
422
423 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
425
426 std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
428 mutable std::recursive_mutex m_threads_mutex;
429
431 mutable std::recursive_mutex m_state_mutex;
432
433 std::optional<WaitStatus> m_exit_status;
434
439 uint32_t m_stop_id = 0;
440
441 // Set of signal numbers that LLDB directly injects back to inferior without
442 // stopping it.
443 llvm::DenseSet<int> m_signals_to_ignore;
444
445 // Extensions enabled per the last SetEnabledExtensions() call.
447
448 // lldb_private::Host calls should be used to launch a process for debugging,
449 // and then the process should be attached to. When attaching to a process
450 // lldb_private::Host calls should be used to locate the process to attach
451 // to, and then this function should be called.
452 NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
453 NativeDelegate &delegate);
454
455 void SetID(lldb::pid_t pid) { m_pid = pid; }
456
457 // interface for state handling
458 void SetState(lldb::StateType state, bool notify_delegates = true);
459
460 // Derived classes need not implement this. It can be used as a hook to
461 // clear internal caches that should be invalidated when stop ids change.
462 //
463 // Note this function is called with the state mutex obtained by the caller.
464 virtual void DoStopIDBumped(uint32_t newBumpId);
465
466 // interface for software breakpoints
467
468 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
470
471 virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
472 GetSoftwareBreakpointTrapOpcode(size_t size_hint);
473
474 /// Return the offset of the PC relative to the software breakpoint that was hit. If an
475 /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
476 /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
477 /// PC, this offset will be the size of the breakpoint opcode.
478 virtual size_t GetSoftwareBreakpointPCOffset();
479
480 // Adjust the thread's PC after hitting a software breakpoint. On
481 // architectures where the PC points after the breakpoint instruction, this
482 // resets it to point to the breakpoint itself.
484
485 /// Notify the delegate that an exec occurred.
486 ///
487 /// Provide a mechanism for a delegate to clear out any exec-
488 /// sensitive data.
489 virtual void NotifyDidExec();
490
492
493private:
495 llvm::Expected<SoftwareBreakpoint>
496 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
497};
498} // namespace lldb_private
499
500#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
An architecture specification class.
Definition: ArchSpec.h:31
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:691
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:738
A file utility class.
Definition: FileSpec.h:56
Manager & operator=(const Manager &)=delete
virtual llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Attach(lldb::pid_t pid, NativeDelegate &native_delegate)=0
Attach to an existing process.
virtual llvm::Expected< std::unique_ptr< NativeProcessProtocol > > Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate)=0
Launch a process for debugging.
virtual Extension GetSupportedExtensions() const
Get the bitmask of extensions supported by this process plugin.
virtual void ProcessStateChanged(NativeProcessProtocol *process, lldb::StateType state)=0
virtual void DidExec(NativeProcessProtocol *process)=0
virtual void NewSubprocess(NativeProcessProtocol *parent_process, std::unique_ptr< NativeProcessProtocol > child_process)=0
virtual void InitializeDelegate(NativeProcessProtocol *process)=0
virtual Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
virtual lldb::addr_t GetSharedLibraryInfoAddress()=0
virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len, std::vector< uint8_t > &tags)
llvm::Expected< SoftwareBreakpoint > EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
virtual llvm::Expected< TraceSupportedResponse > TraceSupported()
Get the processor tracing type supported for this process.
virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
std::vector< std::unique_ptr< NativeThreadProtocol > > thread_collection
virtual void NotifyTracersProcessWillResume()
Notify tracers that the target process will resume.
virtual void NotifyTracersProcessDidStop()
Notify tracers that the target process just stopped.
virtual std::optional< WaitStatus > GetExitStatus()
virtual void SetEnabledExtensions(Extension flags)
Method called in order to propagate the bitmap of protocol extensions supported by the client.
virtual Status RemoveWatchpoint(lldb::addr_t addr)
virtual Status Interrupt()
Tells a process to interrupt all operations as if by a Ctrl-C.
virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len, const std::vector< uint8_t > &tags)
virtual void DoStopIDBumped(uint32_t newBumpId)
virtual llvm::Expected< std::vector< SVR4LibraryInfo > > GetLoadedSVR4Libraries()
virtual size_t GetSoftwareBreakpointPCOffset()
Return the offset of the PC relative to the software breakpoint that was hit.
virtual llvm::Expected< std::vector< uint8_t > > TraceGetBinaryData(const TraceGetBinaryDataRequest &request)
Get binary data given a trace technology and a data identifier.
virtual const HardwareBreakpointMap & GetHardwareBreakpointMap() const
virtual llvm::Error TraceStop(const TraceStopRequest &request)
Stop tracing a live process or its threads.
virtual Status GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec)=0
Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint)
virtual Status IgnoreSignals(llvm::ArrayRef< int > signals)
NativeThreadProtocol * GetThreadByIDUnlocked(lldb::tid_t tid)
virtual llvm::Expected< llvm::json::Value > TraceGetState(llvm::StringRef type)
Get the current tracing state of the process and its threads.
virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware)=0
virtual const ArchSpec & GetArchitecture() const =0
virtual const NativeWatchpointList::WatchpointMap & GetWatchpointMap() const
virtual llvm::Error DeallocateMemory(lldb::addr_t addr)
void SetState(lldb::StateType state, bool notify_delegates=true)
llvm::Expected< llvm::StringRef > ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size, size_t &total_bytes_read)
Reads a null terminated string from memory.
NativeThreadProtocol * GetThreadByID(lldb::tid_t tid)
virtual Status GetFileLoadAddress(const llvm::StringRef &file_name, lldb::addr_t &load_addr)=0
void SynchronouslyNotifyProcessStateChanged(lldb::StateType state)
virtual llvm::Expected< std::string > SaveCore(llvm::StringRef path_hint)
Write a core dump (without crashing the program).
virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)=0
std::vector< std::unique_ptr< NativeThreadProtocol > > m_threads
std::optional< WaitStatus > m_exit_status
virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange)
virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware=false)
static NativeThreadProtocol & thread_list_adapter(I &iter)
virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)=0
LockingAdaptedIterable< thread_collection, NativeThreadProtocol &, thread_list_adapter, std::recursive_mutex > ThreadIterable
Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
virtual Status Resume(const ResumeActionList &resume_actions)=0
virtual ~NativeProcessProtocol()=default
virtual Status Signal(int signo)=0
Sends a process a UNIX signal signal.
Status RemoveSoftwareBreakpoint(lldb::addr_t addr)
void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread)
NativeThreadProtocol * GetThreadAtIndex(uint32_t idx)
virtual void NotifyDidExec()
Notify the delegate that an exec occurred.
virtual llvm::Expected< lldb::addr_t > AllocateMemory(size_t size, uint32_t permissions)
Extension
Extension flag constants, returned by Manager::GetSupportedExtensions() and passed to SetEnabledExten...
virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size)
virtual llvm::ErrorOr< std::unique_ptr< llvm::MemoryBuffer > > GetAuxvData() const =0
virtual std::optional< std::pair< uint32_t, uint32_t > > GetHardwareDebugSupportInfo() const
virtual llvm::Expected< llvm::ArrayRef< uint8_t > > GetSoftwareBreakpointTrapOpcode(size_t size_hint)
virtual llvm::Error TraceStart(llvm::StringRef json_params, llvm::StringRef type)
Start tracing a process or its threads.
virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr)
std::unordered_map< lldb::addr_t, SoftwareBreakpoint > m_software_breakpoints
std::map< lldb::addr_t, NativeWatchpoint > WatchpointMap
An error handling class.
Definition: Status.h:44
#define LLDB_INVALID_THREAD_ID
Definition: lldb-defines.h:90
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE()
std::map< lldb::addr_t, HardwareBreakpoint > HardwareBreakpointMap
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateRunning
Process or thread is running and can't be examined.
@ eStateStepping
Process or thread is in the process of stepping and can not be examined.
uint64_t pid_t
Definition: lldb-types.h:81
ByteOrder
Byte ordering definitions.
uint64_t addr_t
Definition: lldb-types.h:79
uint64_t tid_t
Definition: lldb-types.h:82
jLLDBTraceGetBinaryData gdb-remote packet
std::string kind
Identifier for the data.
std::string type
Tracing technology name, e.g. intel-pt, arm-coresight.
jLLDBTraceStop gdb-remote packet
std::string type
Tracing technology name, e.g. intel-pt, arm-coresight.