1 //===-- QueueItem.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_QUEUEITEM_H 10 #define LLDB_TARGET_QUEUEITEM_H 11 12 #include <memory> 13 #include <string> 14 #include <vector> 15 16 #include "lldb/lldb-enumerations.h" 17 #include "lldb/lldb-forward.h" 18 #include "lldb/lldb-private.h" 19 20 #include "lldb/Core/Address.h" 21 #include "lldb/Utility/ConstString.h" 22 23 namespace lldb_private { 24 25 // QueueItem: 26 // This class represents a work item enqueued on a libdispatch aka Grand 27 // Central Dispatch (GCD) queue. Most often, this will be a function or block. 28 // "enqueued" here means that the work item has been added to a queue but it 29 // has not yet started executing. When it is "dequeued", execution of the item 30 // begins. 31 32 class QueueItem : public std::enable_shared_from_this<QueueItem> { 33 public: 34 QueueItem(lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, 35 lldb::addr_t item_ref, lldb_private::Address address); 36 37 ~QueueItem(); 38 39 /// Get the kind of work item this is 40 /// 41 /// \return 42 /// The type of work item that this QueueItem object 43 /// represents. eQueueItemKindUnknown may be returned. 44 lldb::QueueItemKind GetKind(); 45 46 /// Set the type of work item this is 47 /// 48 /// \param [in] item_kind 49 /// Set the kind of this work item object. 50 void SetKind(lldb::QueueItemKind item_kind); 51 52 /// Get the code address that will be executed when this work item 53 /// is executed. 54 /// 55 /// \return 56 /// The address that will be invoked when this work item is 57 /// executed. Not all types of QueueItems will have an 58 /// address associated with them; check that the returned 59 /// Address is valid, or check that the WorkItemKind is a 60 /// kind that involves an address, such as eQueueItemKindFunction 61 /// or eQueueItemKindBlock. 62 lldb_private::Address &GetAddress(); 63 64 /// Set the work item address for this object 65 /// 66 /// \param [in] addr 67 /// The address that will be invoked when this work item 68 /// is executed. 69 void SetAddress(lldb_private::Address addr); 70 71 /// Check if this QueueItem object is valid 72 /// 73 /// If the weak pointer to the parent Queue cannot be revivified, 74 /// it is invalid. 75 /// 76 /// \return 77 /// True if this object is valid. IsValid()78 bool IsValid() { return m_queue_wp.lock() != nullptr; } 79 80 /// Get an extended backtrace thread for this queue item, if available 81 /// 82 /// If the backtrace/thread information was collected when this item 83 /// was enqueued, this call will provide it. 84 /// 85 /// \param [in] type 86 /// The type of extended backtrace being requested, e.g. "libdispatch" 87 /// or "pthread". 88 /// 89 /// \return 90 /// A thread shared pointer which will have a reference to an extended 91 /// thread if one was available. 92 lldb::ThreadSP GetExtendedBacktraceThread(ConstString type); 93 SetItemThatEnqueuedThis(lldb::addr_t address_of_item)94 void SetItemThatEnqueuedThis(lldb::addr_t address_of_item) { 95 m_item_that_enqueued_this_ref = address_of_item; 96 } 97 98 lldb::addr_t GetItemThatEnqueuedThis(); 99 SetEnqueueingThreadID(lldb::tid_t tid)100 void SetEnqueueingThreadID(lldb::tid_t tid) { m_enqueueing_thread_id = tid; } 101 102 lldb::tid_t GetEnqueueingThreadID(); 103 SetEnqueueingQueueID(lldb::queue_id_t qid)104 void SetEnqueueingQueueID(lldb::queue_id_t qid) { 105 m_enqueueing_queue_id = qid; 106 } 107 108 lldb::queue_id_t GetEnqueueingQueueID(); 109 SetTargetQueueID(lldb::queue_id_t qid)110 void SetTargetQueueID(lldb::queue_id_t qid) { m_target_queue_id = qid; } 111 SetStopID(uint32_t stop_id)112 void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } 113 114 uint32_t GetStopID(); 115 SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace)116 void SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace) { 117 m_backtrace = backtrace; 118 } 119 120 std::vector<lldb::addr_t> &GetEnqueueingBacktrace(); 121 SetThreadLabel(std::string thread_name)122 void SetThreadLabel(std::string thread_name) { m_thread_label = thread_name; } 123 124 std::string GetThreadLabel(); 125 SetQueueLabel(std::string queue_name)126 void SetQueueLabel(std::string queue_name) { m_queue_label = queue_name; } 127 128 std::string GetQueueLabel(); 129 SetTargetQueueLabel(std::string queue_name)130 void SetTargetQueueLabel(std::string queue_name) { 131 m_target_queue_label = queue_name; 132 } 133 134 lldb::ProcessSP GetProcessSP(); 135 136 protected: 137 void FetchEntireItem(); 138 139 lldb::QueueWP m_queue_wp; 140 lldb::ProcessWP m_process_wp; 141 142 lldb::addr_t m_item_ref; // the token we can be used to fetch more information 143 // about this queue item 144 lldb_private::Address m_address; 145 bool m_have_fetched_entire_item; 146 147 lldb::QueueItemKind m_kind; 148 lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into 149 // libBacktraceRecording 150 // to get the QueueItem that enqueued this item 151 lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item 152 lldb::queue_id_t 153 m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue 154 lldb::queue_id_t m_target_queue_id; 155 uint32_t m_stop_id; // indicates when this backtrace was recorded in time 156 std::vector<lldb::addr_t> m_backtrace; 157 std::string m_thread_label; 158 std::string m_queue_label; 159 std::string m_target_queue_label; 160 161 private: 162 QueueItem(const QueueItem &) = delete; 163 const QueueItem &operator=(const QueueItem &) = delete; 164 }; 165 166 } // namespace lldb_private 167 168 #endif // LLDB_TARGET_QUEUEITEM_H 169