1 //===-- SystemRuntime.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 liblldb_SystemRuntime_h_
10 #define liblldb_SystemRuntime_h_
11 
12 #include <vector>
13 
14 #include "lldb/Core/ModuleList.h"
15 #include "lldb/Core/PluginInterface.h"
16 #include "lldb/Target/QueueItem.h"
17 #include "lldb/Target/QueueList.h"
18 #include "lldb/Utility/ConstString.h"
19 #include "lldb/Utility/StructuredData.h"
20 #include "lldb/lldb-private.h"
21 #include "lldb/lldb-public.h"
22 
23 namespace lldb_private {
24 
25 /// \class SystemRuntime SystemRuntime.h "lldb/Target/SystemRuntime.h"
26 /// A plug-in interface definition class for system runtimes.
27 ///
28 /// The system runtime plugins can collect information from the system
29 /// libraries during a Process' lifetime and provide information about how
30 /// objects/threads were originated.
31 ///
32 /// For instance, a system runtime plugin use a breakpoint when threads are
33 /// created to record the backtrace of where that thread was created. Later,
34 /// when backtracing the created thread, it could extend the backtrace to show
35 /// where it was originally created from.
36 ///
37 /// The plugin will insert its own breakpoint when Created and start
38 /// collecting information.  Later when it comes time to augment a Thread, it
39 /// can be asked to provide that information.
40 ///
41 
42 class SystemRuntime : public PluginInterface {
43 public:
44   /// Find a system runtime plugin for a given process.
45   ///
46   /// Scans the installed SystemRuntime plugins and tries to find an instance
47   /// that can be used to track image changes in \a process.
48   ///
49   /// \param[in] process
50   ///     The process for which to try and locate a system runtime
51   ///     plugin instance.
52   static SystemRuntime *FindPlugin(Process *process);
53 
54   /// Construct with a process.
55   SystemRuntime(lldb_private::Process *process);
56 
57   /// Destructor.
58   ///
59   /// The destructor is virtual since this class is designed to be inherited
60   /// by the plug-in instance.
61   ~SystemRuntime() override;
62 
63   /// Called after attaching to a process.
64   ///
65   /// Allow the SystemRuntime plugin to execute some code after attaching to a
66   /// process.
67   virtual void DidAttach();
68 
69   /// Called after launching a process.
70   ///
71   /// Allow the SystemRuntime plugin to execute some code after launching a
72   /// process.
73   virtual void DidLaunch();
74 
75   /// Called when modules have been loaded in the process.
76   ///
77   /// Allow the SystemRuntime plugin to enable logging features in the system
78   /// runtime libraries.
79   virtual void ModulesDidLoad(lldb_private::ModuleList &module_list);
80 
81   /// Called before detaching from a process.
82   ///
83   /// This will give a SystemRuntime plugin a chance to free any resources in
84   /// the inferior process before we detach.
85   virtual void Detach();
86 
87   /// Return a list of thread origin extended backtraces that may be
88   /// available.
89   ///
90   /// A System Runtime may be able to provide a backtrace of when this
91   /// thread was originally created.  Furthermore, it may be able to provide
92   /// that extended backtrace for different styles of creation. On a system
93   /// with both pthreads and libdispatch, aka Grand Central Dispatch, queues,
94   /// the system runtime may be able to provide the pthread creation of the
95   /// thread and it may also be able to provide the backtrace of when this GCD
96   /// queue work block was enqueued. The caller may request these different
97   /// origins by name.
98   ///
99   /// The names will be provided in the order that they are most likely to be
100   /// requested.  For instance, a most natural order may be to request the GCD
101   /// libdispatch queue origin.  If there is none, then request the pthread
102   /// origin.
103   ///
104   /// \return
105   ///   A vector of ConstStrings with names like "pthread" or "libdispatch".
106   ///   An empty vector may be returned if no thread origin extended
107   ///   backtrace capabilities are available.
108   virtual const std::vector<ConstString> &GetExtendedBacktraceTypes();
109 
110   /// Return a Thread which shows the origin of this thread's creation.
111   ///
112   /// This likely returns a HistoryThread which shows how thread was
113   /// originally created (e.g. "pthread" type), or how the work that is
114   /// currently executing on it was originally enqueued (e.g. "libdispatch"
115   /// type).
116   ///
117   /// There may be a chain of thread-origins; it may be informative to the end
118   /// user to query the returned ThreadSP for its origins as well.
119   ///
120   /// \param [in] thread
121   ///   The thread to examine.
122   ///
123   /// \param [in] type
124   ///   The type of thread origin being requested.  The types supported
125   ///   are returned from SystemRuntime::GetExtendedBacktraceTypes.
126   ///
127   /// \return
128   ///   A ThreadSP which will have a StackList of frames.  This Thread will
129   ///   not appear in the Process' list of current threads.  Normal thread
130   ///   operations like stepping will not be available.  This is a historical
131   ///   view thread and may be only useful for showing a backtrace.
132   ///
133   ///   An empty ThreadSP will be returned if no thread origin is available.
134   virtual lldb::ThreadSP GetExtendedBacktraceThread(lldb::ThreadSP thread,
135                                                     ConstString type);
136 
137   /// Get the extended backtrace thread for a QueueItem
138   ///
139   /// A QueueItem represents a function/block that will be executed on
140   /// a libdispatch queue in the future, or it represents a function/block
141   /// that is currently executing on a thread.
142   ///
143   /// This method will report a thread backtrace of the function that enqueued
144   /// it originally, if possible.
145   ///
146   /// \param [in] queue_item_sp
147   ///     The QueueItem that we are getting an extended backtrace for.
148   ///
149   /// \param [in] type
150   ///     The type of extended backtrace to fetch.  The types supported
151   ///     are returned from SystemRuntime::GetExtendedBacktraceTypes.
152   ///
153   /// \return
154   ///     If an extended backtrace is available, it is returned.  Else
155   ///     an empty ThreadSP is returned.
156   virtual lldb::ThreadSP
157   GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,
158                                    ConstString type) {
159     return lldb::ThreadSP();
160   }
161 
162   /// Populate the Process' QueueList with libdispatch / GCD queues that
163   /// exist.
164   ///
165   /// When process execution is paused, the SystemRuntime may be called to
166   /// fill in the list of Queues that currently exist.
167   ///
168   /// \param [out] queue_list
169   ///     This QueueList will be cleared, and any queues that currently exist
170   ///     will be added.  An empty QueueList will be returned if no queues
171   ///     exist or if this Systemruntime does not support libdispatch queues.
172   virtual void PopulateQueueList(lldb_private::QueueList &queue_list) {}
173 
174   /// Get the queue name for a thread given a thread's dispatch_qaddr.
175   ///
176   /// On systems using libdispatch queues, a thread may be associated with a
177   /// queue. There will be a call to get the thread's dispatch_qaddr.  At the
178   /// dispatch_qaddr we will find the address of this thread's
179   /// dispatch_queue_t structure. Given the address of the dispatch_queue_t
180   /// structure for a thread, get the queue name and return it.
181   ///
182   /// \param [in] dispatch_qaddr
183   ///     The address of the dispatch_qaddr pointer for this thread.
184   ///
185   /// \return
186   ///     The string of this queue's name.  An empty string is returned if the
187   ///     name could not be found.
188   virtual std::string
189   GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
190     return "";
191   }
192 
193   /// Get the QueueID for the libdispatch queue given the thread's
194   /// dispatch_qaddr.
195   ///
196   /// On systems using libdispatch queues, a thread may be associated with a
197   /// queue. There will be a call to get the thread's dispatch_qaddr.  At the
198   /// dispatch_qaddr we will find the address of this thread's
199   /// dispatch_queue_t structure. Given the address of the dispatch_queue_t
200   /// structure for a thread, get the queue ID and return it.
201   ///
202   /// \param [in] dispatch_qaddr
203   ///     The address of the dispatch_qaddr pointer for this thread.
204   ///
205   /// \return
206   ///     The queue ID, or if it could not be retrieved, LLDB_INVALID_QUEUE_ID.
207   virtual lldb::queue_id_t
208   GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
209     return LLDB_INVALID_QUEUE_ID;
210   }
211 
212   /// Get the libdispatch_queue_t address for the queue given the thread's
213   /// dispatch_qaddr.
214   ///
215   /// On systems using libdispatch queues, a thread may be associated with a
216   /// queue. There will be a call to get the thread's dispatch_qaddr. Given
217   /// the thread's dispatch_qaddr, find the libdispatch_queue_t address and
218   /// return it.
219   ///
220   /// \param [in] dispatch_qaddr
221   ///     The address of the dispatch_qaddr pointer for this thread.
222   ///
223   /// \return
224   ///     The libdispatch_queue_t address, or LLDB_INVALID_ADDRESS if
225   ///     unavailable/not found.
226   virtual lldb::addr_t
227   GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) {
228     return LLDB_INVALID_ADDRESS;
229   }
230 
231   /// Retrieve the Queue kind for the queue at a thread's dispatch_qaddr.
232   ///
233   /// Retrieve the Queue kind - either eQueueKindSerial or
234   /// eQueueKindConcurrent, indicating that this queue processes work items
235   /// serially or concurrently.
236   ///
237   /// \return
238   ///     The Queue kind, if it could be read, else eQueueKindUnknown.
239   virtual lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_qaddr) {
240     return lldb::eQueueKindUnknown;
241   }
242 
243   /// Get the pending work items for a libdispatch Queue
244   ///
245   /// If this system/process is using libdispatch and the runtime can do so,
246   /// retrieve the list of pending work items for the specified Queue and add
247   /// it to the Queue.
248   ///
249   /// \param [in] queue
250   ///     The queue of interest.
251   virtual void PopulatePendingItemsForQueue(lldb_private::Queue *queue) {}
252 
253   /// Complete the fields in a QueueItem
254   ///
255   /// PopulatePendingItemsForQueue() may not fill in all of the QueueItem
256   /// details; when the remaining fields are needed, they will be fetched by
257   /// call this method.
258   ///
259   /// \param [in] queue_item
260   ///   The QueueItem that we will be completing.
261   ///
262   /// \param [in] item_ref
263   ///     The item_ref token that is needed to retrieve the rest of the
264   ///     information about the QueueItem.
265   virtual void CompleteQueueItem(lldb_private::QueueItem *queue_item,
266                                  lldb::addr_t item_ref) {}
267 
268   /// Add key-value pairs to the StructuredData dictionary object with
269   /// information debugserver  may need when constructing the
270   /// jThreadExtendedInfo packet.
271   ///
272   /// \param [out] dict
273   ///     Dictionary to which key-value pairs should be added; they will
274   ///     be sent to the remote gdb server stub as arguments in the
275   ///     jThreadExtendedInfo request.
276   virtual void AddThreadExtendedInfoPacketHints(
277       lldb_private::StructuredData::ObjectSP dict) {}
278 
279   /// Determine whether it is safe to run an expression on a given thread
280   ///
281   /// If a system must not run functions on a thread in some particular state,
282   /// this method gives a way for it to flag that the expression should not be
283   /// run.
284   ///
285   /// \param [in] thread_sp
286   ///     The thread we want to run the expression on.
287   ///
288   /// \return
289   ///     True will be returned if there are no known problems with running an
290   ///     expression on this thread.  False means that the inferior function
291   ///     call should not be made on this thread.
292   virtual bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) {
293     return true;
294   }
295 
296 protected:
297   // Member variables.
298   Process *m_process;
299 
300   std::vector<ConstString> m_types;
301 
302 private:
303   DISALLOW_COPY_AND_ASSIGN(SystemRuntime);
304 };
305 
306 } // namespace lldb_private
307 
308 #endif // liblldb_SystemRuntime_h_
309