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