<rdar://problem/11935492>

Fixed an issue where if we call "Process::Destroy()" and the process is running, if we try to stop it and get "exited" back as the stop reason, we will still deliver the exited event.

llvm-svn: 163591
This commit is contained in:
Greg Clayton 2012-09-11 02:33:37 +00:00
parent 0e3ab7ac5b
commit 85fb1b93f3
3 changed files with 36 additions and 10 deletions

View File

@ -3033,7 +3033,7 @@ public:
GetNextEvent (lldb::EventSP &event_sp);
lldb::StateType
WaitForProcessToStop (const TimeValue *timeout);
WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr = NULL);
lldb::StateType
WaitForStateChangedEvents (const TimeValue *timeout, lldb::EventSP &event_sp);

View File

@ -1078,12 +1078,13 @@ Process::GetNextEvent (EventSP &event_sp)
StateType
Process::WaitForProcessToStop (const TimeValue *timeout)
Process::WaitForProcessToStop (const TimeValue *timeout, lldb::EventSP *event_sp_ptr)
{
// We can't just wait for a "stopped" event, because the stopped event may have restarted the target.
// We have to actually check each event, and in the case of a stopped event check the restarted flag
// on the event.
EventSP event_sp;
if (event_sp_ptr)
event_sp_ptr->reset();
StateType state = GetState();
// If we are exited or detached, we won't ever get back to any
// other valid state...
@ -1092,7 +1093,11 @@ Process::WaitForProcessToStop (const TimeValue *timeout)
while (state != eStateInvalid)
{
EventSP event_sp;
state = WaitForStateChangedEvents (timeout, event_sp);
if (event_sp_ptr && event_sp)
*event_sp_ptr = event_sp;
switch (state)
{
case eStateCrashed:
@ -3108,6 +3113,7 @@ Process::Destroy ()
Error error (WillDestroy());
if (error.Success())
{
EventSP exit_event_sp;
if (m_public_state.GetValue() == eStateRunning)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@ -3117,10 +3123,12 @@ Process::Destroy ()
if (error.Success())
{
// Consume the halt event.
EventSP stop_event;
TimeValue timeout (TimeValue::Now());
timeout.OffsetWithSeconds(1);
StateType state = WaitForProcessToStop (&timeout);
StateType state = WaitForProcessToStop (&timeout, &exit_event_sp);
if (state != eStateExited)
exit_event_sp.reset(); // It is ok to consume any non-exit stop events
if (state != eStateStopped)
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@ -3131,16 +3139,18 @@ Process::Destroy ()
StateType private_state = m_private_state.GetValue();
if (private_state != eStateStopped && private_state != eStateExited)
{
// If we exited when we were waiting for a process to stop, then
// forward the event here so we don't lose the event
return error;
}
}
}
else
{
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("Process::Destroy() Halt got error: %s", error.AsCString());
return error;
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("Process::Destroy() Halt got error: %s", error.AsCString());
return error;
}
}
@ -3166,7 +3176,16 @@ Process::Destroy ()
m_target.GetDebugger().PopInputReader (m_process_input_reader);
if (m_process_input_reader)
m_process_input_reader.reset();
// If we exited when we were waiting for a process to stop, then
// forward the event here so we don't lose the event
if (exit_event_sp)
{
// Directly broadcast our exited event because we shut down our
// private state thread above
BroadcastEvent(exit_event_sp);
}
// If we have been interrupted (to kill us) in the middle of running, we may not end up propagating
// the last events through the event system, in which case we might strand the write lock. Unlock
// it here so when we do to tear down the process we don't get an error destroying the lock.

View File

@ -3525,10 +3525,17 @@ RNBRemote::HandlePacket_k (const char *p)
rnb_err_t
RNBRemote::HandlePacket_stop_process (const char *p)
{
//#define TEST_EXIT_ON_INTERRUPT // This should only be uncommented to test exiting on interrupt
#if defined(TEST_EXIT_ON_INTERRUPT)
rnb_err_t err = HandlePacket_k (p);
m_comm.Disconnect(true);
return err;
#else
DNBProcessSignal (m_ctx.ProcessID(), SIGSTOP);
//DNBProcessSignal (m_ctx.ProcessID(), SIGINT);
// Do not send any response packet! Wait for the stop reply packet to naturally happen
return rnb_success;
#endif
}
/* 's'