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:
|
public:
|
||||||
|
|
||||||
QueueItem (lldb::QueueSP queue_sp);
|
QueueItem (lldb::QueueSP queue_sp, lldb::addr_t item_ref);
|
||||||
|
|
||||||
~QueueItem ();
|
~QueueItem ();
|
||||||
|
|
||||||
|
@ -222,6 +222,7 @@ protected:
|
||||||
lldb::QueueItemKind m_kind;
|
lldb::QueueItemKind m_kind;
|
||||||
lldb_private::Address m_address;
|
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
|
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
|
// to get the QueueItem that enqueued this item
|
||||||
lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
|
lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
|
||||||
|
|
|
@ -48,6 +48,9 @@ public:
|
||||||
lldb::SBQueueItem
|
lldb::SBQueueItem
|
||||||
GetPendingItemAtIndex (uint32_t);
|
GetPendingItemAtIndex (uint32_t);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
GetNumRunningItems ();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace lldb
|
} // 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
|
void
|
||||||
SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
|
SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
|
||||||
{
|
{
|
||||||
if (BacktraceRecordingHeadersInitialized())
|
if (BacktraceRecordingHeadersInitialized())
|
||||||
{
|
{
|
||||||
std::vector<addr_t> pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
|
PendingItemsForQueue pending_item_refs = GetPendingItemRefsForQueue (queue->GetLibdispatchQueueAddress());
|
||||||
for (addr_t pending_item : pending_item_refs)
|
for (ItemRefAndCodeAddress pending_item : pending_item_refs.item_refs_and_code_addresses)
|
||||||
{
|
{
|
||||||
AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
|
AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
|
||||||
ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
|
ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
|
||||||
Error error;
|
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 = LLDB_INVALID_ADDRESS;
|
||||||
m_page_to_free_size = 0;
|
m_page_to_free_size = 0;
|
||||||
if (ret.item_buffer_ptr != 0 && ret.item_buffer_ptr != LLDB_INVALID_ADDRESS && ret.item_buffer_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());
|
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
|
||||||
ItemInfo item = ExtractItemInfoFromBuffer (extractor);
|
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);
|
queue_item_sp->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
|
||||||
|
|
||||||
Address addr;
|
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
|
void
|
||||||
SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size,
|
SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size,
|
||||||
uint64_t count, lldb_private::QueueList &queue_list)
|
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
|
bool
|
||||||
BacktraceRecordingHeadersInitialized ();
|
BacktraceRecordingHeadersInitialized ();
|
||||||
|
|
||||||
|
@ -197,7 +214,7 @@ private:
|
||||||
void
|
void
|
||||||
ReadLibdispatchOffsets ();
|
ReadLibdispatchOffsets ();
|
||||||
|
|
||||||
std::vector<lldb::addr_t>
|
PendingItemsForQueue
|
||||||
GetPendingItemRefsForQueue (lldb::addr_t queue);
|
GetPendingItemRefsForQueue (lldb::addr_t queue);
|
||||||
|
|
||||||
ItemInfo
|
ItemInfo
|
||||||
|
|
|
@ -15,10 +15,11 @@
|
||||||
using namespace lldb;
|
using namespace lldb;
|
||||||
using namespace lldb_private;
|
using namespace lldb_private;
|
||||||
|
|
||||||
QueueItem::QueueItem (QueueSP queue_sp) :
|
QueueItem::QueueItem (QueueSP queue_sp, lldb::addr_t item_ref) :
|
||||||
m_queue_wp (),
|
m_queue_wp (),
|
||||||
m_kind (eQueueItemKindUnknown),
|
m_kind (eQueueItemKindUnknown),
|
||||||
m_address (),
|
m_address (),
|
||||||
|
m_item_ref (item_ref),
|
||||||
m_item_that_enqueued_this_ref (LLDB_INVALID_ADDRESS),
|
m_item_that_enqueued_this_ref (LLDB_INVALID_ADDRESS),
|
||||||
m_enqueueing_thread_id (LLDB_INVALID_THREAD_ID),
|
m_enqueueing_thread_id (LLDB_INVALID_THREAD_ID),
|
||||||
m_enqueueing_queue_id (LLDB_INVALID_QUEUE_ID),
|
m_enqueueing_queue_id (LLDB_INVALID_QUEUE_ID),
|
||||||
|
|
Loading…
Reference in New Issue