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
llvm-svn: 262863
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index f9befad..d138d4a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -657,7 +657,7 @@
 }
 
 ProcessSP
-Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener &listener, const FileSpec *crash_file_path)
+Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, ListenerSP listener_sp, const FileSpec *crash_file_path)
 {
     static uint32_t g_process_unique_id = 0;
 
@@ -669,7 +669,7 @@
         create_callback  = PluginManager::GetProcessCreateCallbackForPluginName (const_plugin_name);
         if (create_callback)
         {
-            process_sp = create_callback(target_sp, listener, crash_file_path);
+            process_sp = create_callback(target_sp, listener_sp, crash_file_path);
             if (process_sp)
             {
                 if (process_sp->CanDebug(target_sp, true))
@@ -685,7 +685,7 @@
     {
         for (uint32_t idx = 0; (create_callback = PluginManager::GetProcessCreateCallbackAtIndex(idx)) != nullptr; ++idx)
         {
-            process_sp = create_callback(target_sp, listener, crash_file_path);
+            process_sp = create_callback(target_sp, listener_sp, crash_file_path);
             if (process_sp)
             {
                 if (process_sp->CanDebug(target_sp, false))
@@ -708,23 +708,23 @@
     return class_name;
 }
 
-Process::Process(lldb::TargetSP target_sp, Listener &listener) :
-    Process(target_sp, listener, UnixSignals::Create(HostInfo::GetArchitecture()))
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) :
+    Process(target_sp, listener_sp, UnixSignals::Create(HostInfo::GetArchitecture()))
 {
     // This constructor just delegates to the full Process constructor,
     // defaulting to using the Host's UnixSignals.
 }
 
-Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignalsSP &unix_signals_sp) :
+Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, const UnixSignalsSP &unix_signals_sp) :
     ProcessProperties (this),
     UserID (LLDB_INVALID_PROCESS_ID),
-    Broadcaster (&(target_sp->GetDebugger()), Process::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster ((target_sp->GetDebugger().GetBroadcasterManager()), Process::GetStaticBroadcasterClass().AsCString()),
     m_target_sp (target_sp),
     m_public_state (eStateUnloaded),
     m_private_state (eStateUnloaded),
     m_private_state_broadcaster(nullptr, "lldb.process.internal_state_broadcaster"),
     m_private_state_control_broadcaster(nullptr, "lldb.process.internal_state_control_broadcaster"),
-    m_private_state_listener ("lldb.process.internal_state_listener"),
+    m_private_state_listener_sp (Listener::MakeListener("lldb.process.internal_state_listener")),
     m_private_state_control_wait(),
     m_mod_id (),
     m_process_unique_id(0),
@@ -742,7 +742,7 @@
     m_queue_list_stop_id (0),
     m_notifications (),
     m_image_tokens (),
-    m_listener (listener),
+    m_listener_sp (listener_sp),
     m_breakpoint_site_list (),
     m_dynamic_checkers_ap (),
     m_unix_signals_sp (unix_signals_sp),
@@ -792,18 +792,18 @@
     m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" );
     m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume");
 
-    listener.StartListeningForEvents (this,
+    m_listener_sp->StartListeningForEvents (this,
                                       eBroadcastBitStateChanged |
                                       eBroadcastBitInterrupt |
                                       eBroadcastBitSTDOUT |
                                       eBroadcastBitSTDERR |
                                       eBroadcastBitProfileData);
 
-    m_private_state_listener.StartListeningForEvents(&m_private_state_broadcaster,
+    m_private_state_listener_sp->StartListeningForEvents(&m_private_state_broadcaster,
                                                      eBroadcastBitStateChanged |
                                                      eBroadcastBitInterrupt);
 
-    m_private_state_listener.StartListeningForEvents(&m_private_state_control_broadcaster,
+    m_private_state_listener_sp->StartListeningForEvents(&m_private_state_control_broadcaster,
                                                      eBroadcastInternalStateControlStop |
                                                      eBroadcastInternalStateControlPause |
                                                      eBroadcastInternalStateControlResume);
@@ -904,7 +904,7 @@
 //#ifdef LLDB_CONFIGURATION_DEBUG
 //    StreamFile s(stdout, false);
 //    EventSP event_sp;
-//    while (m_private_state_listener.GetNextEvent(event_sp))
+//    while (m_private_state_listener_sp->GetNextEvent(event_sp))
 //    {
 //        event_sp->Dump (&s);
 //        s.EOL();
@@ -913,7 +913,7 @@
     // We have to be very careful here as the m_private_state_listener might
     // contain events that have ProcessSP values in them which can keep this
     // process around forever. These events need to be cleared out.
-    m_private_state_listener.Clear();
+    m_private_state_listener_sp->Clear();
     m_public_run_lock.TrySetRunning(); // This will do nothing if already locked
     m_public_run_lock.SetStopped();
     m_private_run_lock.TrySetRunning(); // This will do nothing if already locked
@@ -970,7 +970,7 @@
 {
     StateType state = eStateInvalid;
 
-    if (m_listener.GetNextEventForBroadcaster (this, event_sp) && event_sp)
+    if (m_listener_sp->GetNextEventForBroadcaster (this, event_sp) && event_sp)
         state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
 
     return state;
@@ -997,7 +997,7 @@
 Process::WaitForProcessToStop (const TimeValue *timeout,
                                EventSP *event_sp_ptr,
                                bool wait_always,
-                               Listener *hijack_listener,
+                               ListenerSP hijack_listener_sp,
                                Stream *stream,
                                bool use_run_lock)
 {
@@ -1026,7 +1026,7 @@
                         __FUNCTION__);
         // We need to toggle the run lock as this won't get done in
         // SetPublicState() if the process is hijacked.
-        if (hijack_listener && use_run_lock)
+        if (hijack_listener_sp && use_run_lock)
             m_public_run_lock.SetStopped();
         return state;
     }
@@ -1034,11 +1034,11 @@
     while (state != eStateInvalid)
     {
         EventSP event_sp;
-        state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener);
+        state = WaitForStateChangedEvents (timeout, event_sp, hijack_listener_sp);
         if (event_sp_ptr && event_sp)
             *event_sp_ptr = event_sp;
 
-        bool pop_process_io_handler = hijack_listener != nullptr;
+        bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr);
         Process::HandleProcessStateChangedEvent (event_sp, stream, pop_process_io_handler);
 
         switch (state)
@@ -1049,7 +1049,7 @@
         case eStateUnloaded:
             // We need to toggle the run lock as this won't get done in
             // SetPublicState() if the process is hijacked.
-            if (hijack_listener && use_run_lock)
+            if (hijack_listener_sp && use_run_lock)
                 m_public_run_lock.SetStopped();
             return state;
         case eStateStopped:
@@ -1059,7 +1059,7 @@
             {
                 // We need to toggle the run lock as this won't get done in
                 // SetPublicState() if the process is hijacked.
-                if (hijack_listener && use_run_lock)
+                if (hijack_listener_sp && use_run_lock)
                     m_public_run_lock.SetStopped();
                 return state;
             }
@@ -1295,11 +1295,11 @@
 }
 
 bool
-Process::HijackProcessEvents (Listener *listener)
+Process::HijackProcessEvents (ListenerSP listener_sp)
 {
-    if (listener != nullptr)
+    if (listener_sp)
     {
-        return HijackBroadcaster(listener, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
+        return HijackBroadcaster(listener_sp, eBroadcastBitStateChanged | eBroadcastBitInterrupt);
     }
     else
         return false;
@@ -1312,7 +1312,7 @@
 }
 
 StateType
-Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, Listener *hijack_listener)
+Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, ListenerSP hijack_listener_sp)
 {
     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
 
@@ -1320,15 +1320,15 @@
         log->Printf ("Process::%s (timeout = %p, event_sp)...", __FUNCTION__,
                      static_cast<const void*>(timeout));
 
-    Listener *listener = hijack_listener;
-    if (listener == nullptr)
-        listener = &m_listener;
+    ListenerSP listener_sp = hijack_listener_sp;
+    if (!listener_sp)
+        listener_sp = m_listener_sp;
 
     StateType state = eStateInvalid;
-    if (listener->WaitForEventForBroadcasterWithType (timeout,
-                                                      this,
-                                                      eBroadcastBitStateChanged | eBroadcastBitInterrupt,
-                                                      event_sp))
+    if (listener_sp->WaitForEventForBroadcasterWithType (timeout,
+                                                         this,
+                                                         eBroadcastBitStateChanged | eBroadcastBitInterrupt,
+                                                         event_sp))
     {
         if (event_sp && event_sp->GetType() == eBroadcastBitStateChanged)
             state = Process::ProcessEventData::GetStateFromEvent(event_sp.get());
@@ -1352,7 +1352,7 @@
         log->Printf ("Process::%s...", __FUNCTION__);
 
     Event *event_ptr;
-    event_ptr = m_listener.PeekAtNextEventForBroadcasterWithType (this,
+    event_ptr = m_listener_sp->PeekAtNextEventForBroadcasterWithType (this,
                                                                   eBroadcastBitStateChanged);
     if (log)
     {
@@ -1381,7 +1381,7 @@
                      static_cast<const void*>(timeout));
 
     StateType state = eStateInvalid;
-    if (m_private_state_listener.WaitForEventForBroadcasterWithType (timeout,
+    if (m_private_state_listener_sp->WaitForEventForBroadcasterWithType (timeout,
                                                                      &m_private_state_broadcaster,
                                                                      eBroadcastBitStateChanged | eBroadcastBitInterrupt,
                                                                      event_sp))
@@ -1408,9 +1408,9 @@
                      static_cast<const void*>(timeout));
 
     if (control_only)
-        return m_private_state_listener.WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
+        return m_private_state_listener_sp->WaitForEventForBroadcaster(timeout, &m_private_state_control_broadcaster, event_sp);
     else
-        return m_private_state_listener.WaitForEvent(timeout, event_sp);
+        return m_private_state_listener_sp->WaitForEvent(timeout, event_sp);
 }
 
 bool
@@ -1690,7 +1690,8 @@
 {
     if (IsHijackedForEvent(eBroadcastBitStateChanged))
     {
-        if (strcmp(m_hijacking_listeners.back()->GetName(), "lldb.Process.ResumeSynchronous.hijack"))
+        const char *hijacking_name = GetHijackingListenerName();
+        if (hijacking_name && strcmp(hijacking_name, "lldb.Process.ResumeSynchronous.hijack"))
             return true;
     }
     return false;
@@ -1763,13 +1764,13 @@
         return error;
     }
 
-    ListenerSP listener_sp (new Listener("lldb.Process.ResumeSynchronous.hijack"));
-    HijackProcessEvents(listener_sp.get());
+    ListenerSP listener_sp (Listener::MakeListener("lldb.Process.ResumeSynchronous.hijack"));
+    HijackProcessEvents(listener_sp);
 
     Error error = PrivateResume();
     if (error.Success())
     {
-        StateType state = WaitForProcessToStop(nullptr, nullptr, true, listener_sp.get(), stream);
+        StateType state = WaitForProcessToStop (NULL, NULL, true, listener_sp, stream);
         const bool must_be_alive = false; // eStateExited is ok, so this must be false
         if (!StateIsStoppedState(state, must_be_alive))
             error.SetErrorStringWithFormat("process not in stopped state after synchronous resume: %s", StateAsCString(state));
@@ -3065,8 +3066,8 @@
     Error error = DoLoadCore();
     if (error.Success())
     {
-        Listener listener ("lldb.process.load_core_listener");
-        HijackProcessEvents(&listener);
+        ListenerSP listener_sp (Listener::MakeListener("lldb.process.load_core_listener"));
+        HijackProcessEvents(listener_sp);
 
         if (PrivateStateThreadIsValid ())
             ResumePrivateStateThread ();
@@ -3091,7 +3092,7 @@
 
         // Wait indefinitely for a stopped event since we just posted one above...
         lldb::EventSP event_sp;
-        listener.WaitForEvent(nullptr, event_sp);
+        listener_sp->WaitForEvent (nullptr, event_sp);
         StateType state = ProcessEventData::GetStateFromEvent(event_sp.get());
 
         if (!StateIsStoppedState (state, false))
@@ -3216,10 +3217,13 @@
     return m_exit_string.c_str();
 }
 
-Listener &
+ListenerSP
 ProcessAttachInfo::GetListenerForProcess (Debugger &debugger)
 {
-    return (m_listener_sp ? *m_listener_sp : debugger.GetListener());
+    if (m_listener_sp)
+        return m_listener_sp;
+    else
+        return debugger.GetListener();
 }
 
 Error
@@ -3599,8 +3603,8 @@
     // own.
     m_clear_thread_plans_on_stop |= clear_thread_plans;
     
-    Listener halt_listener ("lldb.process.halt_listener");
-    HijackProcessEvents(&halt_listener);
+    ListenerSP halt_listener_sp (Listener::MakeListener("lldb.process.halt_listener"));
+    HijackProcessEvents(halt_listener_sp);
 
     EventSP event_sp;
     
@@ -3620,7 +3624,7 @@
     TimeValue timeout_time;
     timeout_time = TimeValue::Now();
     timeout_time.OffsetWithSeconds(10);
-    StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, &halt_listener,
+    StateType state = WaitForProcessToStop(&timeout_time, &event_sp, true, halt_listener_sp,
                                            nullptr, use_run_lock);
     RestoreProcessEvents();
 
@@ -3645,8 +3649,8 @@
         if (log)
             log->Printf("Process::%s() About to stop.", __FUNCTION__);
 
-        ListenerSP listener_sp (new Listener("lldb.Process.StopForDestroyOrDetach.hijack"));
-        HijackProcessEvents(listener_sp.get());
+        ListenerSP listener_sp (Listener::MakeListener("lldb.Process.StopForDestroyOrDetach.hijack"));
+        HijackProcessEvents(listener_sp);
 
         SendAsyncInterrupt();
 
@@ -3654,7 +3658,7 @@
         TimeValue timeout (TimeValue::Now());
         timeout.OffsetWithSeconds(10);
 
-        StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp.get());
+        StateType state = WaitForProcessToStop (&timeout, &exit_event_sp, true, listener_sp);
 
         RestoreProcessEvents();
 
@@ -5323,7 +5327,7 @@
         return eExpressionStoppedForDebug;
     }
 
-    Listener listener("lldb.process.listener.run-thread-plan");
+    ListenerSP listener_sp(Listener::MakeListener("lldb.process.listener.run-thread-plan"));
 
     lldb::EventSP event_to_broadcast_sp;
 
@@ -5334,7 +5338,7 @@
         // If the event needs to propagate beyond the hijacker (e.g., the process exits during execution), then the event
         // is put into event_to_broadcast_sp for rebroadcasting.
 
-        ProcessEventHijacker run_thread_plan_hijacker (*this, &listener);
+        ProcessEventHijacker run_thread_plan_hijacker (*this, listener_sp);
 
         if (log)
         {
@@ -5424,7 +5428,7 @@
         // Are there cases where we might want to run the remaining events here, and then try to
         // call the function?  That's probably being too tricky for our own good.
 
-        Event *other_events = listener.PeekAtNextEvent();
+        Event *other_events = listener_sp->PeekAtNextEvent();
         if (other_events != nullptr)
         {
             errors.Printf("Calling RunThreadPlan with pending events on the queue.");
@@ -5483,7 +5487,7 @@
                 TimeValue resume_timeout = TimeValue::Now();
                 resume_timeout.OffsetWithMicroSeconds(500000);
 
-                got_event = listener.WaitForEvent(&resume_timeout, event_sp);
+                got_event = listener_sp->WaitForEvent(&resume_timeout, event_sp);
                 if (!got_event)
                 {
                     if (log)
@@ -5605,7 +5609,7 @@
             }
             else
 #endif
-            got_event = listener.WaitForEvent (timeout_ptr, event_sp);
+            got_event = listener_sp->WaitForEvent (timeout_ptr, event_sp);
 
             if (got_event)
             {
@@ -5805,7 +5809,7 @@
                         real_timeout = TimeValue::Now();
                         real_timeout.OffsetWithMicroSeconds(500000);
 
-                        got_event = listener.WaitForEvent(&real_timeout, event_sp);
+                        got_event = listener_sp->WaitForEvent(&real_timeout, event_sp);
 
                         if (got_event)
                         {
diff --git a/lldb/source/Target/ProcessLaunchInfo.cpp b/lldb/source/Target/ProcessLaunchInfo.cpp
index 3102036..c9c53e9 100644
--- a/lldb/source/Target/ProcessLaunchInfo.cpp
+++ b/lldb/source/Target/ProcessLaunchInfo.cpp
@@ -517,11 +517,11 @@
     return false;
 }
 
-Listener &
+ListenerSP
 ProcessLaunchInfo::GetListenerForProcess (Debugger &debugger)
 {
     if (m_listener_sp)
-        return *m_listener_sp;
+        return m_listener_sp;
     else
         return debugger.GetListener();
 }
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 7455c20..acb84e5 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -70,7 +70,7 @@
 
 Target::Target(Debugger &debugger, const ArchSpec &target_arch, const lldb::PlatformSP &platform_sp, bool is_dummy_target) :
     TargetProperties (this),
-    Broadcaster (&debugger, Target::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster (debugger.GetBroadcasterManager(), Target::GetStaticBroadcasterClass().AsCString()),
     ExecutionContextScope (),
     m_debugger (debugger),
     m_platform_sp (platform_sp),
@@ -194,10 +194,10 @@
 }
 
 const lldb::ProcessSP &
-Target::CreateProcess (Listener &listener, const char *plugin_name, const FileSpec *crash_file)
+Target::CreateProcess (ListenerSP listener_sp, const char *plugin_name, const FileSpec *crash_file)
 {
     DeleteCurrentProcess ();
-    m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener, crash_file);
+    m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file);
     return m_process_sp;
 }
 
@@ -3072,12 +3072,12 @@
             ListenerSP hijack_listener_sp (launch_info.GetHijackListener());
             if (!hijack_listener_sp)
             {
-                hijack_listener_sp.reset(new Listener("lldb.Target.Launch.hijack"));
+                hijack_listener_sp = Listener::MakeListener("lldb.Target.Launch.hijack");
                 launch_info.SetHijackListener(hijack_listener_sp);
-                m_process_sp->HijackProcessEvents(hijack_listener_sp.get());
+                m_process_sp->HijackProcessEvents(hijack_listener_sp);
             }
 
-            StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp.get(), nullptr);
+            StateType state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, false, hijack_listener_sp, nullptr);
             
             if (state == eStateStopped)
             {
@@ -3088,7 +3088,7 @@
                         error = m_process_sp->PrivateResume();
                         if (error.Success())
                         {
-                            state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp.get(), stream);
+                            state = m_process_sp->WaitForProcessToStop(nullptr, nullptr, true, hijack_listener_sp, stream);
                             const bool must_be_alive = false; // eStateExited is ok, so this must be false
                             if (!StateIsStoppedState(state, must_be_alive))
                             {
@@ -3182,7 +3182,7 @@
     const bool async = attach_info.GetAsync();
     if (!async)
     {
-        hijack_listener_sp.reset (new Listener ("lldb.Target.Attach.attach.hijack"));
+        hijack_listener_sp = Listener::MakeListener("lldb.Target.Attach.attach.hijack");
         attach_info.SetHijackListener (hijack_listener_sp);
     }
 
@@ -3205,7 +3205,7 @@
             }
         }
         if (hijack_listener_sp)
-            process_sp->HijackProcessEvents (hijack_listener_sp.get ());
+            process_sp->HijackProcessEvents (hijack_listener_sp);
         error = process_sp->Attach (attach_info);
     }
 
@@ -3217,7 +3217,7 @@
         }
         else
         {
-            state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener ().get (), stream);
+            state = process_sp->WaitForProcessToStop (nullptr, nullptr, false, attach_info.GetHijackListener(), stream);
             process_sp->RestoreProcessEvents ();
 
             if (state != eStateStopped)
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index ffec758..5f1a439 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -43,7 +43,7 @@
 // TargetList constructor
 //----------------------------------------------------------------------
 TargetList::TargetList(Debugger &debugger) :
-    Broadcaster(&debugger, TargetList::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster(debugger.GetBroadcasterManager(), TargetList::GetStaticBroadcasterClass().AsCString()),
     m_target_list(),
     m_target_list_mutex (Mutex::eMutexTypeRecursive),
     m_selected_target_idx (0)
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index fd3df8f..b455094 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -274,7 +274,7 @@
 Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) :
     ThreadProperties (false),
     UserID (tid),
-    Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()),
+    Broadcaster(process.GetTarget().GetDebugger().GetBroadcasterManager(), Thread::GetStaticBroadcasterClass().AsCString()),
     m_process_wp (process.shared_from_this()),
     m_stop_info_sp (),
     m_stop_info_stop_id (0),