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/Host/Host.h"
14 #include "lldb/Host/MainLoop.h"
15 #include "lldb/Utility/Status.h"
16 #include "lldb/Utility/TraceOptions.h"
17 #include "lldb/lldb-private-forward.h"
18 #include "lldb/lldb-types.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/MemoryBuffer.h"
26 #include "NativeBreakpointList.h"
27 #include "NativeWatchpointList.h"
29 namespace lldb_private {
30 class MemoryRegionInfo;
31 class ResumeActionList;
33 //------------------------------------------------------------------
34 // NativeProcessProtocol
35 //------------------------------------------------------------------
36 class NativeProcessProtocol {
37 friend class SoftwareBreakpoint;
40 virtual ~NativeProcessProtocol() {}
42 virtual Status Resume(const ResumeActionList &resume_actions) = 0;
44 virtual Status Halt() = 0;
46 virtual Status Detach() = 0;
48 //------------------------------------------------------------------
49 /// Sends a process a UNIX signal \a signal.
52 /// Returns an error object.
53 //------------------------------------------------------------------
54 virtual Status Signal(int signo) = 0;
56 //------------------------------------------------------------------
57 /// Tells a process to interrupt all operations as if by a Ctrl-C.
59 /// The default implementation will send a local host's equivalent of
60 /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
64 /// Returns an error object.
65 //------------------------------------------------------------------
66 virtual Status Interrupt();
68 virtual Status Kill() = 0;
70 //------------------------------------------------------------------
71 // Tells a process not to stop the inferior on given signals
72 // and just reinject them back.
73 //------------------------------------------------------------------
74 virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
76 //----------------------------------------------------------------------
77 // Memory and memory region functions
78 //----------------------------------------------------------------------
80 virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
81 MemoryRegionInfo &range_info);
83 virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
84 size_t &bytes_read) = 0;
86 virtual Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf,
87 size_t size, size_t &bytes_read) = 0;
89 virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
90 size_t &bytes_written) = 0;
92 virtual Status AllocateMemory(size_t size, uint32_t permissions,
93 lldb::addr_t &addr) = 0;
95 virtual Status DeallocateMemory(lldb::addr_t addr) = 0;
97 virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
99 virtual bool IsAlive() const;
101 virtual size_t UpdateThreads() = 0;
103 virtual bool GetArchitecture(ArchSpec &arch) const = 0;
105 //----------------------------------------------------------------------
106 // Breakpoint functions
107 //----------------------------------------------------------------------
108 virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
111 virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
113 virtual Status EnableBreakpoint(lldb::addr_t addr);
115 virtual Status DisableBreakpoint(lldb::addr_t addr);
117 //----------------------------------------------------------------------
118 // Hardware Breakpoint functions
119 //----------------------------------------------------------------------
120 virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
122 virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
124 virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
126 //----------------------------------------------------------------------
127 // Watchpoint functions
128 //----------------------------------------------------------------------
129 virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
131 virtual llvm::Optional<std::pair<uint32_t, uint32_t>>
132 GetHardwareDebugSupportInfo() const;
134 virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
135 uint32_t watch_flags, bool hardware);
137 virtual Status RemoveWatchpoint(lldb::addr_t addr);
139 //----------------------------------------------------------------------
141 //----------------------------------------------------------------------
142 lldb::pid_t GetID() const { return m_pid; }
144 lldb::StateType GetState() const;
146 bool IsRunning() const {
147 return m_state == lldb::eStateRunning || IsStepping();
150 bool IsStepping() const { return m_state == lldb::eStateStepping; }
152 bool CanResume() const { return m_state == lldb::eStateStopped; }
154 bool GetByteOrder(lldb::ByteOrder &byte_order) const;
156 virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
157 GetAuxvData() const = 0;
159 //----------------------------------------------------------------------
161 //----------------------------------------------------------------------
162 virtual llvm::Optional<WaitStatus> GetExitStatus();
164 virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
166 //----------------------------------------------------------------------
168 //----------------------------------------------------------------------
169 NativeThreadProtocolSP GetThreadAtIndex(uint32_t idx);
171 NativeThreadProtocolSP GetThreadByID(lldb::tid_t tid);
173 void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
175 lldb::tid_t GetCurrentThreadID() { return m_current_thread_id; }
177 NativeThreadProtocolSP GetCurrentThread() {
178 return GetThreadByID(m_current_thread_id);
181 //----------------------------------------------------------------------
182 // Access to inferior stdio
183 //----------------------------------------------------------------------
184 virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
186 //----------------------------------------------------------------------
188 //----------------------------------------------------------------------
190 uint32_t GetStopID() const;
192 // ---------------------------------------------------------------------
193 // Callbacks for low-level process state changes
194 // ---------------------------------------------------------------------
195 class NativeDelegate {
197 virtual ~NativeDelegate() {}
199 virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
201 virtual void ProcessStateChanged(NativeProcessProtocol *process,
202 lldb::StateType state) = 0;
204 virtual void DidExec(NativeProcessProtocol *process) = 0;
207 //------------------------------------------------------------------
208 /// Register a native delegate.
210 /// Clients can register nofication callbacks by passing in a
211 /// NativeDelegate impl and passing it into this function.
213 /// Note: it is required that the lifetime of the
214 /// native_delegate outlive the NativeProcessProtocol.
216 /// @param[in] native_delegate
217 /// A NativeDelegate impl to be called when certain events
218 /// happen within the NativeProcessProtocol or related threads.
221 /// true if the delegate was registered successfully;
222 /// false if the delegate was already registered.
224 /// @see NativeProcessProtocol::NativeDelegate.
225 //------------------------------------------------------------------
226 bool RegisterNativeDelegate(NativeDelegate &native_delegate);
228 //------------------------------------------------------------------
229 /// Unregister a native delegate previously registered.
231 /// @param[in] native_delegate
232 /// A NativeDelegate impl previously registered with this process.
234 /// @return Returns \b true if the NativeDelegate was
235 /// successfully removed from the process, \b false otherwise.
237 /// @see NativeProcessProtocol::NativeDelegate
238 //------------------------------------------------------------------
239 bool UnregisterNativeDelegate(NativeDelegate &native_delegate);
241 virtual Status GetLoadedModuleFileSpec(const char *module_path,
242 FileSpec &file_spec) = 0;
244 virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
245 lldb::addr_t &load_addr) = 0;
250 //------------------------------------------------------------------
251 /// Launch a process for debugging.
253 /// @param[in] launch_info
254 /// Information required to launch the process.
256 /// @param[in] native_delegate
257 /// The delegate that will receive messages regarding the
258 /// inferior. Must outlive the NativeProcessProtocol
261 /// @param[in] mainloop
262 /// The mainloop instance with which the process can register
263 /// callbacks. Must outlive the NativeProcessProtocol
267 /// A NativeProcessProtocol shared pointer if the operation succeeded or
268 /// an error object if it failed.
269 //------------------------------------------------------------------
270 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
271 Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
272 MainLoop &mainloop) const = 0;
274 //------------------------------------------------------------------
275 /// Attach to an existing process.
278 /// pid of the process locatable
280 /// @param[in] native_delegate
281 /// The delegate that will receive messages regarding the
282 /// inferior. Must outlive the NativeProcessProtocol
285 /// @param[in] mainloop
286 /// The mainloop instance with which the process can register
287 /// callbacks. Must outlive the NativeProcessProtocol
291 /// A NativeProcessProtocol shared pointer if the operation succeeded or
292 /// an error object if it failed.
293 //------------------------------------------------------------------
294 virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
295 Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
296 MainLoop &mainloop) const = 0;
299 //------------------------------------------------------------------
300 /// StartTracing API for starting a tracing instance with the
301 /// TraceOptions on a specific thread or process.
303 /// @param[in] config
304 /// The configuration to use when starting tracing.
306 /// @param[out] error
307 /// Status indicates what went wrong.
310 /// The API returns a user_id which can be used to get trace
311 /// data, trace configuration or stopping the trace instance.
312 /// The user_id is a key to identify and operate with a tracing
313 /// instance. It may refer to the complete process or a single
315 //------------------------------------------------------------------
316 virtual lldb::user_id_t StartTrace(const TraceOptions &config,
318 error.SetErrorString("Not implemented");
319 return LLDB_INVALID_UID;
322 //------------------------------------------------------------------
323 /// StopTracing API as the name suggests stops a tracing instance.
325 /// @param[in] traceid
326 /// The user id of the trace intended to be stopped. Now a
327 /// user_id may map to multiple threads in which case this API
328 /// could be used to stop the tracing for a specific thread by
329 /// supplying its thread id.
331 /// @param[in] thread
332 /// Thread is needed when the complete process is being traced
333 /// and the user wishes to stop tracing on a particular thread.
336 /// Status indicating what went wrong.
337 //------------------------------------------------------------------
338 virtual Status StopTrace(lldb::user_id_t traceid,
339 lldb::tid_t thread = LLDB_INVALID_THREAD_ID) {
340 return Status("Not implemented");
343 //------------------------------------------------------------------
344 /// This API provides the trace data collected in the form of raw
347 /// @param[in] traceid thread
348 /// The traceid and thread provide the context for the trace
351 /// @param[in] buffer
352 /// The buffer provides the destination buffer where the trace
353 /// data would be read to. The buffer should be truncated to the
354 /// filled length by this function.
356 /// @param[in] offset
357 /// There is possibility to read partially the trace data from
358 /// a specified offset where in such cases the buffer provided
359 /// may be smaller than the internal trace collection container.
362 /// The size of the data actually read.
363 //------------------------------------------------------------------
364 virtual Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
365 llvm::MutableArrayRef<uint8_t> &buffer,
367 return Status("Not implemented");
370 //------------------------------------------------------------------
371 /// Similar API as above except it aims to provide any extra data
372 /// useful for decoding the actual trace data.
373 //------------------------------------------------------------------
374 virtual Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
375 llvm::MutableArrayRef<uint8_t> &buffer,
377 return Status("Not implemented");
380 //------------------------------------------------------------------
381 /// API to query the TraceOptions for a given user id
383 /// @param[in] traceid
384 /// The user id of the tracing instance.
386 /// @param[in] config
387 /// The thread id of the tracing instance, in case configuration
388 /// for a specific thread is needed should be specified in the
391 /// @param[out] error
392 /// Status indicates what went wrong.
394 /// @param[out] config
395 /// The actual configuration being used for tracing.
396 //------------------------------------------------------------------
397 virtual Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) {
398 return Status("Not implemented");
404 std::vector<NativeThreadProtocolSP> m_threads;
405 lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
406 mutable std::recursive_mutex m_threads_mutex;
408 lldb::StateType m_state = lldb::eStateInvalid;
409 mutable std::recursive_mutex m_state_mutex;
411 llvm::Optional<WaitStatus> m_exit_status;
413 std::recursive_mutex m_delegates_mutex;
414 std::vector<NativeDelegate *> m_delegates;
415 NativeBreakpointList m_breakpoint_list;
416 NativeWatchpointList m_watchpoint_list;
417 HardwareBreakpointMap m_hw_breakpoints_map;
419 uint32_t m_stop_id = 0;
421 // Set of signal numbers that LLDB directly injects back to inferior
422 // without stopping it.
423 llvm::DenseSet<int> m_signals_to_ignore;
425 // lldb_private::Host calls should be used to launch a process for debugging,
427 // then the process should be attached to. When attaching to a process
428 // lldb_private::Host calls should be used to locate the process to attach to,
429 // and then this function should be called.
430 NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
431 NativeDelegate &delegate);
433 // -----------------------------------------------------------
434 // Internal interface for state handling
435 // -----------------------------------------------------------
436 void SetState(lldb::StateType state, bool notify_delegates = true);
438 // Derived classes need not implement this. It can be used as a
439 // hook to clear internal caches that should be invalidated when
442 // Note this function is called with the state mutex obtained
444 virtual void DoStopIDBumped(uint32_t newBumpId);
446 // -----------------------------------------------------------
447 // Internal interface for software breakpoints
448 // -----------------------------------------------------------
449 Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
452 GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
453 size_t &actual_opcode_size,
454 const uint8_t *&trap_opcode_bytes) = 0;
456 // -----------------------------------------------------------
457 /// Notify the delegate that an exec occurred.
459 /// Provide a mechanism for a delegate to clear out any exec-
461 // -----------------------------------------------------------
462 void NotifyDidExec();
464 NativeThreadProtocolSP GetThreadByIDUnlocked(lldb::tid_t tid);
466 // -----------------------------------------------------------
467 // Static helper methods for derived classes.
468 // -----------------------------------------------------------
469 static Status ResolveProcessArchitecture(lldb::pid_t pid, ArchSpec &arch);
472 void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
474 } // namespace lldb_private
476 #endif // #ifndef liblldb_NativeProcessProtocol_h_