diff options
author | Jim Ingham <jingham@apple.com> | 2016-03-07 21:50:25 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2016-03-07 21:50:25 +0000 |
commit | 583bbb1dd46e1665c2d5f31d4e4772bf6207c1c0 (patch) | |
tree | 08371c4b8334ea4e9a7f1ce3d29420712fd7949a /lldb/source/Target/Process.cpp | |
parent | 2a831fb8264e6a53a8b08b90107f3b176c152db2 (diff) | |
download | bcm5719-llvm-583bbb1dd46e1665c2d5f31d4e4772bf6207c1c0.tar.gz bcm5719-llvm-583bbb1dd46e1665c2d5f31d4e4772bf6207c1c0.zip |
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
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r-- | lldb/source/Target/Process.cpp | 118 |
1 files changed, 61 insertions, 57 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index f9befad1986..d138d4ae8e2 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -657,7 +657,7 @@ ProcessInstanceInfoMatch::Clear() } 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 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener 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 @@ Process::FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, Listener { 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 @@ Process::GetStaticBroadcasterClass () 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 @@ Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignals 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 @@ Process::Process(lldb::TargetSP target_sp, Listener &listener, const UnixSignals 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 @@ Process::Finalize() //#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 @@ Process::Finalize() // 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 @@ Process::GetNextEvent (EventSP &event_sp) { 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 @@ StateType 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 @@ Process::WaitForProcessToStop (const TimeValue *timeout, __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 @@ Process::WaitForProcessToStop (const TimeValue *timeout, 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 @@ Process::WaitForProcessToStop (const TimeValue *timeout, 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 @@ Process::WaitForProcessToStop (const TimeValue *timeout, { // 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 @@ Process::WaitForState(const TimeValue *timeout, } 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 @@ Process::RestoreProcessEvents () } 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 @@ Process::WaitForStateChangedEvents (const TimeValue *timeout, EventSP &event_sp, 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 @@ Process::PeekAtStateChangedEvents () 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 @@ Process::WaitForStateChangedEventsPrivate (const TimeValue *timeout, EventSP &ev 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 @@ Process::WaitForEventsPrivate (const TimeValue *timeout, EventSP &event_sp, bool 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 @@ Process::StateChangedIsExternallyHijacked() { 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 @@ Process::ResumeSynchronous (Stream *stream) 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 @@ Process::LoadCore () 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 @@ Process::LoadCore () // 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 @@ Process::AttachCompletionHandler::GetExitString () 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 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock) // 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 @@ Process::Halt (bool clear_thread_plans, bool use_run_lock) 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 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) 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 @@ Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp) 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, // 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, } 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 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx, 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) { |