diff options
author | Greg Clayton <gclayton@apple.com> | 2012-10-29 20:52:08 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2012-10-29 20:52:08 +0000 |
commit | 35a4cc5ea7020fbefd5f328a47d944b15cbda246 (patch) | |
tree | 8e45665751e40c27be4cf084361670323aada85d /lldb/source/Target/Process.cpp | |
parent | c2cccd795f304f582d9146008f48e736262eac15 (diff) | |
download | bcm5719-llvm-35a4cc5ea7020fbefd5f328a47d944b15cbda246.tar.gz bcm5719-llvm-35a4cc5ea7020fbefd5f328a47d944b15cbda246.zip |
<rdar://problem/12500785>
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
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r-- | lldb/source/Target/Process.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1f975c4a0d4..737283218d0 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())); } //------------------------------------------------------------------ |