forked from OSchip/llvm-project
<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:
parent
0e3ab7ac5b
commit
85fb1b93f3
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue