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:
Jim Ingham 2012-10-10 18:32:14 +00:00
parent 9a6717f647
commit 4f465cff8a
26 changed files with 369 additions and 51 deletions

View File

@ -74,6 +74,7 @@ protected:
friend class SBBreakpoint;
friend class SBDebugger;
friend class SBProcess;
friend class SBThread;
SBEvent (lldb::EventSP &event_sp);

View File

@ -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;

View File

@ -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();

View File

@ -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:
//------------------------------------------------------------------

View File

@ -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.'''

View File

@ -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
{

View File

@ -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 ());

View File

@ -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;
}

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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());
}

View File

@ -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 ();

View File

@ -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);
}
}

View File

@ -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),

View File

@ -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

View File

@ -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),

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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);