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
162 return m_software_breakpoints.find(addr) != m_software_breakpoints.end();
163 }
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
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
224
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
416 /// Get the list of structured data plugins supported by this process. They
417 /// must match the `type` field used by the corresponding
418 /// StructuredDataPlugins in the client.
419 ///
420 /// \return
421 /// A vector of structured data plugin names.
422 virtual std::vector<std::string> GetStructuredDataPlugins() { return {}; };
423
424protected:
426 llvm::SmallVector<uint8_t, 4> saved_opcodes;
427 llvm::ArrayRef<uint8_t> breakpoint_opcodes;
428 };
429
430 std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
432
433 std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
435 mutable std::recursive_mutex m_threads_mutex;
436
438 mutable std::recursive_mutex m_state_mutex;
439
440 std::optional<WaitStatus> m_exit_status;
441
446 uint32_t m_stop_id = 0;
447
448 // Set of signal numbers that LLDB directly injects back to inferior without
449 // stopping it.
450 llvm::DenseSet<int> m_signals_to_ignore;
451
452 // Extensions enabled per the last SetEnabledExtensions() call.
454
455 // lldb_private::Host calls should be used to launch a process for debugging,
456 // and then the process should be attached to. When attaching to a process
457 // lldb_private::Host calls should be used to locate the process to attach
458 // to, and then this function should be called.
459 NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
460 NativeDelegate &delegate);
461
462 void SetID(lldb::pid_t pid) { m_pid = pid; }
463
464 // interface for state handling
465 void SetState(lldb::StateType state, bool notify_delegates = true);
466
467 // Derived classes need not implement this. It can be used as a hook to
468 // clear internal caches that should be invalidated when stop ids change.
469 //
470 // Note this function is called with the state mutex obtained by the caller.
471 virtual void DoStopIDBumped(uint32_t newBumpId);
472
473 // interface for software breakpoints
474
475 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
477
478 virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
479 GetSoftwareBreakpointTrapOpcode(size_t size_hint);
480
481 /// Return the offset of the PC relative to the software breakpoint that was hit. If an
482 /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
483 /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
484 /// PC, this offset will be the size of the breakpoint opcode.
485 virtual size_t GetSoftwareBreakpointPCOffset();
486
487 // Adjust the thread's PC after hitting a software breakpoint. On
488 // architectures where the PC points after the breakpoint instruction, this
489 // resets it to point to the breakpoint itself.
491
492 /// Notify the delegate that an exec occurred.
493 ///
494 /// Provide a mechanism for a delegate to clear out any exec-
495 /// sensitive data.
496 virtual void NotifyDidExec();
497
499
500private:
502 llvm::Expected<SoftwareBreakpoint>
503 EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
504};
505} // namespace lldb_private
506
507#endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:690
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:739
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.