From 4f465cff8a1591a821d13c7fb34bfc56c1d1d96f Mon Sep 17 00:00:00 2001 From: Jim Ingham Date: Wed, 10 Oct 2012 18:32:14 +0000 Subject: [PATCH] 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. llvm-svn: 165640 --- lldb/include/lldb/API/SBEvent.h | 1 + lldb/include/lldb/API/SBThread.h | 23 ++++ lldb/include/lldb/Core/Broadcaster.h | 4 + lldb/include/lldb/Target/Thread.h | 101 ++++++++++++-- lldb/scripts/Python/interface/SBThread.i | 12 ++ lldb/source/API/SBThread.cpp | 41 ++++++ lldb/source/Commands/CommandObjectFrame.cpp | 5 +- lldb/source/Commands/CommandObjectThread.cpp | 4 +- .../Darwin-Kernel/OperatingSystemDarwinKernel.cpp | 2 +- .../Python/OperatingSystemPython.cpp | 2 +- .../Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp | 2 +- .../Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp | 4 +- .../Plugins/Process/MacOSX-Kernel/ThreadKDP.h | 2 +- .../Plugins/Process/Utility/ThreadMemory.cpp | 8 +- lldb/source/Plugins/Process/Utility/ThreadMemory.h | 4 +- .../Process/gdb-remote/ProcessGDBRemote.cpp | 4 +- .../Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 6 +- .../Plugins/Process/gdb-remote/ThreadGDBRemote.h | 2 +- .../Plugins/Process/mach-core/ProcessMachCore.cpp | 2 +- .../Plugins/Process/mach-core/ThreadMachCore.cpp | 4 +- .../Plugins/Process/mach-core/ThreadMachCore.h | 2 +- lldb/source/Target/Target.cpp | 2 +- lldb/source/Target/TargetList.cpp | 2 +- lldb/source/Target/Thread.cpp | 146 ++++++++++++++++++++- lldb/tools/driver/Driver.cpp | 32 ++++- lldb/tools/driver/Driver.h | 3 + 26 files changed, 369 insertions(+), 51 deletions(-) diff --git a/lldb/include/lldb/API/SBEvent.h b/lldb/include/lldb/API/SBEvent.h index a24e556..f116060 100644 --- a/lldb/include/lldb/API/SBEvent.h +++ b/lldb/include/lldb/API/SBEvent.h @@ -74,6 +74,7 @@ protected: friend class SBBreakpoint; friend class SBDebugger; friend class SBProcess; + friend class SBThread; SBEvent (lldb::EventSP &event_sp); diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index be67526..947ef14 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -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); @@ -146,6 +157,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 (); @@ -161,6 +181,9 @@ public: bool GetDescription (lldb::SBStream &description) const; + + bool + GetStatus (lldb::SBStream &status) const; protected: friend class SBBreakpoint; diff --git a/lldb/include/lldb/Core/Broadcaster.h b/lldb/include/lldb/Core/Broadcaster.h index d144b1c..907132b 100644 --- a/lldb/include/lldb/Core/Broadcaster.h +++ b/lldb/include/lldb/Core/Broadcaster.h @@ -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(); diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index a509fb4..8ca0729 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -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,15 +49,89 @@ 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: - // TODO: You shouldn't just checkpoint the register state alone, so this should get + //------------------------------------------------------------------ + /// 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: //------------------------------------------------------------------ diff --git a/lldb/scripts/Python/interface/SBThread.i b/lldb/scripts/Python/interface/SBThread.i index 7c5d9f5..76a014a 100644 --- a/lldb/scripts/Python/interface/SBThread.i +++ b/lldb/scripts/Python/interface/SBThread.i @@ -46,6 +46,15 @@ public: SBThread (const lldb::SBThread &thread); ~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.''' diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp index 5a09dcc..f895a3d 100644 --- a/lldb/source/API/SBThread.cpp +++ b/lldb/source/API/SBThread.cpp @@ -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 @@ -1137,6 +1162,22 @@ SBThread::operator != (const SBThread &rhs) const } 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 { Stream &strm = description.ref(); diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 0ac8e92..eab0d02 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -265,8 +265,9 @@ protected: m_options.GenerateOptionUsage (result.GetErrorStream(), this); } } - - bool success = thread->SetSelectedFrameByIndex (frame_idx); + + const bool broadcast = true; + bool success = thread->SetSelectedFrameByIndex (frame_idx, broadcast); if (success) { exe_ctx.SetFrameSP(thread->GetSelectedFrame ()); diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp index a2c3e6a..8c2be37 100644 --- a/lldb/source/Commands/CommandObjectThread.cpp +++ b/lldb/source/Commands/CommandObjectThread.cpp @@ -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; } diff --git a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp index b1e6830..93e6933 100644 --- a/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp +++ b/lldb/source/Plugins/OperatingSystem/Darwin-Kernel/OperatingSystemDarwinKernel.cpp @@ -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); diff --git a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index 8de0f10..c5e3f8a4 100644 --- a/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -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)); diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 8f7021a..ac09a55 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -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; diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp index 150c314..567658d 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp @@ -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) diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h index 97f5f8a..5454f2b 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.h @@ -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 diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp index 10c3a90..9e4c6d6 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.cpp @@ -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() diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h index c1603d4..1880c5a 100644 --- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -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); diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 1cc1009..215e885 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -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); } } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 95e4a99..b63b42d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -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()); } diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 3eb6295..375b7a5 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -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 (); diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp index 255f46b..5b34614 100644 --- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp @@ -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); } } diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp index 3568dc7..001cda1 100644 --- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp +++ b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.cpp @@ -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), diff --git a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h index 497620c..a2d3b7a 100644 --- a/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h +++ b/lldb/source/Plugins/Process/mach-core/ThreadMachCore.h @@ -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 diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 9fbf08b..8a89687 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -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), diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp index 94f0d7e..3f24dd6 100644 --- a/lldb/source/Target/TargetList.cpp +++ b/lldb/source/Target/TargetList.cpp @@ -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) diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index e002ec9..5a48a0a 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -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 (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 diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp index 84d464f..048faff 100644 --- a/lldb/tools/driver/Driver.cpp +++ b/lldb/tools/driver/Driver.cpp @@ -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 diff --git a/lldb/tools/driver/Driver.h b/lldb/tools/driver/Driver.h index 2c69b6cc..16558e0 100644 --- a/lldb/tools/driver/Driver.h +++ b/lldb/tools/driver/Driver.h @@ -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); -- 2.7.4