[Lldb-commits] [lldb] r262863 - Change over the broadcaster/listener process to hold shared or weak pointers

Jim Ingham via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 8 11:32:31 PST 2016


Thanks, Tamas, sorry I missed that.  Looks like everything is green again.

Jim




> On Mar 8, 2016, at 5:39 AM, Tamas Berghammer <tberghammer at google.com> wrote:
> 
> I committed in a fix as rL262925 (initialization order issue in a log line)
> 
> On Tue, Mar 8, 2016 at 3:04 AM Jim Ingham via lldb-commits <lldb-commits at lists.llvm.org> wrote:
> I can’t get to a linux box right now, and I can’t tell from the bot logs what is going wrong.  This change was pretty much all in generic code, the only places it touched platform specific code was to make sure the Process plugins used a Listener Shared pointer not a listener reference, and mechanical changes wherever folks had to make Listeners.  So I’m kind of surprised this is causing problems.
> 
> If somebody working on the Linux side could take a look at what’s going wrong, that would be great.  Otherwise feel free to revert it and I’ll look into it when I can.
> 
> Jim
> 
> 
> > On Mar 7, 2016, at 5:40 PM, Siva Chandra <sivachandra at google.com> wrote:
> >
> > I think this broke everything on Linux:
> > http://lab.llvm.org:8011/builders/lldb-x86_64-ubuntu-14.04-cmake/builds/12154
> >
> > On Mon, Mar 7, 2016 at 1:50 PM, Jim Ingham via lldb-commits
> > <lldb-commits at lists.llvm.org> wrote:
> >> Author: jingham
> >> Date: Mon Mar  7 15:50:25 2016
> >> New Revision: 262863
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=262863&view=rev
> >> Log:
> >> Change over the broadcaster/listener process to hold shared or weak pointers
> >> to each other.  This should remove some infrequent teardown crashes when the
> >> listener is not the debugger's listener.
> >>
> >> Processes now need to take a ListenerSP, not a Listener&.
> >>
> >> This required changing over the Process plugin class constructors to take a ListenerSP, instead
> >> of a Listener&.   Other than that there should be no functional change.
> >>
> >> <rdar://problem/24580184> CrashTracer: [USER] Xcode at …ework: lldb_private::Listener::BroadcasterWillDestruct + 39
> >>
> >> Added:
> >>    lldb/trunk/packages/Python/lldbsuite/test/api/listeners/
> >>    lldb/trunk/packages/Python/lldbsuite/test/api/listeners/Makefile
> >>    lldb/trunk/packages/Python/lldbsuite/test/api/listeners/TestListener.py
> >>    lldb/trunk/packages/Python/lldbsuite/test/api/listeners/main.c
> >> Modified:
> >>    lldb/trunk/include/lldb/API/SBListener.h
> >>    lldb/trunk/include/lldb/Core/Broadcaster.h
> >>    lldb/trunk/include/lldb/Core/Debugger.h
> >>    lldb/trunk/include/lldb/Core/Event.h
> >>    lldb/trunk/include/lldb/Core/Listener.h
> >>    lldb/trunk/include/lldb/Target/Process.h
> >>    lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h
> >>    lldb/trunk/include/lldb/Target/Target.h
> >>    lldb/trunk/include/lldb/lldb-forward.h
> >>    lldb/trunk/include/lldb/lldb-private-interfaces.h
> >>    lldb/trunk/source/API/SBBroadcaster.cpp
> >>    lldb/trunk/source/API/SBDebugger.cpp
> >>    lldb/trunk/source/API/SBListener.cpp
> >>    lldb/trunk/source/API/SBTarget.cpp
> >>    lldb/trunk/source/Core/Broadcaster.cpp
> >>    lldb/trunk/source/Core/Communication.cpp
> >>    lldb/trunk/source/Core/Debugger.cpp
> >>    lldb/trunk/source/Core/Event.cpp
> >>    lldb/trunk/source/Core/IOHandler.cpp
> >>    lldb/trunk/source/Core/Listener.cpp
> >>    lldb/trunk/source/Interpreter/CommandInterpreter.cpp
> >>    lldb/trunk/source/Plugins/Platform/Linux/PlatformLinux.cpp
> >>    lldb/trunk/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
> >>    lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp
> >>    lldb/trunk/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
> >>    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp
> >>    lldb/trunk/source/Plugins/Process/FreeBSD/ProcessFreeBSD.h
> >>    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
> >>    lldb/trunk/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
> >>    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.cpp
> >>    lldb/trunk/source/Plugins/Process/Windows/Common/ProcessWindows.h
> >>    lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
> >>    lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.h
> >>    lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
> >>    lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.h
> >>    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.cpp
> >>    lldb/trunk/source/Plugins/Process/elf-core/ProcessElfCore.h
> >>    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
> >>    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
> >>    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
> >>    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.cpp
> >>    lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
> >>    lldb/trunk/source/Target/Process.cpp
> >>    lldb/trunk/source/Target/ProcessLaunchInfo.cpp
> >>    lldb/trunk/source/Target/Target.cpp
> >>    lldb/trunk/source/Target/TargetList.cpp
> >>    lldb/trunk/source/Target/Thread.cpp
> >>
> >> Modified: lldb/trunk/include/lldb/API/SBListener.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBListener.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/API/SBListener.h (original)
> >> +++ lldb/trunk/include/lldb/API/SBListener.h Mon Mar  7 15:50:25 2016
> >> @@ -106,8 +106,6 @@ protected:
> >>     friend class SBLaunchInfo;
> >>     friend class SBTarget;
> >>
> >> -    SBListener (lldb_private::Listener &listener);
> >> -
> >>     SBListener (const lldb::ListenerSP &listener_sp);
> >>
> >>     lldb::ListenerSP
> >> @@ -124,20 +122,11 @@ private:
> >>     lldb_private::Listener *
> >>     get() const;
> >>
> >> -    lldb_private::Listener &
> >> -    ref() const;
> >> -
> >> -    lldb_private::Listener &
> >> -    operator *();
> >> -
> >> -    const lldb_private::Listener &
> >> -    operator *() const;
> >> -
> >>     void
> >> -    reset(lldb_private::Listener *listener, bool transfer_ownership);
> >> +    reset(lldb::ListenerSP listener_sp);
> >>
> >>     lldb::ListenerSP m_opaque_sp;
> >> -    lldb_private::Listener *m_opaque_ptr;
> >> +    lldb_private::Listener *m_unused_ptr;
> >> };
> >>
> >> } // namespace lldb
> >>
> >> Modified: lldb/trunk/include/lldb/Core/Broadcaster.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Broadcaster.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Core/Broadcaster.h (original)
> >> +++ lldb/trunk/include/lldb/Core/Broadcaster.h Mon Mar  7 15:50:25 2016
> >> @@ -19,9 +19,8 @@
> >> // Other libraries and framework includes
> >> // Project includes
> >> #include "lldb/lldb-private.h"
> >> -//#include "lldb/Core/Flags.h"
> >> #include "lldb/Core/ConstString.h"
> >> -#include "lldb/Core/Listener.h"
> >> +#include "lldb/Host/Mutex.h"
> >>
> >> namespace lldb_private {
> >>
> >> @@ -82,37 +81,47 @@ private:
> >>     uint32_t m_event_bits;
> >> };
> >>
> >> -class BroadcasterManager
> >> +class BroadcasterManager :
> >> +    public std::enable_shared_from_this<BroadcasterManager>
> >> {
> >> public:
> >>     friend class Listener;
> >>
> >> +protected:
> >>     BroadcasterManager ();
> >> -
> >> +public:
> >> +    // Listeners hold onto weak pointers to their broadcaster managers.  So they must be
> >> +    // made into shared pointers, which you do with MakeBroadcasterManager.
> >> +
> >> +    static lldb::BroadcasterManagerSP
> >> +    MakeBroadcasterManager();
> >> +
> >>     ~BroadcasterManager() = default;
> >>
> >>     uint32_t
> >> -    RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
> >> +    RegisterListenerForEvents (lldb::ListenerSP listener_sp, BroadcastEventSpec event_spec);
> >>
> >>     bool
> >> -    UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec);
> >> +    UnregisterListenerForEvents (lldb::ListenerSP listener_sp, BroadcastEventSpec event_spec);
> >>
> >> -    Listener *
> >> +    lldb::ListenerSP
> >>     GetListenerForEventSpec (BroadcastEventSpec event_spec) const;
> >>
> >>     void
> >>     SignUpListenersForBroadcaster (Broadcaster &broadcaster);
> >>
> >>     void
> >> -    RemoveListener (Listener &Listener);
> >> +    RemoveListener (lldb::ListenerSP listener_sp);
> >> +
> >> +    void
> >> +    RemoveListener (Listener *listener);
> >>
> >> -protected:
> >>     void Clear();
> >>
> >> private:
> >> -    typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key;
> >> -    typedef std::map<BroadcastEventSpec, Listener *> collection;
> >> -    typedef std::set<Listener *> listener_collection;
> >> +    typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
> >> +    typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
> >> +    typedef std::set<lldb::ListenerSP> listener_collection;
> >>     collection m_event_map;
> >>     listener_collection m_listeners;
> >>
> >> @@ -162,9 +171,9 @@ private:
> >>     {
> >>     public:
> >>         ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec,
> >> -                                                   const Listener &listener) :
> >> +                                                   const lldb::ListenerSP listener_sp) :
> >>             m_broadcaster_spec (broadcaster_spec),
> >> -            m_listener (&listener)
> >> +            m_listener_sp (listener_sp)
> >>         {
> >>         }
> >>
> >> @@ -174,19 +183,19 @@ private:
> >>         {
> >>             return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass()
> >>                     && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0
> >> -                    && input.second == m_listener);
> >> +                    && input.second == m_listener_sp);
> >>         }
> >>
> >>     private:
> >>         BroadcastEventSpec m_broadcaster_spec;
> >> -        const Listener *m_listener;
> >> +        const lldb::ListenerSP m_listener_sp;
> >>     };
> >>
> >>     class ListenerMatches
> >>     {
> >>     public:
> >> -        ListenerMatches (const Listener &in_listener) :
> >> -            m_listener (&in_listener)
> >> +        ListenerMatches (const lldb::ListenerSP in_listener_sp) :
> >> +            m_listener_sp (in_listener_sp)
> >>         {
> >>         }
> >>
> >> @@ -194,7 +203,40 @@ private:
> >>
> >>         bool operator () (const event_listener_key input) const
> >>         {
> >> -            return (input.second == m_listener);
> >> +            if (input.second == m_listener_sp)
> >> +                return true;
> >> +            else
> >> +                return false;
> >> +        }
> >> +
> >> +    private:
> >> +        const lldb::ListenerSP m_listener_sp;
> >> +    };
> >> +
> >> +    class ListenerMatchesPointer
> >> +    {
> >> +    public:
> >> +        ListenerMatchesPointer (const Listener *in_listener) :
> >> +            m_listener (in_listener)
> >> +        {
> >> +        }
> >> +
> >> +        ~ListenerMatchesPointer() = default;
> >> +
> >> +        bool operator () (const event_listener_key input) const
> >> +        {
> >> +            if (input.second.get() == m_listener)
> >> +                return true;
> >> +            else
> >> +                return false;
> >> +        }
> >> +
> >> +        bool operator () (const lldb::ListenerSP input) const
> >> +        {
> >> +            if (input.get() == m_listener)
> >> +                return true;
> >> +            else
> >> +                return false;
> >>         }
> >>
> >>     private:
> >> @@ -237,6 +279,8 @@ private:
> >> //----------------------------------------------------------------------
> >> class Broadcaster
> >> {
> >> +friend class Listener;
> >> +friend class Event;
> >> public:
> >>     //------------------------------------------------------------------
> >>     /// Construct with a broadcaster with a name.
> >> @@ -245,7 +289,7 @@ public:
> >>     ///     A NULL terminated C string that contains the name of the
> >>     ///     broadcaster object.
> >>     //------------------------------------------------------------------
> >> -    Broadcaster (BroadcasterManager *manager, const char *name);
> >> +    Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name);
> >>
> >>     //------------------------------------------------------------------
> >>     /// Destructor.
> >> @@ -275,22 +319,37 @@ public:
> >>     ///
> >>     //------------------------------------------------------------------
> >>     void
> >> -    BroadcastEvent (lldb::EventSP &event_sp);
> >> +    BroadcastEvent (lldb::EventSP &event_sp)
> >> +    {
> >> +        m_broadcaster_sp->BroadcastEvent(event_sp);
> >> +    }
> >>
> >>     void
> >> -    BroadcastEventIfUnique (lldb::EventSP &event_sp);
> >> +    BroadcastEventIfUnique (lldb::EventSP &event_sp)
> >> +    {
> >> +        m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
> >> +    }
> >>
> >>     void
> >> -    BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
> >> +    BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr)
> >> +    {
> >> +        m_broadcaster_sp->BroadcastEvent(event_type, event_data);
> >> +    }
> >>
> >>     void
> >> -    BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
> >> +    BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr)
> >> +    {
> >> +        m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
> >> +    }
> >>
> >>     void
> >> -    Clear();
> >> +    Clear()
> >> +    {
> >> +        m_broadcaster_sp->Clear();
> >> +    }
> >>
> >>     virtual void
> >> -    AddInitialEventsToListener (Listener *listener, uint32_t requested_events);
> >> +    AddInitialEventsToListener (lldb::ListenerSP listener_sp, uint32_t requested_events);
> >>
> >>     //------------------------------------------------------------------
> >>     /// Listen for any events specified by \a event_mask.
> >> @@ -315,7 +374,10 @@ public:
> >>     ///     The actual event bits that were acquired by \a listener.
> >>     //------------------------------------------------------------------
> >>     uint32_t
> >> -    AddListener (Listener* listener, uint32_t event_mask);
> >> +    AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask)
> >> +    {
> >> +        return m_broadcaster_sp->AddListener(listener_sp, event_mask);
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Get the NULL terminated C string name of this Broadcaster
> >> @@ -325,7 +387,10 @@ public:
> >>     ///     The NULL terminated C string name of this Broadcaster.
> >>     //------------------------------------------------------------------
> >>     const ConstString &
> >> -    GetBroadcasterName ();
> >> +    GetBroadcasterName ()
> >> +    {
> >> +        return m_broadcaster_name;
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Get the event name(s) for one or more event bits.
> >> @@ -337,7 +402,10 @@ public:
> >>     ///     The NULL terminated C string name of this Broadcaster.
> >>     //------------------------------------------------------------------
> >>     bool
> >> -    GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
> >> +    GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const
> >> +    {
> >> +        return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name);
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Set the name for an event bit.
> >> @@ -352,20 +420,20 @@ public:
> >>     void
> >>     SetEventName (uint32_t event_mask, const char *name)
> >>     {
> >> -        m_event_names[event_mask] = name;
> >> +        m_broadcaster_sp->SetEventName(event_mask, name);
> >>     }
> >>
> >>     const char *
> >>     GetEventName (uint32_t event_mask) const
> >>     {
> >> -        const auto pos = m_event_names.find (event_mask);
> >> -        if (pos != m_event_names.end())
> >> -            return pos->second.c_str();
> >> -        return nullptr;
> >> +        return m_broadcaster_sp->GetEventName(event_mask);
> >>     }
> >>
> >>     bool
> >> -    EventTypeHasListeners (uint32_t event_type);
> >> +    EventTypeHasListeners (uint32_t event_type)
> >> +    {
> >> +        return m_broadcaster_sp->EventTypeHasListeners(event_type);
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Removes a Listener from this broadcasters list and frees the
> >> @@ -386,7 +454,10 @@ public:
> >>     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
> >>     //------------------------------------------------------------------
> >>     bool
> >> -    RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX);
> >> +    RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX)
> >> +    {
> >> +        return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Provides a simple mechanism to temporarily redirect events from
> >> @@ -410,17 +481,26 @@ public:
> >>     /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
> >>     //------------------------------------------------------------------
> >>     bool
> >> -    HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX);
> >> +    HijackBroadcaster (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX)
> >> +    {
> >> +        return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
> >> +    }
> >>
> >>     bool
> >> -    IsHijackedForEvent (uint32_t event_mask);
> >> +    IsHijackedForEvent (uint32_t event_mask)
> >> +    {
> >> +        return m_broadcaster_sp->IsHijackedForEvent(event_mask);
> >> +    }
> >>
> >>     //------------------------------------------------------------------
> >>     /// Restore the state of the Broadcaster from a previous hijack attempt.
> >>     ///
> >>     //------------------------------------------------------------------
> >>     void
> >> -    RestoreBroadcaster ();
> >> +    RestoreBroadcaster ()
> >> +    {
> >> +        m_broadcaster_sp->RestoreBroadcaster();
> >> +    }
> >>
> >>     // This needs to be filled in if you are going to register the broadcaster with the broadcaster
> >>     // manager and do broadcaster class matching.
> >> @@ -428,32 +508,145 @@ public:
> >>     // with the BroadcasterManager, so that it is clearer how to add one.
> >>     virtual ConstString &GetBroadcasterClass() const;
> >>
> >> -    BroadcasterManager *GetManager();
> >> +    lldb::BroadcasterManagerSP GetManager();
> >>
> >> protected:
> >> -    void
> >> -    PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
> >> +    // BroadcasterImpl contains the actual Broadcaster implementation.  The Broadcaster makes a BroadcasterImpl
> >> +    // which lives as long as it does.  The Listeners & the Events hold a weak pointer to the BroadcasterImpl,
> >> +    // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to
> >> +    // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads
> >> +    // simultaneously.
> >> +    // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters
> >> +    // (e.g. the Target and the Process) are shared in their own right.
> >> +    //
> >> +    // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the
> >> +    // public Broadcaster API above.
> >> +
> >> +
> >> +    class BroadcasterImpl
> >> +    {
> >> +    friend class Listener;
> >> +    friend class Broadcaster;
> >> +    public:
> >> +        BroadcasterImpl (Broadcaster &broadcaster);
> >> +
> >> +        ~BroadcasterImpl() = default;
> >> +
> >> +        void
> >> +        BroadcastEvent (lldb::EventSP &event_sp);
> >> +
> >> +        void
> >> +        BroadcastEventIfUnique (lldb::EventSP &event_sp);
> >> +
> >> +        void
> >> +        BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);
> >> +
> >> +        void
> >> +        BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr);
> >> +
> >> +        void
> >> +        Clear();
> >> +
> >> +        uint32_t
> >> +        AddListener (lldb::ListenerSP listener_sp, uint32_t event_mask);
> >> +
> >> +        const char *
> >> +        GetBroadcasterName () const
> >> +        {
> >> +            return m_broadcaster.GetBroadcasterName().AsCString();
> >> +        }
> >> +
> >> +        Broadcaster *
> >> +        GetBroadcaster();
> >> +
> >> +        bool
> >> +        GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const;
> >> +
> >> +        void
> >> +        SetEventName (uint32_t event_mask, const char *name)
> >> +        {
> >> +            m_event_names[event_mask] = name;
> >> +        }
> >> +
> >> +        const char *
> >> +        GetEventName (uint32_t event_mask) const
> >> +        {
> >> +            const auto pos = m_event_names.find (event_mask);
> >> +            if (pos != m_event_names.end())
> >> +                return pos->second.c_str();
> >> +            return nullptr;
> >> +        }
> >> +
> >> +        bool
> >> +        EventTypeHasListeners (uint32_t event_type);
> >>
> >> +        bool
> >> +        RemoveListener (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX);
> >> +
> >> +        bool
> >> +        HijackBroadcaster (lldb::ListenerSP listener_sp, uint32_t event_mask = UINT32_MAX);
> >> +
> >> +        bool
> >> +        IsHijackedForEvent (uint32_t event_mask);
> >> +
> >> +        void
> >> +        RestoreBroadcaster ();
> >> +
> >> +    protected:
> >> +        void
> >> +        PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique);
> >> +
> >> +        const char *
> >> +        GetHijackingListenerName();
> >> +
> >> +        //------------------------------------------------------------------
> >> +        //
> >> +        //------------------------------------------------------------------
> >> +        typedef std::vector< std::pair<lldb::ListenerSP,uint32_t> > collection;
> >> +        typedef std::map<uint32_t, std::string> event_names_map;
> >> +
> >> +        Broadcaster &m_broadcaster;                     ///< The broadcsater that this implements
> >> +        event_names_map m_event_names;                  ///< Optionally define event names for readability and logging for each event bit
> >> +        collection m_listeners;                         ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
> >> +        Mutex m_listeners_mutex;                        ///< A mutex that protects \a m_listeners.
> >> +        std::vector<lldb::ListenerSP> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster
> >> +        std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
> >> +                                                        // collections, but for now this is just for private hijacking.
> >> +
> >> +    private:
> >> +        //------------------------------------------------------------------
> >> +        // For Broadcaster only
> >> +        //------------------------------------------------------------------
> >> +        DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl);
> >> +    };
> >> +
> >> +    typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
> >> +    typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;
> >> +
> >> +    BroadcasterImplSP
> >> +    GetBroadcasterImpl()
> >> +    {
> >> +        return m_broadcaster_sp;
> >> +    }
> >> +
> >> +    const char *
> >> +    GetHijackingListenerName()
> >> +    {
> >> +        return m_broadcaster_sp->GetHijackingListenerName();
> >> +    }
> >>     //------------------------------------------------------------------
> >>     // Classes that inherit from Broadcaster can see and modify these
> >>     //------------------------------------------------------------------
> >> -    typedef std::vector< std::pair<Listener*,uint32_t> > collection;
> >> -    typedef std::map<uint32_t, std::string> event_names_map;
> >> -    // Prefix the name of our member variables with "m_broadcaster_"
> >> -    // since this is a class that gets subclassed.
> >> -    const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
> >> -    event_names_map m_event_names;  ///< Optionally define event names for readability and logging for each event bit
> >> -    collection m_listeners;     ///< A list of Listener / event_mask pairs that are listening to this broadcaster.
> >> -    Mutex m_listeners_mutex;    ///< A mutex that protects \a m_listeners.
> >> -    std::vector<Listener *> m_hijacking_listeners;  // A simple mechanism to intercept events from a broadcaster
> >> -    std::vector<uint32_t> m_hijacking_masks;        // At some point we may want to have a stack or Listener
> >> -                                                    // collections, but for now this is just for private hijacking.
> >> -    BroadcasterManager *m_manager;
> >> +
> >>
> >> private:
> >>     //------------------------------------------------------------------
> >>     // For Broadcaster only
> >>     //------------------------------------------------------------------
> >> +    BroadcasterImplSP m_broadcaster_sp;
> >> +    lldb::BroadcasterManagerSP m_manager_sp;
> >> +    const ConstString m_broadcaster_name;   ///< The name of this broadcaster object.
> >> +
> >>     DISALLOW_COPY_AND_ASSIGN (Broadcaster);
> >> };
> >>
> >>
> >> Modified: lldb/trunk/include/lldb/Core/Debugger.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Debugger.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Core/Debugger.h (original)
> >> +++ lldb/trunk/include/lldb/Core/Debugger.h Mon Mar  7 15:50:25 2016
> >> @@ -53,8 +53,7 @@ namespace lldb_private {
> >> class Debugger :
> >>     public std::enable_shared_from_this<Debugger>,
> >>     public UserID,
> >> -    public Properties,
> >> -    public BroadcasterManager
> >> +    public Properties
> >> {
> >> friend class SourceManager;  // For GetSourceFileCache.
> >>
> >> @@ -159,10 +158,10 @@ public:
> >>         return *m_command_interpreter_ap;
> >>     }
> >>
> >> -    Listener &
> >> +    lldb::ListenerSP
> >>     GetListener ()
> >>     {
> >> -        return m_listener;
> >> +        return m_listener_sp;
> >>     }
> >>
> >>     // This returns the Debugger's scratch source manager.  It won't be able to look up files in debug
> >> @@ -392,6 +391,12 @@ public:
> >>     Target *GetSelectedOrDummyTarget(bool prefer_dummy = false);
> >>     Target *GetDummyTarget();
> >>
> >> +    lldb::BroadcasterManagerSP
> >> +    GetBroadcasterManager()
> >> +    {
> >> +        return m_broadcaster_manager_sp;
> >> +    }
> >> +
> >> protected:
> >>     friend class CommandInterpreter;
> >>     friend class REPL;
> >> @@ -446,15 +451,20 @@ protected:
> >>
> >>     void
> >>     InstanceInitialize ();
> >> -
> >> +
> >>     lldb::StreamFileSP m_input_file_sp;
> >>     lldb::StreamFileSP m_output_file_sp;
> >>     lldb::StreamFileSP m_error_file_sp;
> >> +
> >> +    lldb::BroadcasterManagerSP m_broadcaster_manager_sp;  // The debugger acts as a broadcaster manager of last resort.
> >> +                                                          // It needs to get constructed before the target_list or any other
> >> +                                                          // member that might want to broadcast through the debugger.
> >> +
> >>     TerminalState m_terminal_state;
> >>     TargetList m_target_list;
> >>
> >>     PlatformList m_platform_list;
> >> -    Listener m_listener;
> >> +    lldb::ListenerSP m_listener_sp;
> >>     std::unique_ptr<SourceManager> m_source_manager_ap;    // This is a scratch source manager that we return if we have no targets.
> >>     SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared
> >>                                                         // source file cache.
> >>
> >> Modified: lldb/trunk/include/lldb/Core/Event.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Event.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Core/Event.h (original)
> >> +++ lldb/trunk/include/lldb/Core/Event.h Mon Mar  7 15:50:25 2016
> >> @@ -20,6 +20,7 @@
> >> #include "lldb/lldb-private.h"
> >> #include "lldb/Core/ConstString.h"
> >> #include "lldb/Host/Predicate.h"
> >> +#include "lldb/Core/Broadcaster.h"
> >>
> >> namespace lldb_private {
> >>
> >> @@ -118,9 +119,9 @@ private:
> >> //----------------------------------------------------------------------
> >> class Event
> >> {
> >> -    friend class Broadcaster;
> >>     friend class Listener;
> >>     friend class EventData;
> >> +    friend class Broadcaster::BroadcasterImpl;
> >>
> >> public:
> >>     Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data = nullptr);
> >> @@ -165,13 +166,21 @@ public:
> >>     Broadcaster *
> >>     GetBroadcaster () const
> >>     {
> >> -        return m_broadcaster;
> >> +        Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
> >> +        if (broadcaster_impl_sp)
> >> +            return broadcaster_impl_sp->GetBroadcaster();
> >> +        else
> >> +            return nullptr;
> >>     }
> >>
> >>     bool
> >>     BroadcasterIs (Broadcaster *broadcaster)
> >>     {
> >> -        return broadcaster == m_broadcaster;
> >> +        Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock();
> >> +        if (broadcaster_impl_sp)
> >> +            return broadcaster_impl_sp->GetBroadcaster() == broadcaster;
> >> +        else
> >> +            return false;
> >>     }
> >>
> >>     void
> >> @@ -194,10 +203,10 @@ private:
> >>     void
> >>     SetBroadcaster (Broadcaster *broadcaster)
> >>     {
> >> -        m_broadcaster = broadcaster;
> >> +        m_broadcaster_wp = broadcaster->GetBroadcasterImpl();
> >>     }
> >>
> >> -    Broadcaster *   m_broadcaster;  // The broadcaster that sent this event
> >> +    Broadcaster::BroadcasterImplWP   m_broadcaster_wp;  // The broadcaster that sent this event
> >>     uint32_t        m_type;         // The bit describing this event
> >>     std::unique_ptr<EventData> m_data_ap;         // User specific data for this event
> >>
> >>
> >> Modified: lldb/trunk/include/lldb/Core/Listener.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Listener.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Core/Listener.h (original)
> >> +++ lldb/trunk/include/lldb/Core/Listener.h Mon Mar  7 15:50:25 2016
> >> @@ -21,11 +21,13 @@
> >> // Project includes
> >> #include "lldb/lldb-private.h"
> >> #include "lldb/Host/Predicate.h"
> >> +#include "lldb/Core/Broadcaster.h"
> >> #include "lldb/Core/Event.h"
> >>
> >> namespace lldb_private {
> >>
> >> -class Listener
> >> +class Listener :
> >> +    public std::enable_shared_from_this<Listener>
> >> {
> >> public:
> >>     typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton);
> >> @@ -36,8 +38,16 @@ public:
> >>     //------------------------------------------------------------------
> >>     // Constructors and Destructors
> >>     //------------------------------------------------------------------
> >> +    //
> >> +    // Listeners have to be constructed into shared pointers - at least if you want them to listen to
> >> +    // Broadcasters,
> >> +protected:
> >>     Listener (const char *name);
> >>
> >> +public:
> >> +    static lldb::ListenerSP
> >> +    MakeListener(const char *name);
> >> +
> >>     ~Listener ();
> >>
> >>     void
> >> @@ -53,11 +63,11 @@ public:
> >>     }
> >>
> >>     uint32_t
> >> -    StartListeningForEventSpec (BroadcasterManager &manager,
> >> +    StartListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
> >>                                  const BroadcastEventSpec &event_spec);
> >>
> >>     bool
> >> -    StopListeningForEventSpec (BroadcasterManager &manager,
> >> +    StopListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp,
> >>                                  const BroadcastEventSpec &event_spec);
> >>
> >>     uint32_t
> >> @@ -133,9 +143,11 @@ private:
> >>         void *callback_user_data;
> >>     };
> >>
> >> -    typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection;
> >> +    typedef std::multimap<Broadcaster::BroadcasterImplWP,
> >> +                          BroadcasterInfo,
> >> +                          std::owner_less<Broadcaster::BroadcasterImplWP>> broadcaster_collection;
> >>     typedef std::list<lldb::EventSP> event_collection;
> >> -    typedef std::vector<BroadcasterManager *> broadcaster_manager_collection;
> >> +    typedef std::vector<lldb::BroadcasterManagerWP> broadcaster_manager_collection;
> >>
> >>     bool
> >>     FindNextEventInternal(Broadcaster *broadcaster,   // nullptr for any broadcaster
> >> @@ -172,7 +184,7 @@ private:
> >>     BroadcasterWillDestruct (Broadcaster *);
> >>
> >>     void
> >> -    BroadcasterManagerWillDestruct (BroadcasterManager *manager);
> >> +    BroadcasterManagerWillDestruct (lldb::BroadcasterManagerSP manager_sp);
> >>
> >>
> >> //    broadcaster_collection::iterator
> >>
> >> Modified: lldb/trunk/include/lldb/Target/Process.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Target/Process.h (original)
> >> +++ lldb/trunk/include/lldb/Target/Process.h Mon Mar  7 15:50:25 2016
> >> @@ -30,6 +30,7 @@
> >> #include "lldb/Core/Communication.h"
> >> #include "lldb/Core/Error.h"
> >> #include "lldb/Core/Event.h"
> >> +#include "lldb/Core/Listener.h"
> >> #include "lldb/Core/LoadedModuleInfoList.h"
> >> #include "lldb/Core/ThreadSafeValue.h"
> >> #include "lldb/Core/PluginInterface.h"
> >> @@ -400,7 +401,7 @@ public:
> >>         m_listener_sp = listener_sp;
> >>     }
> >>
> >> -    Listener &
> >> +    lldb::ListenerSP
> >>     GetListenerForProcess (Debugger &debugger);
> >>
> >> protected:
> >> @@ -939,13 +940,13 @@ public:
> >>     /// Construct with a shared pointer to a target, and the Process listener.
> >>     /// Uses the Host UnixSignalsSP by default.
> >>     //------------------------------------------------------------------
> >> -    Process(lldb::TargetSP target_sp, Listener &listener);
> >> +    Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp);
> >>
> >>     //------------------------------------------------------------------
> >>     /// Construct with a shared pointer to a target, the Process listener,
> >>     /// and the appropriate UnixSignalsSP for the process.
> >>     //------------------------------------------------------------------
> >> -    Process(lldb::TargetSP target_sp, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp);
> >> +    Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb::UnixSignalsSP &unix_signals_sp);
> >>
> >>     //------------------------------------------------------------------
> >>     /// Destructor.
> >> @@ -985,7 +986,7 @@ public:
> >>     static lldb::ProcessSP
> >>     FindPlugin (lldb::TargetSP target_sp,
> >>                 const char *plugin_name,
> >> -                Listener &listener,
> >> +                lldb::ListenerSP listener_sp,
> >>                 const FileSpec *crash_file_path);
> >>
> >>     //------------------------------------------------------------------
> >> @@ -2851,7 +2852,7 @@ public:
> >>     WaitForProcessToStop(const TimeValue *timeout,
> >>                          lldb::EventSP *event_sp_ptr = nullptr,
> >>                          bool wait_always = true,
> >> -                         Listener *hijack_listener = nullptr,
> >> +                         lldb::ListenerSP hijack_listener = lldb::ListenerSP(),
> >>                          Stream *stream = nullptr,
> >>                          bool use_run_lock = true);
> >>
> >> @@ -2877,7 +2878,7 @@ public:
> >>     lldb::StateType
> >>     WaitForStateChangedEvents(const TimeValue *timeout,
> >>                               lldb::EventSP &event_sp,
> >> -                              Listener *hijack_listener); // Pass nullptr to use builtin listener
> >> +                              lldb::ListenerSP hijack_listener); // Pass an empty ListenerSP to use builtin listener
> >>
> >>     //--------------------------------------------------------------------------------------
> >>     /// Centralize the code that handles and prints descriptions for process state changes.
> >> @@ -2908,10 +2909,10 @@ public:
> >>     ProcessEventHijacker
> >>     {
> >>     public:
> >> -        ProcessEventHijacker (Process &process, Listener *listener) :
> >> +        ProcessEventHijacker (Process &process, lldb::ListenerSP listener_sp) :
> >>             m_process (process)
> >>         {
> >> -            m_process.HijackProcessEvents (listener);
> >> +            m_process.HijackProcessEvents (listener_sp);
> >>         }
> >>
> >>         ~ProcessEventHijacker ()
> >> @@ -2940,7 +2941,7 @@ public:
> >>     ///     \b false otherwise.
> >>     //------------------------------------------------------------------
> >>     bool
> >> -    HijackProcessEvents (Listener *listener);
> >> +    HijackProcessEvents (lldb::ListenerSP listener_sp);
> >>
> >>     //------------------------------------------------------------------
> >>     /// Restores the process event broadcasting to its normal state.
> >> @@ -3343,7 +3344,7 @@ protected:
> >>     ThreadSafeValue<lldb::StateType>  m_private_state; // The actual state of our process
> >>     Broadcaster                 m_private_state_broadcaster;  // This broadcaster feeds state changed events into the private state thread's listener.
> >>     Broadcaster                 m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread.
> >> -    Listener                    m_private_state_listener;     // This is the listener for the private state thread.
> >> +    lldb::ListenerSP            m_private_state_listener_sp;     // This is the listener for the private state thread.
> >>     Predicate<bool>             m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete.
> >>     HostThread                  m_private_state_thread; ///< Thread ID for the thread that watches internal state events
> >>     ProcessModID                m_mod_id;               ///< Tracks the state of the process over stops and other alterations.
> >> @@ -3363,7 +3364,7 @@ protected:
> >>     uint32_t                    m_queue_list_stop_id;   ///< The natural stop id when queue list was last fetched
> >>     std::vector<Notifications>  m_notifications;        ///< The list of notifications that this process can deliver.
> >>     std::vector<lldb::addr_t>   m_image_tokens;
> >> -    Listener                    &m_listener;
> >> +    lldb::ListenerSP            m_listener_sp;          ///< Shared pointer to the listener used for public events.  Can not be empty.
> >>     BreakpointSiteList          m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target.
> >>     lldb::DynamicLoaderUP       m_dyld_ap;
> >>     lldb::JITLoaderListUP       m_jit_loaders_ap;
> >>
> >> Modified: lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h (original)
> >> +++ lldb/trunk/include/lldb/Target/ProcessLaunchInfo.h Mon Mar  7 15:50:25 2016
> >> @@ -196,7 +196,7 @@ namespace lldb_private
> >>             m_listener_sp = listener_sp;
> >>         }
> >>
> >> -        Listener &
> >> +        lldb::ListenerSP
> >>         GetListenerForProcess (Debugger &debugger);
> >>
> >>         lldb::ListenerSP
> >>
> >> Modified: lldb/trunk/include/lldb/Target/Target.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/Target/Target.h (original)
> >> +++ lldb/trunk/include/lldb/Target/Target.h Mon Mar  7 15:50:25 2016
> >> @@ -719,7 +719,7 @@ public:
> >>     Dump (Stream *s, lldb::DescriptionLevel description_level);
> >>
> >>     const lldb::ProcessSP &
> >> -    CreateProcess (Listener &listener,
> >> +    CreateProcess (lldb::ListenerSP listener,
> >>                    const char *plugin_name,
> >>                    const FileSpec *crash_file);
> >>
> >>
> >> Modified: lldb/trunk/include/lldb/lldb-forward.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-forward.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/lldb-forward.h (original)
> >> +++ lldb/trunk/include/lldb/lldb-forward.h Mon Mar  7 15:50:25 2016
> >> @@ -310,6 +310,8 @@ namespace lldb {
> >>     typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP;
> >>     typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP;
> >>     typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP;
> >> +    typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP;
> >> +    typedef std::weak_ptr<lldb_private::BroadcasterManager> BroadcasterManagerWP;
> >>     typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP;
> >>     typedef std::shared_ptr<lldb_private::ClangASTImporter> ClangASTImporterSP;
> >>     typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP;
> >>
> >> Modified: lldb/trunk/include/lldb/lldb-private-interfaces.h
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-private-interfaces.h?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/include/lldb/lldb-private-interfaces.h (original)
> >> +++ lldb/trunk/include/lldb/lldb-private-interfaces.h Mon Mar  7 15:50:25 2016
> >> @@ -35,7 +35,7 @@ namespace lldb_private
> >>     typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject) (CommandInterpreter& interpreter);
> >>     typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process);
> >>     typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch);
> >> -    typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path);
> >> +    typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path);
> >>     typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(CommandInterpreter &interpreter);
> >>     typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file);
> >>     typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm);   // Module can be NULL for default system symbol vendor
> >>
> >> Added: lldb/trunk/packages/Python/lldbsuite/test/api/listeners/Makefile
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/api/listeners/Makefile?rev=262863&view=auto
> >> ==============================================================================
> >> --- lldb/trunk/packages/Python/lldbsuite/test/api/listeners/Makefile (added)
> >> +++ lldb/trunk/packages/Python/lldbsuite/test/api/listeners/Makefile Mon Mar  7 15:50:25 2016
> >> @@ -0,0 +1,6 @@
> >> +LEVEL = ../../make
> >> +
> >> +C_SOURCES := main.c
> >> +
> >> +include $(LEVEL)/Makefile.rules
> >> +
> >>
> >> Added: lldb/trunk/packages/Python/lldbsuite/test/api/listeners/TestListener.py
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/api/listeners/TestListener.py?rev=262863&view=auto
> >> ==============================================================================
> >> --- lldb/trunk/packages/Python/lldbsuite/test/api/listeners/TestListener.py (added)
> >> +++ lldb/trunk/packages/Python/lldbsuite/test/api/listeners/TestListener.py Mon Mar  7 15:50:25 2016
> >> @@ -0,0 +1,55 @@
> >> +"""
> >> +Test that we can listen to modules loaded events.
> >> +"""
> >> +
> >> +from __future__ import print_function
> >> +
> >> +import copy
> >> +import os
> >> +import time
> >> +
> >> +import lldb
> >> +from lldbsuite.test.decorators import *
> >> +from lldbsuite.test.lldbtest import *
> >> +from lldbsuite.test import lldbutil
> >> +
> >> +import six
> >> +
> >> +class ListenToModuleLoadedEvents (TestBase):
> >> +
> >> +    mydir = TestBase.compute_mydir(__file__)
> >> +
> >> +    def setUp(self):
> >> +        # Call super's setUp().
> >> +        TestBase.setUp(self)
> >> +        self.build()
> >> +
> >> +    def test_receiving_breakpoint_added (self):
> >> +        """Test that we get breakpoint added events, waiting on event classes on the debugger"""
> >> +
> >> +        my_listener = lldb.SBListener("test_listener")
> >> +
> >> +        my_listener.StartListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
> >> +
> >> +        exe = os.path.join (os.getcwd(), "a.out")
> >> +
> >> +        target = self.dbg.CreateTarget(exe)
> >> +
> >> +        bkpt = target.BreakpointCreateByName("main")
> >> +
> >> +        event = lldb.SBEvent()
> >> +        my_listener.WaitForEvent(1, event)
> >> +
> >> +        self.assertTrue(event.IsValid(), "Got a valid event.")
> >> +        self.assertTrue(lldb.SBBreakpoint.EventIsBreakpointEvent(event), "It is a breakpoint event.")
> >> +        self.assertTrue(lldb.SBBreakpoint.GetBreakpointEventTypeFromEvent(event) == lldb.eBreakpointEventTypeAdded, "It is a breakpoint added event.")
> >> +        self.assertTrue(bkpt == lldb.SBBreakpoint.GetBreakpointFromEvent(event), "It is our breakpoint.")
> >> +
> >> +        # Now make sure if we stop listening for events we don't get them:
> >> +
> >> +        my_listener.StopListeningForEventClass(self.dbg, lldb.SBTarget.GetBroadcasterClassName(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
> >> +        my_listener.StopListeningForEvents(target.GetBroadcaster(), lldb.SBTarget.eBroadcastBitBreakpointChanged)
> >> +
> >> +        bkpt2 = target.BreakpointCreateByName("main")
> >> +        my_listener.WaitForEvent(1, event)
> >> +        self.assertTrue(not event.IsValid(), "We don't get events we aren't listening to.")
> >>
> >> Added: lldb/trunk/packages/Python/lldbsuite/test/api/listeners/main.c
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/api/listeners/main.c?rev=262863&view=auto
> >> ==============================================================================
> >> --- lldb/trunk/packages/Python/lldbsuite/test/api/listeners/main.c (added)
> >> +++ lldb/trunk/packages/Python/lldbsuite/test/api/listeners/main.c Mon Mar  7 15:50:25 2016
> >> @@ -0,0 +1,7 @@
> >> +#include <stdio.h>
> >> +
> >> +int
> >> +main()
> >> +{
> >> +    printf ("Hello there.\n");
> >> +}
> >>
> >> Modified: lldb/trunk/source/API/SBBroadcaster.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBBroadcaster.cpp?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/source/API/SBBroadcaster.cpp (original)
> >> +++ lldb/trunk/source/API/SBBroadcaster.cpp Mon Mar  7 15:50:25 2016
> >> @@ -117,14 +117,14 @@ SBBroadcaster::AddInitialEventsToListene
> >>                      static_cast<void*>(m_opaque_ptr),
> >>                      static_cast<void*>(listener.get()), requested_events);
> >>     if (m_opaque_ptr)
> >> -        m_opaque_ptr->AddInitialEventsToListener (listener.get(), requested_events);
> >> +        m_opaque_ptr->AddInitialEventsToListener (listener.m_opaque_sp, requested_events);
> >> }
> >>
> >> uint32_t
> >> SBBroadcaster::AddListener (const SBListener &listener, uint32_t event_mask)
> >> {
> >>     if (m_opaque_ptr)
> >> -        return m_opaque_ptr->AddListener (listener.get(), event_mask);
> >> +        return m_opaque_ptr->AddListener (listener.m_opaque_sp, event_mask);
> >>     return 0;
> >> }
> >>
> >> @@ -148,7 +148,7 @@ bool
> >> SBBroadcaster::RemoveListener (const SBListener &listener, uint32_t event_mask)
> >> {
> >>     if (m_opaque_ptr)
> >> -        return m_opaque_ptr->RemoveListener (listener.get(), event_mask);
> >> +        return m_opaque_ptr->RemoveListener (listener.m_opaque_sp, event_mask);
> >>     return false;
> >> }
> >>
> >>
> >> Modified: lldb/trunk/source/API/SBDebugger.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBDebugger.cpp?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/source/API/SBDebugger.cpp (original)
> >> +++ lldb/trunk/source/API/SBDebugger.cpp Mon Mar  7 15:50:25 2016
> >> @@ -432,8 +432,8 @@ SBDebugger::HandleCommand (const char *c
> >>             if (process_sp)
> >>             {
> >>                 EventSP event_sp;
> >> -                Listener &lldb_listener = m_opaque_sp->GetListener();
> >> -                while (lldb_listener.GetNextEventForBroadcaster (process_sp.get(), event_sp))
> >> +                ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
> >> +                while (lldb_listener_sp->GetNextEventForBroadcaster (process_sp.get(), event_sp))
> >>                 {
> >>                     SBEvent event(event_sp);
> >>                     HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
> >> @@ -450,7 +450,7 @@ SBDebugger::GetListener ()
> >>
> >>     SBListener sb_listener;
> >>     if (m_opaque_sp)
> >> -        sb_listener.reset(&m_opaque_sp->GetListener(), false);
> >> +        sb_listener.reset(m_opaque_sp->GetListener());
> >>
> >>     if (log)
> >>         log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)",
> >>
> >> Modified: lldb/trunk/source/API/SBListener.cpp
> >> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBListener.cpp?rev=262863&r1=262862&r2=262863&view=diff
> >> ==============================================================================
> >> --- lldb/trunk/source/API/SBListener.cpp (original)
> >> +++ lldb/trunk/source/API/SBListener.cpp Mon Mar  7 15:50:25 2016
> >> @@ -26,27 +26,25 @@ using namespace lldb_private;
> >>
> >> SBListener::SBListener () :
> >>     m_opaque_sp (),
> >> -    m_opaque_ptr (NULL)
> >> +    m_unused_ptr (NULL)
> >> {
> >> }
> >>
> >> SBListener::SBListener (const char *name) :
> >> -    m_opaque_sp (new Listener (name)),
> >> -    m_opaque_ptr (NULL)
> >> +    m_opaque_sp (Listener::MakeListener(name)),
> >> +    m_unused_ptr (nullptr)
> >> {
> >> -    m_opaque_ptr = m_opaque_sp.get();
> >> -
> >>     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
> >>
> >>     if (log)
> >>         log->Printf ("SBListener::SBListener (name=\"%s\") => SBListener(%p)",
> >> -                     name, static_cast<void*>(m_opaque_ptr));
> >> +                     name, static_cast<void*>(m_opaque_sp.get()));
> >> }
> >>
> >>
> >> SBListener::SBListener (const SBListener &rhs) :
> >>     m_opaque_sp (rhs.m_opaque_sp),
> >> -    m_opaque_ptr (rhs.m_opaque_ptr)
> >> +    m_unused_ptr (nullptr)
> >> {
> >> }
> >>
> >> @@ -56,20 +54,14 @@ SBListener::operator = (const lldb::SBLi
> >>     if (this != &rhs)
> >>     {
> >>         m_opaque_sp = rhs.m_opaque_sp;
> >> -        m_opaque_ptr = rhs.m_opaque_ptr;
> >> +        m_unused_ptr = nullptr;
> >>     }
> >>     return *this;
> >> }
> >>
> >> -SBListener::SBListener (Listener &listener) :
> >> -    m_opaque_sp (),
> >> -    m_opaque_ptr (&listener)
> >> -{
> >> -}
> >> -
> >> SBListener::SBListener (const lldb::ListenerSP &listener_sp) :
> >>     m_opaque_sp (listener_sp),
> >> -    m_opaque_ptr (listener_sp.get())
> >> +    m_unused_ptr (nullptr)
> >> {
> >> }
> >>
> >> @@ -80,7 +72,7 @@ SBListener::~SBListener ()
> >> bool
> >> SBListener::IsValid() const
> >> {
> >> -    return m_opaque_ptr != NULL;
> >> +    return m_opaque_sp != nullptr;
> >> }
> >>
> >> void
> >> @@ -88,14 +80,14 @@ SBListener::AddEvent (const SBEvent &eve
> >> {
> >>     EventSP &event_sp = event.GetSP ();
> >>     if (event_sp)
> >> -        m_opaque_ptr->AddEvent (event_sp);
> >> +        m_opaque_sp->AddEvent (event_sp);
> >> }
> >>
> >> void
> >> SBListener::Clear ()
> >> {
> >> -    if (m_opaque_ptr)
> >> -        m_opaque_ptr->Clear ();
> >> +    if (m_opaque_sp)
> >> +        m_opaque_sp->Clear ();
> >> }
> >>
> >> uint32_t
> >> @@ -103,13 +95,13 @@ SBListener::StartListeningForEventClass
> >>                              const char *broadcaster_class,
> >>                              uint32_t event_mask)
> >> {
> >> -    if (m_opaque_ptr)
> >> +    if (m_opaque_sp)
> >>     {
> >>         Debugger *lldb_debugger = debugger.get();
> >>         if (!lldb_debugger)
> >>             return 0;
> >>         BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
> >> -        return m_opaque_ptr->StartListeningForEventSpec (*lldb_debugger, event_spec);
> >> +        return m_opaque_sp->StartListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
> >>     }
> >>     else
> >>         return 0;
> >> @@ -120,13 +112,13 @@ SBListener::StopListeningForEventClass (
> >>                             const char *broadcaster_class,
> >>                             uint32_t event_mask)
> >> {
> >> -    if (m_opaque_ptr)
> >> +    if (m_opaque_sp)
> >>     {
> >>         Debugger *lldb_debugger = debugger.get();
> >>         if (!lldb_debugger)
> >>             return false;
> >>         BroadcastEventSpec event_spec (ConstString (broadcaster_class), event_mask);
> >> -        return m_opaque_ptr->StopListeningForEventSpec (*lldb_debugger, event_spec);
> >> +        return m_opaque_sp->StopListeningForEventSpec (lldb_debugger->GetBroadcasterManager(), event_spec);
> >>     }
> >>     else
> >>         return false;
> >> @@ -136,9 +128,9 @@ uint32_t
> >> SBListener::StartListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
> >> {
> >>     uint32_t acquired_event_mask = 0;
> >> -    if (m_opaque_ptr && broadcaster.IsValid())
> >> +    if (m_opaque_sp && broadcaster.IsValid())
> >>     {
> >> -        acquired_event_mask = m_opaque_ptr->StartListeningForEvents (broadcaster.get(), event_mask);
> >> +        acquired_event_mask = m_opaque_sp->StartListeningForEvents (broadcaster.get(), event_mask);
> >>     }
> >>
> >>     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
> >> @@ -153,7 +145,7 @@ SBListener::StartListeningForEvents (con
> >>             const bool got_requested_names = lldb_broadcaster->GetEventNames (sstr_requested, event_mask, false);
> >>             const bool got_acquired_names = lldb_broadcaster->GetEventNames (sstr_acquired, acquired_event_mask, false);
> >>             log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p): %s, event_mask=0x%8.8x%s%s%s) => 0x%8.8x%s%s%s",
> >> -                         static_cast<void*>(m_opaque_ptr),
> >> +                         static_cast<void*>(m_opaque_sp.get()),
> >>                          static_cast<void*>(lldb_broadcaster),
> >>                          lldb_broadcaster->GetBroadcasterName().GetCString(),
> >>                          event_mask,
> >> @@ -168,7 +160,7 @@ SBListener::StartListeningForEvents (con
> >>         else
> >>         {
> >>             log->Printf ("SBListener(%p)::StartListeneingForEvents (SBBroadcaster(%p), event_mask=0x%8.8x) => 0x%8.8x",
> >> -                         static_cast<void*>(m_opaque_ptr),
> >> +                         static_cast<void*>(m_opaque_sp.get()),
> >>                          static_cast<void*>(lldb_broadcaster), event_mask,
> >>                          acquired_event_mask);
> >>         }
> >> @@ -180,9 +172,9 @@ SBListener::StartListeningForEvents (con
> >> bool
> >> SBListener::StopListeningForEvents (const SBBroadcaster& broadcaster, uint32_t event_mask)
> >> {
> >> -    if (m_opaque_ptr && broadcaster.IsValid())
> >> +    if (m_opaque_sp && broadcaster.IsValid())
> >>     {
> >> -        return m_opaque_ptr->StopListeningForEvents (broadcaster.get(), event_mask);
> >> +        return m_opaque_sp->StopListeningForEvents (broadcaster.get(), event_mask);
> >>     }
> >>     return false;
> >> }
> >> @@ -196,19 +188,19 @@ SBListener::WaitForEvent (uint32_t timeo
> >>         if (timeout_secs == UINT32_MAX)
> >>         {
> >>             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p))...",
> >> -                         static_cast<void*>(m_opaque_ptr),
> >> +                         static_cast<void*>(m_opaque_sp.get()),
> >>                          static_cast<void*>(event.get()));
> >>         }
> >>         else
> >>         {
> >>             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p))...",
> >> -                         static_cast<void*>(m_opaque_ptr), timeout_secs,
> >> +                         static_cast<void*>(m_opaque_sp.get()), timeout_secs,
> >>                          static_cast<void*>(event.get()));
> >>         }
> >>     }
> >>     bool success = false;
> >>
> >> -    if (m_opaque_ptr)
> >> +    if (m_opaque_sp)
> >>     {
> >>         TimeValue time_value;
> >>         if (timeout_secs != UINT32_MAX)
> >> @@ -218,7 +210,7 @@ SBListener::WaitForEvent (uint32_t timeo
> >>             time_value.OffsetWithSeconds (timeout_secs);
> >>         }
> >>         EventSP event_sp;
> >> -        if (m_opaque_ptr->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
> >> +        if (m_opaque_sp->WaitForEvent (time_value.IsValid() ? &time_value : NULL, event_sp))
> >>         {
> >>             event.reset (event_sp);
> >>             success = true;
> >> @@ -230,13 +222,13 @@ SBListener::WaitForEvent (uint32_t timeo
> >>         if (timeout_secs == UINT32_MAX)
> >>         {
> >>             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=INFINITE, SBEvent(%p)) => %i",
> >> -                         static_cast<void*>(m_opaque_ptr),
> >> +                         static_cast<void*>(m_opaque_sp.get()),
> >>                          static_cast<void*>(event.get()), success);
> >>         }
> >>         else
> >>         {
> >>             log->Printf ("SBListener(%p)::WaitForEvent (timeout_secs=%d, SBEvent(%p)) => %i",
> >> -                         static_cast<void*>(m_opaque_ptr), timeout_secs,
> >> +                         static_cast<void*>(m_opaque_sp.get()), timeout_secs,
> >>                          static_cast<void*>(event.get()), success);
> >>         }
> >>     }
> >> @@ -253,7 +245,7 @@ SBListener::WaitForEventForBroadcaster
> >>     SBEvent &event
> >> )
> >> {
> >> -    if (m_opaque_ptr && broadcaster.IsValid())
> >> +    if (m_opaque_sp && broadcaster.IsValid())
> >>     {
> >>         TimeValue time_value;
> >>         if (num_seconds != UINT32_MAX)
> >> @@ -262,7 +254,7 @@ SBListener::WaitForEventForBroadcaster
> >>             time_value.OffsetWithSeconds (num_seconds);
> >>         }
> >>         EventSP event_sp;
> >> -        if (m_opaque_ptr->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
> >> +        if (m_opaque_sp->WaitForEventForBroadcaster (time_value.IsValid() ? &time_value : NULL,
> >>                                                          broadcaster.get(),
> >>                                                          event_sp))
> >>         {
> >> @@ -284,7 +276,7 @@ SBListener::WaitForEventForBroadcasterWi
> >>     SBEvent &event
> >> )
> >> {
> >> -    if (m_opaque_ptr && broadcaster.IsValid())
> >> +    if (m_opaque_sp && broadcaster.IsValid())
> >>     {
> >>         TimeValue time_value;
> >>         if (num_seconds != UINT32_MAX)
> >> @@ -293,7 +285,7 @@ SBListener::WaitForEventForBroadcasterWi
> >>             time_value.OffsetWithSeconds (num_seconds);
> >>         }
> >>         EventSP event_sp;
> >> -        if (m_opaque_ptr->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
> >> +        if (m_opaque_sp->WaitForEventForBroadcasterWithType (time_value.IsValid() ? &time_value : NULL,
> >>



More information about the lldb-commits mailing list