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 GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp,ConstString type)158 GetExtendedBacktraceForQueueItem(lldb::QueueItemSP queue_item_sp, 159 ConstString type) { 160 return lldb::ThreadSP(); 161 } 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. PopulateQueueList(lldb_private::QueueList & queue_list)173 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 GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr)190 GetQueueNameFromThreadQAddress(lldb::addr_t dispatch_qaddr) { 191 return ""; 192 } 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 GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr)209 GetQueueIDFromThreadQAddress(lldb::addr_t dispatch_qaddr) { 210 return LLDB_INVALID_QUEUE_ID; 211 } 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 GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr)228 GetLibdispatchQueueAddressFromThreadQAddress(lldb::addr_t dispatch_qaddr) { 229 return LLDB_INVALID_ADDRESS; 230 } 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. GetQueueKind(lldb::addr_t dispatch_qaddr)240 virtual lldb::QueueKind GetQueueKind(lldb::addr_t dispatch_qaddr) { 241 return lldb::eQueueKindUnknown; 242 } 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. PopulatePendingItemsForQueue(lldb_private::Queue * queue)252 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. CompleteQueueItem(lldb_private::QueueItem * queue_item,lldb::addr_t item_ref)266 virtual void CompleteQueueItem(lldb_private::QueueItem *queue_item, 267 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. AddThreadExtendedInfoPacketHints(lldb_private::StructuredData::ObjectSP dict)277 virtual void AddThreadExtendedInfoPacketHints( 278 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. SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp)293 virtual bool SafeToCallFunctionsOnThisThread(lldb::ThreadSP thread_sp) { 294 return true; 295 } 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 308