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