Add a new SBThread::GetExtendedBacktraceOriginatingIndexID() method

(and same thing to Thread base class) which can be used when looking
at an ExtendedBacktrace thread; it will try to find the IndexID() of
the original thread that was executing this backtrace when it was
recorded.  If lldb can't find a record of that thread, it will return
the same value as IndexID() for the ExtendedBacktrace thread.

llvm-svn: 194912
This commit is contained in:
Jason Molenda
2013-11-16 01:24:22 +00:00
parent 5dcabbc9e8
commit 8ee9cb5891
8 changed files with 133 additions and 8 deletions

View File

@@ -204,6 +204,9 @@ public:
SBThread
GetExtendedBacktraceThread (const char *type);
uint32_t
GetExtendedBacktraceOriginatingIndexID ();
protected:
friend class SBBreakpoint;
friend class SBBreakpointLocation;

View File

@@ -273,6 +273,11 @@ public:
return NULL;
}
virtual void
SetName (const char *name)
{
}
virtual lldb::queue_id_t
GetQueueID ()
{
@@ -795,7 +800,7 @@ public:
void
SetTracer (lldb::ThreadPlanTracerSP &tracer_sp);
//------------------------------------------------------------------
// Get the thread index ID. The index ID that is guaranteed to not
// be re-used by a process. They start at 1 and increase with each
@@ -804,8 +809,25 @@ public:
//------------------------------------------------------------------
uint32_t
GetIndexID () const;
//------------------------------------------------------------------
// Get the originating thread's index ID.
// In the case of an "extended" thread -- a thread which represents
// the stack that enqueued/spawned work that is currently executing --
// we need to provide the IndexID of the thread that actually did
// this work. We don't want to just masquerade as that thread's IndexID
// by using it in our own IndexID because that way leads to madness -
// but the driver program which is iterating over extended threads
// may ask for the OriginatingThreadID to display that information
// to the user.
// Normal threads will return the same thing as GetIndexID();
//------------------------------------------------------------------
virtual uint32_t
GetExtendedBacktraceOriginatingIndexID ()
{
return GetIndexID ();
}
//------------------------------------------------------------------
// The API ID is often the same as the Thread::GetID(), but not in
// all cases. Thread::GetID() is the user visible thread ID that

View File

@@ -239,7 +239,7 @@ public:
bool
operator != (const lldb::SBThread &rhs) const;
%feature("autodoc","
Given an argument of str to specify the type of thread-origin extended
backtrace to retrieve, query whether the origin of this thread is
@@ -253,6 +253,18 @@ public:
lldb::SBThread
GetExtendedBacktraceThread (const char *type);
%feature("autodoc","
Takes no arguments, returns a uint32_t.
If this SBThread is an ExtendedBacktrace thread, get the IndexID of the
original thread that this ExtendedBacktrace thread represents, if
available. The thread that was running this backtrace in the past may
not have been registered with lldb's thread index (if it was created,
did its work, and was destroyed without lldb ever stopping execution).
In that case, this ExtendedBacktrace thread's IndexID will be returned.
") GetExtendedBacktraceOriginatingIndexID;
uint32_t
GetExtendedBacktraceOriginatingIndexID();
%pythoncode %{
class frames_access(object):
'''A helper object that will lazily hand out frames for a thread when supplied an index.'''

View File

@@ -1322,3 +1322,12 @@ SBThread::GetExtendedBacktraceThread (const char *type)
return sb_origin_thread;
}
uint32_t
SBThread::GetExtendedBacktraceOriginatingIndexID ()
{
ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
if (thread_sp)
return thread_sp->GetExtendedBacktraceOriginatingIndexID();
return LLDB_INVALID_INDEX32;
}

View File

@@ -21,6 +21,7 @@ using namespace lldb;
using namespace lldb_private;
HistoryThread::HistoryThread (lldb_private::Process &process,
lldb::tid_t tid,
std::vector<lldb::addr_t> pcs,
uint32_t stop_id,
bool stop_id_is_valid) :
@@ -30,7 +31,10 @@ HistoryThread::HistoryThread (lldb_private::Process &process,
m_pcs (pcs),
m_stop_id (stop_id),
m_stop_id_is_valid (stop_id_is_valid),
m_extended_unwind_token (LLDB_INVALID_ADDRESS)
m_extended_unwind_token (LLDB_INVALID_ADDRESS),
m_queue_name (),
m_thread_name (),
m_originating_unique_thread_id (tid)
{
m_unwinder_ap.reset (new HistoryUnwind (*this, pcs, stop_id, stop_id_is_valid));
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
@@ -75,3 +79,16 @@ HistoryThread::GetStackFrameList ()
return m_framelist;
}
uint32_t
HistoryThread::GetExtendedBacktraceOriginatingIndexID ()
{
if (m_originating_unique_thread_id != LLDB_INVALID_THREAD_ID)
{
if (GetProcess()->HasAssignedIndexIDToThread (m_originating_unique_thread_id))
{
return GetProcess()->AssignIndexIDToThread (m_originating_unique_thread_id);
}
}
return LLDB_INVALID_THREAD_ID;
}

View File

@@ -25,7 +25,7 @@ namespace lldb_private {
class HistoryThread : public lldb_private::Thread
{
public:
HistoryThread (lldb_private::Process &process, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
HistoryThread (lldb_private::Process &process, lldb::tid_t tid, std::vector<lldb::addr_t> pcs, uint32_t stop_id, bool stop_id_is_valid);
virtual ~HistoryThread ();
@@ -65,6 +65,21 @@ public:
m_queue_name = name;
}
const char *
GetThreadName ()
{
return m_thread_name.c_str();
}
uint32_t
GetExtendedBacktraceOriginatingIndexID ();
void
SetThreadName (const char *name)
{
m_thread_name = name;
}
protected:
virtual lldb::StackFrameListSP
GetStackFrameList ();
@@ -77,6 +92,8 @@ protected:
uint64_t m_extended_unwind_token;
std::string m_queue_name;
std::string m_thread_name;
lldb::tid_t m_originating_unique_thread_id;
};
} // namespace lldb_private

View File

@@ -331,7 +331,7 @@ SystemRuntimeMacOSX::SetNewThreadQueueName (ThreadSP original_thread_sp, ThreadS
addr_t queue_name_ptr = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.queue_name_ptr, error);
if (queue_name_ptr != LLDB_INVALID_ADDRESS && error.Success())
{
char namebuf[256];
char namebuf[512];
if (m_process->ReadCStringFromMemory (queue_name_ptr, namebuf, sizeof (namebuf), error) > 0 && error.Success())
{
new_extended_thread_sp->SetQueueName (namebuf);
@@ -340,6 +340,27 @@ SystemRuntimeMacOSX::SetNewThreadQueueName (ThreadSP original_thread_sp, ThreadS
}
}
void
SystemRuntimeMacOSX::SetNewThreadThreadName (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
{
addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
{
Error error;
addr_t thread_name_ptr = m_process->ReadPointerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.thread_name_ptr, error);
if (thread_name_ptr != LLDB_INVALID_ADDRESS && error.Success())
{
char namebuf[512];
if (m_process->ReadCStringFromMemory (thread_name_ptr, namebuf, sizeof (namebuf), error) > 0 && error.Success())
{
new_extended_thread_sp->SetName (namebuf);
}
}
}
}
void
SystemRuntimeMacOSX::SetNewThreadExtendedBacktraceToken (ThreadSP original_thread_sp, ThreadSP new_extended_thread_sp)
{
@@ -355,6 +376,21 @@ SystemRuntimeMacOSX::SetNewThreadExtendedBacktraceToken (ThreadSP original_threa
}
}
lldb::tid_t
SystemRuntimeMacOSX::GetNewThreadUniquethreadID (ThreadSP original_thread_sp)
{
tid_t ret = LLDB_INVALID_THREAD_ID;
addr_t enqueued_item_ptr = GetThreadCreatorItem (original_thread_sp);
if (enqueued_item_ptr != LLDB_INVALID_ADDRESS)
{
Error error;
ret = m_process->ReadUnsignedIntegerFromMemory (enqueued_item_ptr + m_ldi_header.item_offsets.unique_thread_id, 8, LLDB_INVALID_THREAD_ID, error);
if (!error.Success())
ret = LLDB_INVALID_THREAD_ID;
}
return ret;
}
ThreadSP
SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP original_thread_sp, ConstString type)
{
@@ -368,8 +404,11 @@ SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP original_thread_sp, Co
if (bt.pcs.size() == 0)
return new_extended_thread_sp;
new_extended_thread_sp.reset (new HistoryThread (*m_process, bt.pcs, bt.stop_id, bt.stop_id_is_valid));
tid_t unique_thread_id = GetNewThreadUniquethreadID (original_thread_sp);
new_extended_thread_sp.reset (new HistoryThread (*m_process, unique_thread_id, bt.pcs, bt.stop_id, bt.stop_id_is_valid));
SetNewThreadThreadName(original_thread_sp, new_extended_thread_sp);
SetNewThreadQueueName(original_thread_sp, new_extended_thread_sp);
SetNewThreadExtendedBacktraceToken(original_thread_sp, new_extended_thread_sp);

View File

@@ -125,6 +125,12 @@ private:
lldb::addr_t
GetThreadCreatorItem (lldb::ThreadSP thread);
lldb::tid_t
GetNewThreadUniquethreadID (lldb::ThreadSP original_thread_sp);
void
SetNewThreadThreadName (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);
void
SetNewThreadQueueName (lldb::ThreadSP original_thread_sp, lldb::ThreadSP new_extended_thread_sp);