forked from OSchip/llvm-project
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
This commit is contained in:
parent
fe95dc95b5
commit
37e9b5ab38
|
@ -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
|
||||
|
|
|
@ -48,6 +48,9 @@ public:
|
|||
lldb::SBQueueItem
|
||||
GetPendingItemAtIndex (uint32_t);
|
||||
|
||||
uint32_t
|
||||
GetNumRunningItems ();
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Reference in New Issue