forked from OSchip/llvm-project
Revert "Fix race condition during process detach"
This fix is not correct on its own until D12968 is resolved. Will resumbit once that is done. llvm-svn: 248702
This commit is contained in:
parent
9a132f36c3
commit
c8c77d46ef
|
@ -3479,7 +3479,7 @@ protected:
|
|||
}
|
||||
|
||||
Error
|
||||
StopForDestroyOrDetach(lldb::EventSP &exit_event_sp);
|
||||
HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp);
|
||||
|
||||
bool
|
||||
StateChangedIsExternallyHijacked();
|
||||
|
|
|
@ -3916,46 +3916,52 @@ Process::Halt (bool clear_thread_plans)
|
|||
}
|
||||
|
||||
Error
|
||||
Process::StopForDestroyOrDetach(lldb::EventSP &exit_event_sp)
|
||||
Process::HaltForDestroyOrDetach(lldb::EventSP &exit_event_sp)
|
||||
{
|
||||
Error error;
|
||||
if (m_public_state.GetValue() == eStateRunning)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
|
||||
if (log)
|
||||
log->Printf("Process::%s() About to stop.", __FUNCTION__);
|
||||
|
||||
SendAsyncInterrupt();
|
||||
|
||||
// Consume the interrupt event.
|
||||
TimeValue timeout (TimeValue::Now());
|
||||
timeout.OffsetWithSeconds(10);
|
||||
StateType state = WaitForProcessToStop (&timeout, &exit_event_sp);
|
||||
|
||||
// If the process exited while we were waiting for it to stop, put the exited event into
|
||||
// the shared pointer passed in and return. Our caller doesn't need to do anything else, since
|
||||
// they don't have a process anymore...
|
||||
|
||||
if (state == eStateExited || m_private_state.GetValue() == eStateExited)
|
||||
log->Printf("Process::%s() About to halt.", __FUNCTION__);
|
||||
error = Halt();
|
||||
if (error.Success())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::%s() Process exited while waiting to stop.", __FUNCTION__);
|
||||
return error;
|
||||
}
|
||||
else
|
||||
exit_event_sp.reset(); // It is ok to consume any non-exit stop events
|
||||
// Consume the halt event.
|
||||
TimeValue timeout (TimeValue::Now());
|
||||
timeout.OffsetWithSeconds(1);
|
||||
StateType state = WaitForProcessToStop (&timeout, &exit_event_sp);
|
||||
|
||||
if (state != eStateStopped)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::%s() failed to stop, state is: %s", __FUNCTION__, 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)
|
||||
// If the process exited while we were waiting for it to stop, put the exited event into
|
||||
// the shared pointer passed in and return. Our caller doesn't need to do anything else, since
|
||||
// they don't have a process anymore...
|
||||
|
||||
if (state == eStateExited || m_private_state.GetValue() == eStateExited)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::HaltForDestroyOrDetach() Process exited while waiting to Halt.");
|
||||
return error;
|
||||
}
|
||||
else
|
||||
exit_event_sp.reset(); // It is ok to consume any non-exit stop events
|
||||
|
||||
if (state != eStateStopped)
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::HaltForDestroyOrDetach() 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)
|
||||
{
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Process::HaltForDestroyOrDetach() Halt got error: %s", error.AsCString());
|
||||
}
|
||||
}
|
||||
return error;
|
||||
|
@ -3974,7 +3980,7 @@ Process::Detach (bool keep_stopped)
|
|||
{
|
||||
if (DetachRequiresHalt())
|
||||
{
|
||||
error = StopForDestroyOrDetach (exit_event_sp);
|
||||
error = HaltForDestroyOrDetach (exit_event_sp);
|
||||
if (!error.Success())
|
||||
{
|
||||
m_destroy_in_process = false;
|
||||
|
@ -4048,7 +4054,7 @@ Process::Destroy (bool force_kill)
|
|||
EventSP exit_event_sp;
|
||||
if (DestroyRequiresHalt())
|
||||
{
|
||||
error = StopForDestroyOrDetach(exit_event_sp);
|
||||
error = HaltForDestroyOrDetach(exit_event_sp);
|
||||
}
|
||||
|
||||
if (m_public_state.GetValue() != eStateRunning)
|
||||
|
@ -5225,7 +5231,7 @@ public:
|
|||
break;
|
||||
case 'i':
|
||||
if (StateIsRunningState(m_process->GetState()))
|
||||
m_process->SendAsyncInterrupt();
|
||||
m_process->Halt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -5250,8 +5256,8 @@ public:
|
|||
// Do only things that are safe to do in an interrupt context (like in
|
||||
// a SIGINT handler), like write 1 byte to a file descriptor. This will
|
||||
// interrupt the IOHandlerProcessSTDIO::Run() and we can look at the byte
|
||||
// that was written to the pipe and then call m_process->SendAsyncInterrupt()
|
||||
// from a much safer location in code.
|
||||
// that was written to the pipe and then call m_process->Halt() from a
|
||||
// much safer location in code.
|
||||
if (m_active)
|
||||
{
|
||||
char ch = 'i'; // Send 'i' for interrupt
|
||||
|
|
|
@ -15,6 +15,7 @@ class AttachResumeTestCase(TestBase):
|
|||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@expectedFailureFreeBSD('llvm.org/pr19310')
|
||||
@expectedFlakeyLinux('llvm.org/pr19310')
|
||||
@expectedFailureWindows("llvm.org/pr24778")
|
||||
@skipIfRemote
|
||||
@dwarf_test
|
||||
|
|
Loading…
Reference in New Issue