1 //===-- NativeProcessProtocol.h ---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef liblldb_NativeProcessProtocol_h_
11 #define liblldb_NativeProcessProtocol_h_
13 #include "lldb/Core/TraceOptions.h"
14 #include "lldb/Host/MainLoop.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/lldb-private-forward.h"
17 #include "lldb/lldb-types.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/DenseSet.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/MemoryBuffer.h"
24 #include "NativeBreakpointList.h"
25 #include "NativeWatchpointList.h"
27 namespace lldb_private {
28 class MemoryRegionInfo;
29 class ResumeActionList;
31 //------------------------------------------------------------------
32 // NativeProcessProtocol
33 //------------------------------------------------------------------
34 class NativeProcessProtocol
35 : public std::enable_shared_from_this<NativeProcessProtocol> {
36 friend class SoftwareBreakpoint;
39 virtual ~NativeProcessProtocol() {}
41 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
43 virtual Status Halt() = 0;
45 virtual Status Detach() = 0;
47 //------------------------------------------------------------------
48 /// Sends a process a UNIX signal \a signal.
51 /// Returns an error object.
52 //------------------------------------------------------------------
53 virtual Status Signal(int signo) = 0;
55 //------------------------------------------------------------------
56 /// Tells a process to interrupt all operations as if by a Ctrl-C.
58 /// The default implementation will send a local host's equivalent of
59 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
63 /// Returns an error object.
64 //------------------------------------------------------------------
65 virtual Status Interrupt();
67 virtual Status Kill() = 0;
69 //------------------------------------------------------------------
70 // Tells a process not to stop the inferior on given signals
71 // and just reinject them back.
72 //------------------------------------------------------------------
73 virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
75 //----------------------------------------------------------------------
76 // Memory and memory region functions
77 //----------------------------------------------------------------------
79 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
80 MemoryRegionInfo &range_info);
82 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
83 size_t &bytes_read) = 0;
85 virtual Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
86 size_t size, size_t &bytes_read) = 0;
88 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
89 size_t &bytes_written) = 0;
91 virtual Status AllocateMemory(size_t size, uint32_t permissions,
92 lldb::addr_t &addr) = 0;
94 virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
96 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
98 virtual bool IsAlive() const;
100 virtual size_t UpdateThreads() = 0;
102 virtual bool GetArchitecture(ArchSpec &arch) const = 0;
104 //----------------------------------------------------------------------
105 // Breakpoint functions
106 //----------------------------------------------------------------------
107 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
110 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
112 virtual Status EnableBreakpoint(lldb::addr_t addr);
114 virtual Status DisableBreakpoint(lldb::addr_t addr);
116 //----------------------------------------------------------------------
117 // Hardware Breakpoint functions
118 //----------------------------------------------------------------------
119 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
121 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
123 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
125 //----------------------------------------------------------------------
126 // Watchpoint functions
127 //----------------------------------------------------------------------
128 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
130 virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
131 GetHardwareDebugSupportInfo() const;
133 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
134 uint32_t watch_flags, bool hardware);
136 virtual Status RemoveWatchpoint(lldb::addr_t addr);
138 //----------------------------------------------------------------------
140 //----------------------------------------------------------------------
141 lldb::pid_t GetID() const { return m_pid; }
143 lldb::StateType GetState() const;
145 bool IsRunning() const {
146 return m_state == lldb::eStateRunning || IsStepping();
149 bool IsStepping() const { return m_state == lldb::eStateStepping; }
151 bool CanResume() const { return m_state == lldb::eStateStopped; }
153 bool GetByteOrder(lldb::ByteOrder &byte_order) const;
155 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
156 GetAuxvData() const = 0;
158 //----------------------------------------------------------------------
160 //----------------------------------------------------------------------
161 virtual bool GetExitStatus(lldb_private::ExitType *exit_type, int *status,
162 std::string &exit_description);
164 virtual bool SetExitStatus(lldb_private::ExitType exit_type, int status,
165 const char *exit_description,
166 bool bNotifyStateChange);
168 //----------------------------------------------------------------------
170 //----------------------------------------------------------------------
171 NativeThreadProtocolSP GetThreadAtIndex(uint32_t idx);
173 NativeThreadProtocolSP GetThreadByID(lldb::tid_t tid);
175 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
177 lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }
179 NativeThreadProtocolSP GetCurrentThread() {
180 return GetThreadByID(m_current_thread_id);
183 //----------------------------------------------------------------------
184 // Access to inferior stdio
185 //----------------------------------------------------------------------
186 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
188 //----------------------------------------------------------------------
190 //----------------------------------------------------------------------
192 uint32_t GetStopID() const;
194 // ---------------------------------------------------------------------
195 // Callbacks for low-level process state changes
196 // ---------------------------------------------------------------------
197 class NativeDelegate {
199 virtual ~NativeDelegate() {}
201 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
203 virtual void ProcessStateChanged(NativeProcessProtocol *process,
204 lldb::StateType state) = 0;
206 virtual void DidExec(NativeProcessProtocol *process) = 0;
209 //------------------------------------------------------------------
210 /// Register a native delegate.
212 /// Clients can register nofication callbacks by passing in a
213 /// NativeDelegate impl and passing it into this function.
215 /// Note: it is required that the lifetime of the
216 /// native_delegate outlive the NativeProcessProtocol.
218 /// @param[in] native_delegate
219 /// A NativeDelegate impl to be called when certain events
220 /// happen within the NativeProcessProtocol or related threads.
223 /// true if the delegate was registered successfully;
224 /// false if the delegate was already registered.
226 /// @see NativeProcessProtocol::NativeDelegate.
227 //------------------------------------------------------------------
228 bool RegisterNativeDelegate(NativeDelegate &native_delegate);
230 //------------------------------------------------------------------
231 /// Unregister a native delegate previously registered.
233 /// @param[in] native_delegate
234 /// A NativeDelegate impl previously registered with this process.
236 /// @return Returns \b true if the NativeDelegate was
237 /// successfully removed from the process, \b false otherwise.
239 /// @see NativeProcessProtocol::NativeDelegate
240 //------------------------------------------------------------------
241 bool UnregisterNativeDelegate(NativeDelegate &native_delegate);
243 virtual Status GetLoadedModuleFileSpec(const char *module_path,
244 FileSpec &file_spec) = 0;
246 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
247 lldb::addr_t &load_addr) = 0;
249 //------------------------------------------------------------------
250 /// Launch a process for debugging. This method will create an concrete
251 /// instance of NativeProcessProtocol, based on the host platform.
252 /// (e.g. NativeProcessLinux on linux, etc.)
254 /// @param[in] launch_info
255 /// Information required to launch the process.
257 /// @param[in] native_delegate
258 /// The delegate that will receive messages regarding the
259 /// inferior. Must outlive the NativeProcessProtocol
262 /// @param[in] mainloop
263 /// The mainloop instance with which the process can register
264 /// callbacks. Must outlive the NativeProcessProtocol
267 /// @param[out] process_sp
268 /// On successful return from the method, this parameter
269 /// contains the shared pointer to the
270 /// NativeProcessProtocol that can be used to manipulate
271 /// the native process.
274 /// An error object indicating if the operation succeeded,
275 /// and if not, what error occurred.
276 //------------------------------------------------------------------
277 static Status Launch(ProcessLaunchInfo &launch_info,
278 NativeDelegate &native_delegate, MainLoop &mainloop,
279 NativeProcessProtocolSP &process_sp);
281 //------------------------------------------------------------------
282 /// Attach to an existing process. This method will create an concrete
283 /// instance of NativeProcessProtocol, based on the host platform.
284 /// (e.g. NativeProcessLinux on linux, etc.)
287 /// pid of the process locatable
289 /// @param[in] native_delegate
290 /// The delegate that will receive messages regarding the
291 /// inferior. Must outlive the NativeProcessProtocol
294 /// @param[in] mainloop
295 /// The mainloop instance with which the process can register
296 /// callbacks. Must outlive the NativeProcessProtocol
299 /// @param[out] process_sp
300 /// On successful return from the method, this parameter
301 /// contains the shared pointer to the
302 /// NativeProcessProtocol that can be used to manipulate
303 /// the native process.
306 /// An error object indicating if the operation succeeded,
307 /// and if not, what error occurred.
308 //------------------------------------------------------------------
309 static Status Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
310 MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
312 //------------------------------------------------------------------
313 /// StartTracing API for starting a tracing instance with the
314 /// TraceOptions on a specific thread or process.
316 /// @param[in] config
317 /// The configuration to use when starting tracing.
319 /// @param[out] error
320 /// Status indicates what went wrong.
323 /// The API returns a user_id which can be used to get trace
324 /// data, trace configuration or stopping the trace instance.
325 /// The user_id is a key to identify and operate with a tracing
326 /// instance. It may refer to the complete process or a single
328 //------------------------------------------------------------------
329 virtual lldb::user_id_t StartTrace(const TraceOptions &config,
331 error.SetErrorString("Not implemented");
332 return LLDB_INVALID_UID;
335 //------------------------------------------------------------------
336 /// StopTracing API as the name suggests stops a tracing instance.
339 /// The user id of the trace intended to be stopped. Now a
340 /// user_id may map to multiple threads in which case this API
341 /// could be used to stop the tracing for a specific thread by
342 /// supplying its thread id.
344 /// @param[in] thread
345 /// Thread is needed when the complete process is being traced
346 /// and the user wishes to stop tracing on a particular thread.
349 /// Status indicating what went wrong.
350 //------------------------------------------------------------------
351 virtual Status StopTrace(lldb::user_id_t uid,
352 lldb::tid_t thread = LLDB_INVALID_THREAD_ID) {
353 return Status("Not implemented");
356 //------------------------------------------------------------------
357 /// This API provides the trace data collected in the form of raw
360 /// @param[in] uid thread
361 /// The uid and thread provide the context for the trace
364 /// @param[in] buffer
365 /// The buffer provides the destination buffer where the trace
366 /// data would be read to. The buffer should be truncated to the
367 /// filled length by this function.
369 /// @param[in] offset
370 /// There is possibility to read partially the trace data from
371 /// a specified offset where in such cases the buffer provided
372 /// may be smaller than the internal trace collection container.
375 /// The size of the data actually read.
376 //------------------------------------------------------------------
377 virtual Status GetData(lldb::user_id_t uid, lldb::tid_t thread,
378 llvm::MutableArrayRef<uint8_t> &buffer,
380 return Status("Not implemented");
383 //------------------------------------------------------------------
384 /// Similar API as above except it aims to provide any extra data
385 /// useful for decoding the actual trace data.
386 //------------------------------------------------------------------
387 virtual Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread,
388 llvm::MutableArrayRef<uint8_t> &buffer,
390 return Status("Not implemented");
393 //------------------------------------------------------------------
394 /// API to query the TraceOptions for a given user id
397 /// The user id of the tracing instance.
399 /// @param[in] config
400 /// The thread id of the tracing instance, in case configuration
401 /// for a specific thread is needed should be specified in the
404 /// @param[out] error
405 /// Status indicates what went wrong.
407 /// @param[out] config
408 /// The actual configuration being used for tracing.
409 //------------------------------------------------------------------
410 virtual Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &config) {
411 return Status("Not implemented");
417 std::vector<NativeThreadProtocolSP> m_threads;
418 lldb::tid_t m_current_thread_id;
419 mutable std::recursive_mutex m_threads_mutex;
421 lldb::StateType m_state;
422 mutable std::recursive_mutex m_state_mutex;
424 lldb_private::ExitType m_exit_type;
426 std::string m_exit_description;
427 std::recursive_mutex m_delegates_mutex;
428 std::vector<NativeDelegate *> m_delegates;
429 NativeBreakpointList m_breakpoint_list;
430 NativeWatchpointList m_watchpoint_list;
431 HardwareBreakpointMap m_hw_breakpoints_map;
435 // Set of signal numbers that LLDB directly injects back to inferior
436 // without stopping it.
437 llvm::DenseSet<int> m_signals_to_ignore;
439 // lldb_private::Host calls should be used to launch a process for debugging,
441 // then the process should be attached to. When attaching to a process
442 // lldb_private::Host calls should be used to locate the process to attach to,
443 // and then this function should be called.
444 NativeProcessProtocol(lldb::pid_t pid);
446 // -----------------------------------------------------------
447 // Internal interface for state handling
448 // -----------------------------------------------------------
449 void SetState(lldb::StateType state, bool notify_delegates = true);
451 // Derived classes need not implement this. It can be used as a
452 // hook to clear internal caches that should be invalidated when
455 // Note this function is called with the state mutex obtained
457 virtual void DoStopIDBumped(uint32_t newBumpId);
459 // -----------------------------------------------------------
460 // Internal interface for software breakpoints
461 // -----------------------------------------------------------
462 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
465 GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
466 size_t &actual_opcode_size,
467 const uint8_t *&trap_opcode_bytes) = 0;
469 // -----------------------------------------------------------
470 /// Notify the delegate that an exec occurred.
472 /// Provide a mechanism for a delegate to clear out any exec-
474 // -----------------------------------------------------------
475 void NotifyDidExec();
477 NativeThreadProtocolSP GetThreadByIDUnlocked(lldb::tid_t tid);
479 // -----------------------------------------------------------
480 // Static helper methods for derived classes.
481 // -----------------------------------------------------------
482 static Status ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch);
485 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
487 } // namespace lldb_private
489 #endif // #ifndef liblldb_NativeProcessProtocol_h_