diff options
author | Jason Molenda <jmolenda@apple.com> | 2014-03-09 21:17:08 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2014-03-09 21:17:08 +0000 |
commit | 37e9b5ab38208d27d30309a41bc1f0328ccb4afa (patch) | |
tree | c1462c856b8bf010b105e944145173b1c4e5dbb5 /lldb | |
parent | fe95dc95b5c16997f15d59d216734aecdce0bb44 (diff) | |
download | bcm5719-llvm-37e9b5ab38208d27d30309a41bc1f0328ccb4afa.tar.gz bcm5719-llvm-37e9b5ab38208d27d30309a41bc1f0328ccb4afa.zip |
libBacktraceRecording __introspection_dispatch_queue_get_pending_items is
changing the data it returns; this change accepts either the old format or
the new format. It doesn't yet benefit from the new format's additions -
but I need to get this checked in so we aren't rev-locked.
Also add a missing .i entry for SBQueue::GetNumRunningItems() missing from
the last checkin.
<rdar://problem/16272115>
llvm-svn: 203421
Diffstat (limited to 'lldb')
-rw-r--r-- | lldb/include/lldb/Target/QueueItem.h | 3 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBQueue.i | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp | 138 | ||||
-rw-r--r-- | lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h | 19 | ||||
-rw-r--r-- | lldb/source/Target/QueueItem.cpp | 3 |
5 files changed, 115 insertions, 51 deletions
diff --git a/lldb/include/lldb/Target/QueueItem.h b/lldb/include/lldb/Target/QueueItem.h index 1e4dbb786b8..bdb6d99578a 100644 --- a/lldb/include/lldb/Target/QueueItem.h +++ b/lldb/include/lldb/Target/QueueItem.h @@ -38,7 +38,7 @@ class QueueItem : { public: - QueueItem (lldb::QueueSP queue_sp); + QueueItem (lldb::QueueSP queue_sp, lldb::addr_t item_ref); ~QueueItem (); @@ -222,6 +222,7 @@ protected: lldb::QueueItemKind m_kind; lldb_private::Address m_address; + lldb::addr_t m_item_ref; // the token we can be used to fetch more information about this queue item lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into libBacktraceRecording // to get the QueueItem that enqueued this item lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item diff --git a/lldb/scripts/Python/interface/SBQueue.i b/lldb/scripts/Python/interface/SBQueue.i index f3a49b1192d..7f48166f6c2 100644 --- a/lldb/scripts/Python/interface/SBQueue.i +++ b/lldb/scripts/Python/interface/SBQueue.i @@ -48,6 +48,9 @@ public: lldb::SBQueueItem GetPendingItemAtIndex (uint32_t); + uint32_t + GetNumRunningItems (); + }; } // namespace lldb diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp index d4d60b3a05f..53b9c83cce1 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -526,18 +526,104 @@ SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list) } } +// Returns either an array of introspection_dispatch_item_info_ref's for the pending items on +// a queue or an array introspection_dispatch_item_info_ref's and code addresses for the +// pending items on a queue. The information about each of these pending items then needs to +// be fetched individually by passing the ref to libBacktraceRecording. + +SystemRuntimeMacOSX::PendingItemsForQueue +SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue) +{ + PendingItemsForQueue pending_item_refs; + AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer; + ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread()); + if (cur_thread_sp) + { + Error error; + pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error); + m_page_to_free = LLDB_INVALID_ADDRESS; + m_page_to_free_size = 0; + if (error.Success()) + { + if (pending_items_pointer.count > 0 + && pending_items_pointer.items_buffer_size > 0 + && pending_items_pointer.items_buffer_ptr != 0 + && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) + { + DataBufferHeap data (pending_items_pointer.items_buffer_size, 0); + if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error)) + { + DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize()); + + // We either have an array of + // void* item_ref + // (old style) or we have a structure returned which looks like + // + // struct introspection_dispatch_pending_item_info_s { + // void *item_ref; + // void *function_or_block; + // }; + // + // struct introspection_dispatch_pending_items_array_s { + // uint32_t version; + // uint32_t size_of_item_info; + // introspection_dispatch_pending_item_info_s items[]; + // } + + offset_t offset = 0; + int i = 0; + uint32_t version = extractor.GetU32(&offset); + if (version == 1) + { + pending_item_refs.new_style = true; + uint32_t item_size = extractor.GetU32(&offset); + uint32_t start_of_array_offset = offset; + while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count) + { + offset = start_of_array_offset + (i * item_size); + ItemRefAndCodeAddress item; + item.item_ref = extractor.GetPointer (&offset); + item.code_address = extractor.GetPointer (&offset); + pending_item_refs.item_refs_and_code_addresses.push_back (item); + i++; + } + } + else + { + offset = 0; + pending_item_refs.new_style = false; + while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count) + { + ItemRefAndCodeAddress item; + item.item_ref = extractor.GetPointer (&offset); + item.code_address = LLDB_INVALID_ADDRESS; + pending_item_refs.item_refs_and_code_addresses.push_back (item); + i++; + } + } + } + m_page_to_free = pending_items_pointer.items_buffer_ptr; + m_page_to_free_size = pending_items_pointer.items_buffer_size; + } + } + } + return pending_item_refs; +} + + + void SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue) { if (BacktraceRecordingHeadersInitialized()) { - std::vector<addr_t> pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress()); - for (addr_t pending_item : pending_item_refs) + PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress()); + for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses) { AppleGetItemInfoHandler::GetItemInfoReturnInfo ret; ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread()); Error error; - ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), pending_item, m_page_to_free, m_page_to_free_size, error); + ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), pending_item.item_ref, m_page_to_free, m_page_to_free_size, error); m_page_to_free = LLDB_INVALID_ADDRESS; m_page_to_free_size = 0; if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_size > 0) @@ -547,7 +633,7 @@ SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue) { DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize()); ItemInfo item = ExtractItemInfoFromBuffer (extractor); - QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this())); + QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), pending_item.item_ref)); queue_item_sp->SetItemThatEnqueuedThis (item.item_that_enqueued_this); Address addr; @@ -573,50 +659,6 @@ SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue) } } -// Returns an array of introspection_dispatch_item_info_ref's for the pending items on -// a queue. The information about each of these pending items then needs to be fetched -// individually by passing the ref to libBacktraceRecording. - -std::vector<lldb::addr_t> -SystemRuntimeMacOSX::GetPendingItemRefsForQueue (lldb::addr_t queue) -{ - std::vector<addr_t> pending_item_refs; - AppleGetPendingItemsHandler::GetPendingItemsReturnInfo pending_items_pointer; - ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread()); - if (cur_thread_sp) - { - Error error; - pending_items_pointer = m_get_pending_items_handler.GetPendingItems (*cur_thread_sp.get(), queue, m_page_to_free, m_page_to_free_size, error); - m_page_to_free = LLDB_INVALID_ADDRESS; - m_page_to_free_size = 0; - if (error.Success()) - { - if (pending_items_pointer.count > 0 - && pending_items_pointer.items_buffer_size > 0 - && pending_items_pointer.items_buffer_ptr != 0 - && pending_items_pointer.items_buffer_ptr != LLDB_INVALID_ADDRESS) - { - DataBufferHeap data (pending_items_pointer.items_buffer_size, 0); - if (m_process->ReadMemory (pending_items_pointer.items_buffer_ptr, data.GetBytes(), pending_items_pointer.items_buffer_size, error)) - { - offset_t offset = 0; - DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize()); - int i = 0; - while (offset < pending_items_pointer.items_buffer_size && i < pending_items_pointer.count) - { - pending_item_refs.push_back (extractor.GetPointer (&offset)); - i++; - } - } - m_page_to_free = pending_items_pointer.items_buffer_ptr; - m_page_to_free_size = pending_items_pointer.items_buffer_size; - } - } - } - return pending_item_refs; -} - - void SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size, uint64_t count, lldb_private::QueueList &queue_list) diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h index a308844d0e6..c20f19c3244 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h @@ -188,6 +188,23 @@ private: } }; + + // The libBacktraceRecording function __introspection_dispatch_queue_get_pending_items has + // two forms. It can either return a simple array of item_refs (void *) size or it can return + // a header with uint32_t version, a uint32_t size of item, and then an array of item_refs (void*) + // and code addresses (void*) for all the pending blocks. + + struct ItemRefAndCodeAddress { + lldb::addr_t item_ref; + lldb::addr_t code_address; + }; + + struct PendingItemsForQueue { + bool new_style; // new-style means both item_refs and code_addresses avail + // old-style means only item_refs is filled in + std::vector<ItemRefAndCodeAddress> item_refs_and_code_addresses; + }; + bool BacktraceRecordingHeadersInitialized (); @@ -197,7 +214,7 @@ private: void ReadLibdispatchOffsets (); - std::vector<lldb::addr_t> + PendingItemsForQueue GetPendingItemRefsForQueue (lldb::addr_t queue); ItemInfo diff --git a/lldb/source/Target/QueueItem.cpp b/lldb/source/Target/QueueItem.cpp index afb5cd028d5..40d824bcf46 100644 --- a/lldb/source/Target/QueueItem.cpp +++ b/lldb/source/Target/QueueItem.cpp @@ -15,10 +15,11 @@ using namespace lldb; using namespace lldb_private; -QueueItem::QueueItem (QueueSP queue_sp) : +QueueItem::QueueItem (QueueSP queue_sp, lldb::addr_t item_ref) : m_queue_wp (), m_kind (eQueueItemKindUnknown), m_address (), + m_item_ref (item_ref), m_item_that_enqueued_this_ref (LLDB_INVALID_ADDRESS), m_enqueueing_thread_id (LLDB_INVALID_THREAD_ID), m_enqueueing_queue_id (LLDB_INVALID_QUEUE_ID), |