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