forked from OSchip/llvm-project
Change the Thread constructor over to take a Process& rather than a ProcessSP. We can't create Threads with a NULL ProcessSP, so it makes no sense to use the SP.
Then make the Thread a Broadcaster, and get it to broadcast when the selected frame is changed (but only from the Command Line) and when Thread::ReturnFromFrame changes the stack. Made the Driver use this notification to print the new thread status rather than doing it in the command. Fixed a few places where people were setting their broadcaster class by hand rather than using the static broadcaster class call. <rdar://problem/12383087> llvm-svn: 165640
This commit is contained in:
parent
9a6717f647
commit
4f465cff8a
|
@ -74,6 +74,7 @@ protected:
|
|||
friend class SBBreakpoint;
|
||||
friend class SBDebugger;
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
|
||||
SBEvent (lldb::EventSP &event_sp);
|
||||
|
||||
|
|
|
@ -21,6 +21,17 @@ class SBFrame;
|
|||
class SBThread
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
eBroadcastBitStackChanged = (1 << 0),
|
||||
eBroadcastBitThreadSuspended = (1 << 1),
|
||||
eBroadcastBitThreadResumed = (1 << 2),
|
||||
eBroadcastBitSelectedFrameChanged = (1 << 3)
|
||||
};
|
||||
|
||||
static const char *
|
||||
GetBroadcasterClassName ();
|
||||
|
||||
SBThread ();
|
||||
|
||||
SBThread (const lldb::SBThread &thread);
|
||||
|
@ -147,6 +158,15 @@ public:
|
|||
lldb::SBFrame
|
||||
SetSelectedFrame (uint32_t frame_idx);
|
||||
|
||||
static bool
|
||||
EventIsThreadEvent (const SBEvent &event);
|
||||
|
||||
static SBFrame
|
||||
GetStackFrameFromEvent (const SBEvent &event);
|
||||
|
||||
static SBThread
|
||||
GetThreadFromEvent (const SBEvent &event);
|
||||
|
||||
lldb::SBProcess
|
||||
GetProcess ();
|
||||
|
||||
|
@ -162,6 +182,9 @@ public:
|
|||
bool
|
||||
GetDescription (lldb::SBStream &description) const;
|
||||
|
||||
bool
|
||||
GetStatus (lldb::SBStream &status) const;
|
||||
|
||||
protected:
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
|
|
|
@ -430,6 +430,10 @@ public:
|
|||
void
|
||||
RestoreBroadcaster ();
|
||||
|
||||
// This needs to be filled in if you are going to register the broadcaster with the broadcaster
|
||||
// manager and do broadcaster class matching.
|
||||
// FIXME: Probably should make a ManagedBroadcaster subclass with all the bits needed to work
|
||||
// with the BroadcasterManager, so that it is clearer how to add one.
|
||||
virtual ConstString &GetBroadcasterClass() const;
|
||||
|
||||
BroadcasterManager *GetManager();
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Host/Mutex.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
#include "lldb/Core/Event.h"
|
||||
#include "lldb/Core/UserID.h"
|
||||
#include "lldb/Core/UserSettingsController.h"
|
||||
#include "lldb/Target/ExecutionContextScope.h"
|
||||
|
@ -47,14 +49,88 @@ public:
|
|||
|
||||
typedef STD_SHARED_PTR(ThreadProperties) ThreadPropertiesSP;
|
||||
|
||||
|
||||
class Thread :
|
||||
public STD_ENABLE_SHARED_FROM_THIS(Thread),
|
||||
public ThreadProperties,
|
||||
public UserID,
|
||||
public ExecutionContextScope
|
||||
public ExecutionContextScope,
|
||||
public Broadcaster
|
||||
{
|
||||
friend class ThreadEventData;
|
||||
|
||||
public:
|
||||
//------------------------------------------------------------------
|
||||
/// Broadcaster event bits definitions.
|
||||
//------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
eBroadcastBitStackChanged = (1 << 0),
|
||||
eBroadcastBitThreadSuspended = (1 << 1),
|
||||
eBroadcastBitThreadResumed = (1 << 2),
|
||||
eBroadcastBitSelectedFrameChanged = (1 << 3)
|
||||
};
|
||||
|
||||
static ConstString &GetStaticBroadcasterClass ();
|
||||
|
||||
virtual ConstString &GetBroadcasterClass() const
|
||||
{
|
||||
return GetStaticBroadcasterClass();
|
||||
}
|
||||
|
||||
class ThreadEventData :
|
||||
public EventData
|
||||
{
|
||||
public:
|
||||
ThreadEventData (const lldb::ThreadSP thread_sp);
|
||||
|
||||
ThreadEventData (const lldb::ThreadSP thread_sp, const StackID &stack_id);
|
||||
|
||||
ThreadEventData();
|
||||
|
||||
virtual ~ThreadEventData();
|
||||
|
||||
static const ConstString &
|
||||
GetFlavorString ();
|
||||
|
||||
virtual const ConstString &
|
||||
GetFlavor () const
|
||||
{
|
||||
return ThreadEventData::GetFlavorString ();
|
||||
}
|
||||
|
||||
virtual void
|
||||
Dump (Stream *s) const;
|
||||
|
||||
static const ThreadEventData *
|
||||
GetEventDataFromEvent (const Event *event_ptr);
|
||||
|
||||
static lldb::ThreadSP
|
||||
GetThreadFromEvent (const Event *event_ptr);
|
||||
|
||||
static StackID
|
||||
GetStackIDFromEvent (const Event *event_ptr);
|
||||
|
||||
static lldb::StackFrameSP
|
||||
GetStackFrameFromEvent (const Event *event_ptr);
|
||||
|
||||
lldb::ThreadSP
|
||||
GetThread () const
|
||||
{
|
||||
return m_thread_sp;
|
||||
}
|
||||
|
||||
StackID
|
||||
GetStackID () const
|
||||
{
|
||||
return m_stack_id;
|
||||
}
|
||||
|
||||
private:
|
||||
lldb::ThreadSP m_thread_sp;
|
||||
StackID m_stack_id;
|
||||
DISALLOW_COPY_AND_ASSIGN (ThreadEventData);
|
||||
};
|
||||
|
||||
// TODO: You shouldn't just checkpoint the register state alone, so this should get
|
||||
// moved to protected. To do that ThreadStateCheckpoint needs to be returned as a token...
|
||||
class RegisterCheckpoint
|
||||
|
@ -141,7 +217,7 @@ public:
|
|||
static const ThreadPropertiesSP &
|
||||
GetGlobalProperties();
|
||||
|
||||
Thread (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
|
||||
Thread (Process &process, lldb::tid_t tid);
|
||||
virtual ~Thread();
|
||||
|
||||
lldb::ProcessSP
|
||||
|
@ -289,10 +365,10 @@ public:
|
|||
}
|
||||
|
||||
Error
|
||||
ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp);
|
||||
ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
|
||||
|
||||
Error
|
||||
ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp);
|
||||
ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast = false);
|
||||
|
||||
virtual lldb::StackFrameSP
|
||||
GetFrameWithStackID (const StackID &stack_id)
|
||||
|
@ -314,16 +390,10 @@ public:
|
|||
}
|
||||
|
||||
uint32_t
|
||||
SetSelectedFrame (lldb_private::StackFrame *frame)
|
||||
{
|
||||
return GetStackFrameList()->SetSelectedFrame(frame);
|
||||
}
|
||||
SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast = false);
|
||||
|
||||
bool
|
||||
SetSelectedFrameByIndex (uint32_t frame_idx)
|
||||
{
|
||||
return GetStackFrameList()->SetSelectedFrameByIndex(frame_idx);
|
||||
}
|
||||
SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast = false);
|
||||
|
||||
void
|
||||
SetDefaultFileAndLineToSelectedFrame()
|
||||
|
@ -557,6 +627,9 @@ private:
|
|||
bool
|
||||
PlanIsBasePlan (ThreadPlan *plan_ptr);
|
||||
|
||||
void
|
||||
BroadcastSelectedFrameChange(StackID &new_frame_id);
|
||||
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -47,6 +47,15 @@ public:
|
|||
|
||||
~SBThread();
|
||||
|
||||
static bool
|
||||
EventIsThreadEvent (const SBEvent &event);
|
||||
|
||||
static SBFrame
|
||||
GetStackFrameFromEvent (const SBEvent &event);
|
||||
|
||||
static SBThread
|
||||
GetThreadFromEvent (const SBEvent &event);
|
||||
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
|
@ -183,6 +192,9 @@ public:
|
|||
bool
|
||||
GetDescription (lldb::SBStream &description) const;
|
||||
|
||||
bool
|
||||
GetStatus (lldb::SBStream &status) const;
|
||||
|
||||
%pythoncode %{
|
||||
class frames_access(object):
|
||||
'''A helper object that will lazily hand out frames for a thread when supplied an index.'''
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBFrame.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBValue.h"
|
||||
|
@ -39,6 +40,12 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
const char *
|
||||
SBThread::GetBroadcasterClassName ()
|
||||
{
|
||||
return Thread::GetStaticBroadcasterClass().AsCString();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Constructors
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -1123,6 +1130,24 @@ SBThread::SetSelectedFrame (uint32_t idx)
|
|||
return sb_frame;
|
||||
}
|
||||
|
||||
bool
|
||||
SBThread::EventIsThreadEvent (const SBEvent &event)
|
||||
{
|
||||
return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
|
||||
}
|
||||
|
||||
SBFrame
|
||||
SBThread::GetStackFrameFromEvent (const SBEvent &event)
|
||||
{
|
||||
return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
|
||||
|
||||
}
|
||||
|
||||
SBThread
|
||||
SBThread::GetThreadFromEvent (const SBEvent &event)
|
||||
{
|
||||
return Thread::ThreadEventData::GetThreadFromEvent (event.get());
|
||||
}
|
||||
|
||||
bool
|
||||
SBThread::operator == (const SBThread &rhs) const
|
||||
|
@ -1136,6 +1161,22 @@ SBThread::operator != (const SBThread &rhs) const
|
|||
return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
|
||||
}
|
||||
|
||||
bool
|
||||
SBThread::GetStatus (SBStream &status) const
|
||||
{
|
||||
Stream &strm = status.ref();
|
||||
|
||||
ExecutionContext exe_ctx (m_opaque_sp.get());
|
||||
if (exe_ctx.HasThreadScope())
|
||||
{
|
||||
exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
|
||||
}
|
||||
else
|
||||
strm.PutCString ("No status");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SBThread::GetDescription (SBStream &description) const
|
||||
{
|
||||
|
|
|
@ -266,7 +266,8 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
bool success = thread->SetSelectedFrameByIndex (frame_idx);
|
||||
const bool broadcast = true;
|
||||
bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast);
|
||||
if (success)
|
||||
{
|
||||
exe_ctx.SetFrameSP(thread->GetSelectedFrame ());
|
||||
|
|
|
@ -1338,7 +1338,8 @@ protected:
|
|||
|
||||
Error error;
|
||||
ThreadSP thread_sp = exe_ctx.GetThreadSP();
|
||||
error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp);
|
||||
const bool broadcast = true;
|
||||
error = thread_sp->ReturnFromFrame (frame_sp, return_valobj_sp, broadcast);
|
||||
if (!error.Success())
|
||||
{
|
||||
result.AppendErrorWithFormat("Error returning from frame %d of thread %d: %s.", frame_idx, thread_sp->GetIndexID(), error.AsCString());
|
||||
|
@ -1346,7 +1347,6 @@ protected:
|
|||
return false;
|
||||
}
|
||||
|
||||
thread_sp->GetStatus(result.GetOutputStream(), 0, 1, 1);
|
||||
result.SetStatus (eReturnStatusSuccessFinishResult);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ OperatingSystemDarwinKernel::UpdateThreadList (ThreadList &old_thread_list, Thre
|
|||
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadMemory (m_process->shared_from_this(), tid, valobj_sp));
|
||||
thread_sp.reset (new ThreadMemory (*m_process, tid, valobj_sp));
|
||||
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
|
||||
|
|
|
@ -188,7 +188,7 @@ OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList
|
|||
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadMemory (m_process->shared_from_this(),
|
||||
thread_sp.reset (new ThreadMemory (*m_process,
|
||||
tid,
|
||||
name,
|
||||
queue));
|
||||
|
|
|
@ -419,7 +419,7 @@ ProcessKDP::GetKernelThread(ThreadList &old_thread_list, ThreadList &new_thread_
|
|||
ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false));
|
||||
if (!thread_sp)
|
||||
{
|
||||
thread_sp.reset(new ThreadKDP (shared_from_this(), kernel_tid));
|
||||
thread_sp.reset(new ThreadKDP (*this, kernel_tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
return thread_sp;
|
||||
|
|
|
@ -37,8 +37,8 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadKDP::ThreadKDP (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
ThreadKDP::ThreadKDP (Process &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
|
|
|
@ -20,7 +20,7 @@ class ProcessKDP;
|
|||
class ThreadKDP : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadKDP (const lldb::ProcessSP &process_sp,
|
||||
ThreadKDP (lldb_private::Process &process,
|
||||
lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
ThreadMemory::ThreadMemory (const ProcessSP &process_sp,
|
||||
ThreadMemory::ThreadMemory (Process &process,
|
||||
tid_t tid,
|
||||
const ValueObjectSP &thread_info_valobj_sp) :
|
||||
Thread (process_sp, tid),
|
||||
Thread (process, tid),
|
||||
m_thread_info_valobj_sp (thread_info_valobj_sp),
|
||||
m_name(),
|
||||
m_queue()
|
||||
|
@ -28,11 +28,11 @@ ThreadMemory::ThreadMemory (const ProcessSP &process_sp,
|
|||
}
|
||||
|
||||
|
||||
ThreadMemory::ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
ThreadMemory::ThreadMemory (Process &process,
|
||||
lldb::tid_t tid,
|
||||
const char *name,
|
||||
const char *queue) :
|
||||
Thread (process_sp, tid),
|
||||
Thread (process, tid),
|
||||
m_thread_info_valobj_sp (),
|
||||
m_name(),
|
||||
m_queue()
|
||||
|
|
|
@ -17,11 +17,11 @@ class ThreadMemory :
|
|||
{
|
||||
public:
|
||||
|
||||
ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
ThreadMemory (lldb_private::Process &process,
|
||||
lldb::tid_t tid,
|
||||
const lldb::ValueObjectSP &thread_info_valobj_sp);
|
||||
|
||||
ThreadMemory (const lldb::ProcessSP &process_sp,
|
||||
ThreadMemory (lldb_private::Process &process,
|
||||
lldb::tid_t tid,
|
||||
const char *name,
|
||||
const char *queue);
|
||||
|
|
|
@ -1338,7 +1338,7 @@ ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new
|
|||
tid_t tid = m_thread_ids[i];
|
||||
ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
|
||||
if (!thread_sp)
|
||||
thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
new_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
}
|
||||
|
@ -1405,7 +1405,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
|
|||
if (!thread_sp)
|
||||
{
|
||||
// Create the thread if we need to
|
||||
thread_sp.reset (new ThreadGDBRemote (shared_from_this(), tid));
|
||||
thread_sp.reset (new ThreadGDBRemote (*this, tid));
|
||||
m_thread_list.AddThread(thread_sp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,15 +32,15 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadGDBRemote::ThreadGDBRemote (const ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
ThreadGDBRemote::ThreadGDBRemote (Process &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS)
|
||||
{
|
||||
ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)",
|
||||
this,
|
||||
process_sp ? process_sp->GetID() : LLDB_INVALID_PROCESS_ID,
|
||||
process.GetID(),
|
||||
GetID());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class ProcessGDBRemote;
|
|||
class ThreadGDBRemote : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadGDBRemote (const lldb::ProcessSP &process_sp, lldb::tid_t tid);
|
||||
ThreadGDBRemote (lldb_private::Process &process, lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
~ThreadGDBRemote ();
|
||||
|
|
|
@ -344,7 +344,7 @@ ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_
|
|||
const uint32_t num_threads = core_objfile->GetNumThreadContexts ();
|
||||
for (lldb::tid_t tid = 0; tid < num_threads; ++tid)
|
||||
{
|
||||
ThreadSP thread_sp(new ThreadMachCore (shared_from_this(), tid));
|
||||
ThreadSP thread_sp(new ThreadMachCore (*this, tid));
|
||||
new_thread_list.AddThread (thread_sp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ using namespace lldb_private;
|
|||
// Thread Registers
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
ThreadMachCore::ThreadMachCore (const lldb::ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
Thread(process_sp, tid),
|
||||
ThreadMachCore::ThreadMachCore (Process &process, lldb::tid_t tid) :
|
||||
Thread(process, tid),
|
||||
m_thread_name (),
|
||||
m_dispatch_queue_name (),
|
||||
m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS),
|
||||
|
|
|
@ -19,7 +19,7 @@ class ProcessMachCore;
|
|||
class ThreadMachCore : public lldb_private::Thread
|
||||
{
|
||||
public:
|
||||
ThreadMachCore (const lldb::ProcessSP &process_sp,
|
||||
ThreadMachCore (lldb_private::Process &process,
|
||||
lldb::tid_t tid);
|
||||
|
||||
virtual
|
||||
|
|
|
@ -58,7 +58,7 @@ Target::GetStaticBroadcasterClass ()
|
|||
//----------------------------------------------------------------------
|
||||
Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp) :
|
||||
TargetProperties (this),
|
||||
Broadcaster (&debugger, "lldb.target"),
|
||||
Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
|
||||
ExecutionContextScope (),
|
||||
m_debugger (debugger),
|
||||
m_platform_sp (platform_sp),
|
||||
|
|
|
@ -38,7 +38,7 @@ TargetList::GetStaticBroadcasterClass ()
|
|||
// TargetList constructor
|
||||
//----------------------------------------------------------------------
|
||||
TargetList::TargetList(Debugger &debugger) :
|
||||
Broadcaster(&debugger, "TargetList"),
|
||||
Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
|
||||
m_target_list(),
|
||||
m_target_list_mutex (Mutex::eMutexTypeRecursive),
|
||||
m_selected_target_idx (0)
|
||||
|
|
|
@ -136,13 +136,112 @@ ThreadProperties::GetTraceEnabledState() const
|
|||
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Thread Event Data
|
||||
//------------------------------------------------------------------
|
||||
|
||||
Thread::Thread (const ProcessSP &process_sp, lldb::tid_t tid) :
|
||||
|
||||
const ConstString &
|
||||
Thread::ThreadEventData::GetFlavorString ()
|
||||
{
|
||||
static ConstString g_flavor ("Thread::ThreadEventData");
|
||||
return g_flavor;
|
||||
}
|
||||
|
||||
Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp) :
|
||||
m_thread_sp (thread_sp),
|
||||
m_stack_id ()
|
||||
{
|
||||
}
|
||||
|
||||
Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp, const StackID &stack_id) :
|
||||
m_thread_sp (thread_sp),
|
||||
m_stack_id (stack_id)
|
||||
{
|
||||
}
|
||||
|
||||
Thread::ThreadEventData::ThreadEventData () :
|
||||
m_thread_sp (),
|
||||
m_stack_id ()
|
||||
{
|
||||
}
|
||||
|
||||
Thread::ThreadEventData::~ThreadEventData ()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
Thread::ThreadEventData::Dump (Stream *s) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const Thread::ThreadEventData *
|
||||
Thread::ThreadEventData::GetEventDataFromEvent (const Event *event_ptr)
|
||||
{
|
||||
if (event_ptr)
|
||||
{
|
||||
const EventData *event_data = event_ptr->GetData();
|
||||
if (event_data && event_data->GetFlavor() == ThreadEventData::GetFlavorString())
|
||||
return static_cast <const ThreadEventData *> (event_ptr->GetData());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ThreadSP
|
||||
Thread::ThreadEventData::GetThreadFromEvent (const Event *event_ptr)
|
||||
{
|
||||
ThreadSP thread_sp;
|
||||
const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
|
||||
if (event_data)
|
||||
thread_sp = event_data->GetThread();
|
||||
return thread_sp;
|
||||
}
|
||||
|
||||
StackID
|
||||
Thread::ThreadEventData::GetStackIDFromEvent (const Event *event_ptr)
|
||||
{
|
||||
StackID stack_id;
|
||||
const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
|
||||
if (event_data)
|
||||
stack_id = event_data->GetStackID();
|
||||
return stack_id;
|
||||
}
|
||||
|
||||
StackFrameSP
|
||||
Thread::ThreadEventData::GetStackFrameFromEvent (const Event *event_ptr)
|
||||
{
|
||||
const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr);
|
||||
StackFrameSP frame_sp;
|
||||
if (event_data)
|
||||
{
|
||||
ThreadSP thread_sp = event_data->GetThread();
|
||||
if (thread_sp)
|
||||
{
|
||||
frame_sp = thread_sp->GetStackFrameList()->GetFrameWithStackID (event_data->GetStackID());
|
||||
}
|
||||
}
|
||||
return frame_sp;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Thread class
|
||||
//------------------------------------------------------------------
|
||||
|
||||
ConstString &
|
||||
Thread::GetStaticBroadcasterClass ()
|
||||
{
|
||||
static ConstString class_name ("lldb.thread");
|
||||
return class_name;
|
||||
}
|
||||
|
||||
Thread::Thread (Process &process, lldb::tid_t tid) :
|
||||
ThreadProperties (false),
|
||||
UserID (tid),
|
||||
m_process_wp (process_sp),
|
||||
Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
|
||||
m_process_wp (process.shared_from_this()),
|
||||
m_actual_stop_info_sp (),
|
||||
m_index_id (process_sp->GetNextThreadIndexID ()),
|
||||
m_index_id (process.GetNextThreadIndexID ()),
|
||||
m_reg_context_sp (),
|
||||
m_state (eStateUnloaded),
|
||||
m_state_mutex (Mutex::eMutexTypeRecursive),
|
||||
|
@ -163,6 +262,7 @@ Thread::Thread (const ProcessSP &process_sp, lldb::tid_t tid) :
|
|||
if (log)
|
||||
log->Printf ("%p Thread::Thread(tid = 0x%4.4llx)", this, GetID());
|
||||
|
||||
CheckInWithManager();
|
||||
QueueFundamentalPlan(true);
|
||||
}
|
||||
|
||||
|
@ -186,6 +286,38 @@ Thread::DestroyThread ()
|
|||
m_destroy_called = true;
|
||||
}
|
||||
|
||||
void
|
||||
Thread::BroadcastSelectedFrameChange(StackID &new_frame_id)
|
||||
{
|
||||
if (EventTypeHasListeners(eBroadcastBitSelectedFrameChanged))
|
||||
BroadcastEvent(eBroadcastBitSelectedFrameChanged, new ThreadEventData (this->shared_from_this(), new_frame_id));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Thread::SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast)
|
||||
{
|
||||
uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame);
|
||||
if (broadcast)
|
||||
BroadcastSelectedFrameChange(frame->GetStackID());
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
bool
|
||||
Thread::SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast)
|
||||
{
|
||||
StackFrameSP frame_sp(GetStackFrameList()->GetFrameAtIndex (frame_idx));
|
||||
if (frame_sp)
|
||||
{
|
||||
GetStackFrameList()->SetSelectedFrame(frame_sp.get());
|
||||
if (broadcast)
|
||||
BroadcastSelectedFrameChange(frame_sp->GetStackID());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
lldb::StopInfoSP
|
||||
Thread::GetStopInfo ()
|
||||
{
|
||||
|
@ -1285,7 +1417,7 @@ Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx)
|
|||
|
||||
|
||||
Error
|
||||
Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp)
|
||||
Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast)
|
||||
{
|
||||
StackFrameSP frame_sp = GetStackFrameAtIndex (frame_idx);
|
||||
Error return_error;
|
||||
|
@ -1295,11 +1427,11 @@ Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return
|
|||
return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%llx.", frame_idx, GetID());
|
||||
}
|
||||
|
||||
return ReturnFromFrame(frame_sp, return_value_sp);
|
||||
return ReturnFromFrame(frame_sp, return_value_sp, broadcast);
|
||||
}
|
||||
|
||||
Error
|
||||
Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp)
|
||||
Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast)
|
||||
{
|
||||
Error return_error;
|
||||
|
||||
|
@ -1358,6 +1490,8 @@ Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return
|
|||
{
|
||||
thread->DiscardThreadPlans(true);
|
||||
thread->ClearStackFrames();
|
||||
if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged))
|
||||
BroadcastEvent(eBroadcastBitStackChanged, new ThreadEventData (this->shared_from_this()));
|
||||
return return_error;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -978,6 +978,25 @@ Driver::HandleProcessEvent (const SBEvent &event)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
Driver::HandleThreadEvent (const SBEvent &event)
|
||||
{
|
||||
// At present the only thread event we handle is the Frame Changed event, and all we do for that is just
|
||||
// reprint the thread status for that thread.
|
||||
using namespace lldb;
|
||||
const uint32_t event_type = event.GetType();
|
||||
if (event_type == SBThread::eBroadcastBitStackChanged)
|
||||
{
|
||||
SBThread thread = SBThread::GetThreadFromEvent (event);
|
||||
if (thread.IsValid())
|
||||
{
|
||||
SBStream out_stream;
|
||||
thread.GetStatus(out_stream);
|
||||
m_io_channel_ap->OutWrite (out_stream.GetData (), out_stream.GetSize (), ASYNC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function handles events broadcast by the IOChannel (HasInput, UserInterrupt, or ThreadShouldExit).
|
||||
|
||||
bool
|
||||
|
@ -1268,12 +1287,15 @@ Driver::MainLoop ()
|
|||
m_debugger.PushInputReader (m_editline_reader);
|
||||
|
||||
SBListener listener(m_debugger.GetListener());
|
||||
listener.StartListeningForEventClass(m_debugger,
|
||||
SBTarget::GetBroadcasterClassName(),
|
||||
SBTarget::eBroadcastBitBreakpointChanged);
|
||||
if (listener.IsValid())
|
||||
{
|
||||
|
||||
listener.StartListeningForEventClass(m_debugger,
|
||||
SBTarget::GetBroadcasterClassName(),
|
||||
SBTarget::eBroadcastBitBreakpointChanged);
|
||||
listener.StartListeningForEventClass(m_debugger,
|
||||
SBThread::GetBroadcasterClassName(),
|
||||
SBThread::eBroadcastBitStackChanged);
|
||||
listener.StartListeningForEvents (*m_io_channel_ap,
|
||||
IOChannel::eBroadcastBitHasUserInput |
|
||||
IOChannel::eBroadcastBitUserInterrupt |
|
||||
|
@ -1452,6 +1474,10 @@ Driver::MainLoop ()
|
|||
{
|
||||
HandleBreakpointEvent (event);
|
||||
}
|
||||
else if (SBThread::EventIsThreadEvent (event))
|
||||
{
|
||||
HandleThreadEvent (event);
|
||||
}
|
||||
else if (event.BroadcasterMatchesRef (sb_interpreter.GetBroadcaster()))
|
||||
{
|
||||
// TODO: deprecate the eBroadcastBitQuitCommandReceived event
|
||||
|
|
|
@ -65,6 +65,9 @@ public:
|
|||
void
|
||||
HandleBreakpointEvent (const lldb::SBEvent &event);
|
||||
|
||||
void
|
||||
HandleThreadEvent (const lldb::SBEvent &event);
|
||||
|
||||
lldb::SBError
|
||||
ParseArgs (int argc, const char *argv[], FILE *out_fh, bool &do_exit);
|
||||
|
||||
|
|
Loading…
Reference in New Issue