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

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 8 05:39:13 PST 2016


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,
> >>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160308/b77ab7ff/attachment-0001.html>


More information about the lldb-commits mailing list