From 35a4cc5ea7020fbefd5f328a47d944b15cbda246 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 29 Oct 2012 20:52:08 +0000 Subject: [PATCH] I tracked down a leak that could happen when detaching from a process where the lldb_private::Process objects would stay around forever. This was caused by a eStateDetached event that was queued up on the lldb_private::Process private state thread listener. Since process events contain shared pointers to the process, this is dangerous if they don't get consume or cleared as having the lldb_private::Process class contain a collection of things that have a shared pointer to yourself is obviously bad. To fix this I modified the Process::Finalize() function to clear this list. The actual thing that was holding onto the ModuleSP and thus the static archive, was a stack frame. Since the process wasn't going away, it still had thread objects and they still had frames. I modified the Thread::Destroy() to clear the stack frames to ensure this further doesn't happen. llvm-svn: 166964 --- .../BSD-Archive/ObjectContainerBSDArchive.h | 3 +-- lldb/source/Target/Process.cpp | 26 +++++++++++++++++++--- lldb/source/Target/Thread.cpp | 7 +++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index 3e893073..ce245b1 100644 --- a/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -108,7 +108,6 @@ protected: uint32_t ar_size; // size in bytes uint32_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data uint32_t ar_file_size; // length of the object data - lldb::ObjectFileSP object_file_sp; typedef std::vector collection; typedef collection::iterator iterator; @@ -177,7 +176,7 @@ protected: //---------------------------------------------------------------------- lldb_private::ArchSpec m_arch; lldb_private::TimeValue m_time; - Object::collection m_objects; + Object::collection m_objects; lldb_private::UniqueCStringMap m_object_name_to_index_map; }; diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1f975c4..7372832 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -973,6 +973,10 @@ Process::Process(Target &target, Listener &listener) : SetEventName (eBroadcastBitSTDOUT, "stdout-available"); SetEventName (eBroadcastBitSTDERR, "stderr-available"); + m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlStop , "control-stop" ); + m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlPause , "control-pause" ); + m_private_state_control_broadcaster.SetEventName (eBroadcastInternalStateControlResume, "control-resume"); + listener.StartListeningForEvents (this, eBroadcastBitStateChanged | eBroadcastBitInterrupt | @@ -1055,6 +1059,19 @@ Process::Finalize() m_allocated_memory_cache.Clear(); m_language_runtimes.clear(); m_next_event_action_ap.reset(); +//#ifdef LLDB_CONFIGURATION_DEBUG +// StreamFile s(stdout, false); +// EventSP event_sp; +// while (m_private_state_listener.GetNextEvent(event_sp)) +// { +// event_sp->Dump (&s); +// s.EOL(); +// } +//#endif + // 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_finalize_called = true; } @@ -1550,7 +1567,10 @@ Process::SetPrivateState (StateType new_state) log->Printf("Process::SetPrivateState (%s) stop_id = %u", StateAsCString(new_state), m_mod_id.GetStopID()); } // Use our target to get a shared pointer to ourselves... - m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (GetTarget().GetProcessSP(), new_state)); + if (m_finalize_called && PrivateStateThreadIsValid() == false) + BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state)); + else + m_private_state_broadcaster.BroadcastEvent (eBroadcastBitStateChanged, new ProcessEventData (shared_from_this(), new_state)); } else { @@ -3950,7 +3970,7 @@ Process::AppendSTDOUT (const char * s, size_t len) { Mutex::Locker locker (m_stdio_communication_mutex); m_stdout_data.append (s, len); - BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (GetTarget().GetProcessSP(), GetState())); + BroadcastEventIfUnique (eBroadcastBitSTDOUT, new ProcessEventData (shared_from_this(), GetState())); } void @@ -3958,7 +3978,7 @@ Process::AppendSTDERR (const char * s, size_t len) { Mutex::Locker locker (m_stdio_communication_mutex); m_stderr_data.append (s, len); - BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (GetTarget().GetProcessSP(), GetState())); + BroadcastEventIfUnique (eBroadcastBitSTDERR, new ProcessEventData (shared_from_this(), GetState())); } //------------------------------------------------------------------ diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 39157dd..a7f3864 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -279,11 +279,16 @@ Thread::~Thread() void Thread::DestroyThread () { + m_destroy_called = true; m_plan_stack.clear(); m_discarded_plan_stack.clear(); m_completed_plan_stack.clear(); m_actual_stop_info_sp.reset(); - m_destroy_called = true; + m_reg_context_sp.reset(); + m_unwinder_ap.reset(); + Mutex::Locker locker(m_frame_mutex); + m_curr_frames_sp.reset(); + m_prev_frames_sp.reset(); } void -- 2.7.4