diff options
author | Jim Ingham <jingham@apple.com> | 2012-06-06 00:29:30 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2012-06-06 00:29:30 +0000 |
commit | aacc31813e9615e56dc39e322e47ed423e5a3adb (patch) | |
tree | e2dd46f772817eb49ec557c30292896d09cccf18 /lldb/source/Target/Process.cpp | |
parent | c141ba584e5339e1a7f6411204ce93151ca6e4af (diff) | |
download | bcm5719-llvm-aacc31813e9615e56dc39e322e47ed423e5a3adb.tar.gz bcm5719-llvm-aacc31813e9615e56dc39e322e47ed423e5a3adb.zip |
Make sure that when if we are going to Halt while the process is in the middle of HandlePrivateEvent we
wait till that is done. We need a stronger way to do this, but in practice this works and using some locking
strategy is harder because Halt & HandlePrivateEvent generally happen on different threads.
llvm-svn: 158042
Diffstat (limited to 'lldb/source/Target/Process.cpp')
-rw-r--r-- | lldb/source/Target/Process.cpp | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 7004cd243a7..191c3a35df0 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -812,6 +812,7 @@ Process::Process(Target &target, Listener &listener) : m_should_detach (false), m_next_event_action_ap(), m_run_lock (), + m_currently_handling_event(false), m_can_jit(eCanJITDontKnow) { UpdateInstanceName(); @@ -2936,6 +2937,11 @@ Process::PrivateResume () Error Process::Halt () { + // First make sure we aren't in the middle of handling an event, or we might restart. This is pretty weak, since + // we could just straightaway get another event. It just narrows the window... + m_currently_handling_event.WaitForValueEqualTo(false); + + // Pause our private state thread so we can ensure no one else eats // the stop event out from under us. Listener halt_listener ("lldb.process.halt_listener"); @@ -3039,31 +3045,51 @@ Process::Destroy () Error error (WillDestroy()); if (error.Success()) { - DisableAllBreakpointSites(); if (m_public_state.GetValue() == eStateRunning) { + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY)); + if (log) + log->Printf("Process::Destroy() About to halt."); error = Halt(); if (error.Success()) { // Consume the halt event. EventSP stop_event; TimeValue timeout (TimeValue::Now()); - timeout.OffsetWithMicroSeconds(1000); + timeout.OffsetWithSeconds(1); StateType state = WaitForProcessToStop (&timeout); if (state != eStateStopped) { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY)); if (log) log->Printf("Process::Destroy() Halt failed to stop, state is: %s", StateAsCString(state)); + // If we really couldn't stop the process then we should just error out here, but if the + // lower levels just bobbled sending the event and we really are stopped, then continue on. + StateType private_state = m_private_state.GetValue(); + if (private_state != eStateStopped && private_state != eStateExited) + { + return error; + } } } else { - LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TEMPORARY)); if (log) log->Printf("Process::Destroy() Halt got error: %s", error.AsCString()); + return error; } } + + if (m_public_state.GetValue() != eStateRunning) + { + // Ditch all thread plans, and remove all our breakpoints: in case we have to restart the target to + // kill it, we don't want it hitting a breakpoint... + // Only do this if we've stopped, however, since if we didn't manage to halt it above, then + // we're not going to have much luck doing this now. + m_thread_list.DiscardThreadPlans(); + DisableAllBreakpointSites(); + } error = DoDestroy(); if (error.Success()) @@ -3342,6 +3368,7 @@ void Process::HandlePrivateEvent (EventSP &event_sp) { LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + m_currently_handling_event.SetValue(true, eBroadcastNever); const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); @@ -3407,6 +3434,7 @@ Process::HandlePrivateEvent (EventSP &event_sp) StateAsCString (GetState ())); } } + m_currently_handling_event.SetValue(false, eBroadcastAlways); } void * |