forked from OSchip/llvm-project
Correctly add the QueueID to a pending block's extended thread backtrace thread.
Seed the QueueItem objects with the item_refs and addresses when they are fetched in one batch. If additional information is needed from the QueueItem, fetch it lazily one pending item per function call. <rdar://problem/16270007>, <rdar://problem/16032150> llvm-svn: 203449
This commit is contained in:
parent
6c25ca87a0
commit
e32cd191f0
|
@ -38,7 +38,7 @@ class QueueItem :
|
|||
{
|
||||
public:
|
||||
|
||||
QueueItem (lldb::QueueSP queue_sp, lldb::addr_t item_ref);
|
||||
QueueItem (lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, lldb::addr_t item_ref, lldb_private::Address address);
|
||||
|
||||
~QueueItem ();
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
|||
/// represents. eQueueItemKindUnknown may be returned.
|
||||
//------------------------------------------------------------------
|
||||
lldb::QueueItemKind
|
||||
GetKind () const;
|
||||
GetKind ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Set the type of work item this is
|
||||
|
@ -125,10 +125,7 @@ public:
|
|||
}
|
||||
|
||||
lldb::addr_t
|
||||
GetItemThatEnqueuedThis ()
|
||||
{
|
||||
return m_item_that_enqueued_this_ref;
|
||||
}
|
||||
GetItemThatEnqueuedThis ();
|
||||
|
||||
void
|
||||
SetEnqueueingThreadID (lldb::tid_t tid)
|
||||
|
@ -137,10 +134,7 @@ public:
|
|||
}
|
||||
|
||||
lldb::tid_t
|
||||
GetEnqueueingThreadID ()
|
||||
{
|
||||
return m_enqueueing_thread_id;
|
||||
}
|
||||
GetEnqueueingThreadID ();
|
||||
|
||||
void
|
||||
SetEnqueueingQueueID (lldb::queue_id_t qid)
|
||||
|
@ -149,10 +143,7 @@ public:
|
|||
}
|
||||
|
||||
lldb::queue_id_t
|
||||
GetEnqueueingQueueID ()
|
||||
{
|
||||
return m_enqueueing_queue_id;
|
||||
}
|
||||
GetEnqueueingQueueID ();
|
||||
|
||||
void
|
||||
SetTargetQueueID (lldb::queue_id_t qid)
|
||||
|
@ -167,10 +158,7 @@ public:
|
|||
}
|
||||
|
||||
uint32_t
|
||||
GetStopID ()
|
||||
{
|
||||
return m_stop_id;
|
||||
}
|
||||
GetStopID ();
|
||||
|
||||
void
|
||||
SetEnqueueingBacktrace (std::vector<lldb::addr_t> backtrace)
|
||||
|
@ -179,10 +167,7 @@ public:
|
|||
}
|
||||
|
||||
std::vector<lldb::addr_t> &
|
||||
GetEnqueueingBacktrace ()
|
||||
{
|
||||
return m_backtrace;
|
||||
}
|
||||
GetEnqueueingBacktrace ();
|
||||
|
||||
void
|
||||
SetThreadLabel (std::string thread_name)
|
||||
|
@ -191,10 +176,7 @@ public:
|
|||
}
|
||||
|
||||
std::string
|
||||
GetThreadLabel ()
|
||||
{
|
||||
return m_thread_label;
|
||||
}
|
||||
GetThreadLabel ();
|
||||
|
||||
void
|
||||
SetQueueLabel (std::string queue_name)
|
||||
|
@ -203,10 +185,7 @@ public:
|
|||
}
|
||||
|
||||
std::string
|
||||
GetQueueLabel ()
|
||||
{
|
||||
return m_queue_label;
|
||||
}
|
||||
GetQueueLabel ();
|
||||
|
||||
void
|
||||
SetTargetQueueLabel (std::string queue_name)
|
||||
|
@ -218,11 +197,18 @@ public:
|
|||
GetProcessSP ();
|
||||
|
||||
protected:
|
||||
void
|
||||
FetchEntireItem ();
|
||||
|
||||
|
||||
lldb::QueueWP m_queue_wp;
|
||||
lldb::QueueItemKind m_kind;
|
||||
lldb_private::Address m_address;
|
||||
lldb::ProcessWP m_process_wp;
|
||||
|
||||
lldb::addr_t m_item_ref; // the token we can be used to fetch more information about this queue item
|
||||
lldb_private::Address m_address;
|
||||
bool m_have_fetched_entire_item;
|
||||
|
||||
lldb::QueueItemKind m_kind;
|
||||
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
|
||||
|
|
|
@ -270,6 +270,25 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Complete the fields in a QueueItem
|
||||
///
|
||||
/// PopulatePendingItemsForQueue() may not fill in all of the QueueItem
|
||||
/// details; when the remaining fields are needed, they will be
|
||||
/// fetched by call this method.
|
||||
///
|
||||
/// @param [in] queue_item
|
||||
/// The QueueItem that we will be completing.
|
||||
///
|
||||
/// @param [in] item_ref
|
||||
/// The item_ref token that is needed to retrieve the rest of the
|
||||
/// information about the QueueItem.
|
||||
//------------------------------------------------------------------
|
||||
virtual void
|
||||
CompleteQueueItem (lldb_private::QueueItem *queue_item, lldb::addr_t item_ref)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Member variables.
|
||||
|
|
|
@ -620,45 +620,45 @@ SystemRuntimeMacOSX::PopulatePendingItemsForQueue (Queue *queue)
|
|||
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.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)
|
||||
{
|
||||
DataBufferHeap data (ret.item_buffer_size, 0);
|
||||
if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
|
||||
{
|
||||
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(), pending_item.item_ref));
|
||||
queue_item_sp->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
|
||||
|
||||
Address addr;
|
||||
if (!m_process->GetTarget().ResolveLoadAddress (item.function_or_block, addr, item.stop_id))
|
||||
{
|
||||
m_process->GetTarget().ResolveLoadAddress (item.function_or_block, addr);
|
||||
}
|
||||
queue_item_sp->SetAddress (addr);
|
||||
queue_item_sp->SetEnqueueingThreadID (item.enqueuing_thread_id);
|
||||
queue_item_sp->SetTargetQueueID (item.enqueuing_thread_id);
|
||||
queue_item_sp->SetStopID (item.stop_id);
|
||||
queue_item_sp->SetEnqueueingBacktrace (item.enqueuing_callstack);
|
||||
queue_item_sp->SetThreadLabel (item.enqueuing_thread_label);
|
||||
queue_item_sp->SetQueueLabel (item.enqueuing_queue_label);
|
||||
queue_item_sp->SetTargetQueueLabel (item.target_queue_label);
|
||||
|
||||
queue->PushPendingQueueItem (queue_item_sp);
|
||||
}
|
||||
m_page_to_free = ret.item_buffer_ptr;
|
||||
m_page_to_free_size = ret.item_buffer_size;
|
||||
}
|
||||
Address addr;
|
||||
m_process->GetTarget().ResolveLoadAddress (pending_item.code_address, addr);
|
||||
QueueItemSP queue_item_sp (new QueueItem (queue->shared_from_this(), m_process->shared_from_this(), pending_item.item_ref, addr));
|
||||
queue->PushPendingQueueItem (queue_item_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SystemRuntimeMacOSX::CompleteQueueItem (QueueItem *queue_item, addr_t item_ref)
|
||||
{
|
||||
AppleGetItemInfoHandler::GetItemInfoReturnInfo ret;
|
||||
|
||||
ThreadSP cur_thread_sp (m_process->GetThreadList().GetSelectedThread());
|
||||
Error error;
|
||||
ret = m_get_item_info_handler.GetItemInfo (*cur_thread_sp.get(), 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)
|
||||
{
|
||||
DataBufferHeap data (ret.item_buffer_size, 0);
|
||||
if (m_process->ReadMemory (ret.item_buffer_ptr, data.GetBytes(), ret.item_buffer_size, error) && error.Success())
|
||||
{
|
||||
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), m_process->GetByteOrder(), m_process->GetAddressByteSize());
|
||||
ItemInfo item = ExtractItemInfoFromBuffer (extractor);
|
||||
queue_item->SetItemThatEnqueuedThis (item.item_that_enqueued_this);
|
||||
queue_item->SetEnqueueingThreadID (item.enqueuing_thread_id);
|
||||
queue_item->SetEnqueueingQueueID (item.enqueuing_queue_serialnum);
|
||||
queue_item->SetStopID (item.stop_id);
|
||||
queue_item->SetEnqueueingBacktrace (item.enqueuing_callstack);
|
||||
queue_item->SetThreadLabel (item.enqueuing_thread_label);
|
||||
queue_item->SetQueueLabel (item.enqueuing_queue_label);
|
||||
queue_item->SetTargetQueueLabel (item.target_queue_label);
|
||||
}
|
||||
m_page_to_free = ret.item_buffer_ptr;
|
||||
m_page_to_free_size = ret.item_buffer_size;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SystemRuntimeMacOSX::PopulateQueuesUsingLibBTR (lldb::addr_t queues_buffer, uint64_t queues_buffer_size,
|
||||
uint64_t count, lldb_private::QueueList &queue_list)
|
||||
|
|
|
@ -100,6 +100,9 @@ public:
|
|||
void
|
||||
PopulatePendingItemsForQueue (lldb_private::Queue *queue);
|
||||
|
||||
void
|
||||
CompleteQueueItem (lldb_private::QueueItem *queue_item, lldb::addr_t item_ref);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// PluginInterface protocol
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
QueueItem::QueueItem (QueueSP queue_sp, lldb::addr_t item_ref) :
|
||||
QueueItem::QueueItem (QueueSP queue_sp, ProcessSP process_sp, lldb::addr_t item_ref, lldb_private::Address address) :
|
||||
m_queue_wp (),
|
||||
m_kind (eQueueItemKindUnknown),
|
||||
m_address (),
|
||||
m_process_wp (),
|
||||
m_item_ref (item_ref),
|
||||
m_address (address),
|
||||
m_have_fetched_entire_item (false),
|
||||
m_kind (eQueueItemKindUnknown),
|
||||
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),
|
||||
|
@ -31,6 +33,7 @@ QueueItem::QueueItem (QueueSP queue_sp, lldb::addr_t item_ref) :
|
|||
m_target_queue_label()
|
||||
{
|
||||
m_queue_wp = queue_sp;
|
||||
m_process_wp = process_sp;
|
||||
}
|
||||
|
||||
QueueItem::~QueueItem ()
|
||||
|
@ -38,8 +41,9 @@ QueueItem::~QueueItem ()
|
|||
}
|
||||
|
||||
QueueItemKind
|
||||
QueueItem::GetKind() const
|
||||
QueueItem::GetKind()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
|
@ -64,6 +68,7 @@ QueueItem::SetAddress (Address addr)
|
|||
ThreadSP
|
||||
QueueItem::GetExtendedBacktraceThread (ConstString type)
|
||||
{
|
||||
FetchEntireItem ();
|
||||
ThreadSP return_thread;
|
||||
QueueSP queue_sp = m_queue_wp.lock();
|
||||
if (queue_sp)
|
||||
|
@ -77,14 +82,75 @@ QueueItem::GetExtendedBacktraceThread (ConstString type)
|
|||
return return_thread;
|
||||
}
|
||||
|
||||
lldb::addr_t
|
||||
QueueItem::GetItemThatEnqueuedThis ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_item_that_enqueued_this_ref;
|
||||
}
|
||||
|
||||
lldb::tid_t
|
||||
QueueItem::GetEnqueueingThreadID ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_enqueueing_thread_id;
|
||||
}
|
||||
|
||||
lldb::queue_id_t
|
||||
QueueItem::GetEnqueueingQueueID ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_enqueueing_queue_id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
QueueItem::GetStopID ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_stop_id;
|
||||
}
|
||||
|
||||
std::vector<lldb::addr_t> &
|
||||
QueueItem::GetEnqueueingBacktrace ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_backtrace;
|
||||
}
|
||||
|
||||
std::string
|
||||
QueueItem::GetThreadLabel ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_thread_label;
|
||||
}
|
||||
|
||||
std::string
|
||||
QueueItem::GetQueueLabel ()
|
||||
{
|
||||
FetchEntireItem ();
|
||||
return m_queue_label;
|
||||
}
|
||||
|
||||
|
||||
ProcessSP
|
||||
QueueItem::GetProcessSP()
|
||||
{
|
||||
ProcessSP process_sp;
|
||||
QueueSP queue_sp = m_queue_wp.lock ();
|
||||
if (queue_sp)
|
||||
{
|
||||
process_sp = queue_sp->GetProcess();
|
||||
}
|
||||
return process_sp;
|
||||
return m_process_wp.lock ();
|
||||
}
|
||||
|
||||
void
|
||||
QueueItem::FetchEntireItem()
|
||||
{
|
||||
if (m_have_fetched_entire_item == true)
|
||||
return;
|
||||
ProcessSP process_sp = m_process_wp.lock();
|
||||
if (process_sp)
|
||||
{
|
||||
SystemRuntime *runtime = process_sp->GetSystemRuntime();
|
||||
if (runtime)
|
||||
{
|
||||
runtime->CompleteQueueItem (this, m_item_ref);
|
||||
m_have_fetched_entire_item = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue