forked from OSchip/llvm-project
Rework fix in r201744. You really DO need to waitpid twice to get the
process fully reaped. The race & bad behavior was because we were letting the reaping thread in LLDB to also set the Process exit status, so debugserver would sometimes be shut down before it got a chance to report the exit status, and then we got confused. <rdar://problem/16555850> llvm-svn: 211636
This commit is contained in:
parent
5d1b9c7386
commit
6008924508
|
@ -824,9 +824,6 @@ public:
|
|||
bool
|
||||
MonitorProcess () const
|
||||
{
|
||||
if (GetFlags().Test(lldb::eLaunchFlagsDontMonitorProcess))
|
||||
return true;
|
||||
|
||||
if (m_monitor_callback && ProcessIDIsValid())
|
||||
{
|
||||
Host::StartMonitoringChildProcess (m_monitor_callback,
|
||||
|
|
|
@ -47,8 +47,8 @@ namespace lldb {
|
|||
eLaunchFlagLaunchInTTY = (1u << 5), ///< Launch the process in a new TTY if supported by the host
|
||||
eLaunchFlagLaunchInShell= (1u << 6), ///< Launch the process inside a shell to get shell expansion
|
||||
eLaunchFlagLaunchInSeparateProcessGroup = (1u << 7), ///< Launch the process in a separate process group
|
||||
eLaunchFlagsDontMonitorProcess = (1u << 8) ///< If you are going to hand the process off (e.g. to debugserver)
|
||||
///< set this flag so lldb & the handee don't race to reap it.
|
||||
eLaunchFlagsDontSetExitStatus = (1u << 8) ///< If you are going to hand the process off (e.g. to debugserver)
|
||||
///< set this flag so lldb & the handee don't race to set its exit status.
|
||||
} LaunchFlags;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -1667,7 +1667,12 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
|
|||
if (!launch_info.MonitorProcess())
|
||||
{
|
||||
const bool monitor_signals = false;
|
||||
StartMonitoringChildProcess (Process::SetProcessExitStatus,
|
||||
Host::MonitorChildProcessCallback callback = nullptr;
|
||||
|
||||
if (!launch_info.GetFlags().Test(lldb::eLaunchFlagsDontSetExitStatus))
|
||||
callback = Process::SetProcessExitStatus;
|
||||
|
||||
StartMonitoringChildProcess (callback,
|
||||
NULL,
|
||||
pid,
|
||||
monitor_signals);
|
||||
|
|
|
@ -785,10 +785,10 @@ PlatformDarwin::DebugProcess (ProcessLaunchInfo &launch_info,
|
|||
|
||||
if (IsHost())
|
||||
{
|
||||
// We are going to hand this process off to debugserver which will monitor the process itself.
|
||||
// So don't also monitor it from lldb or we set up a race between debugserver & us for who will find out
|
||||
// about the debugged process's death.
|
||||
launch_info.GetFlags().Set(eLaunchFlagsDontMonitorProcess);
|
||||
// We are going to hand this process off to debugserver which will be in charge of setting the exit status.
|
||||
// We still need to reap it from lldb but if we let the monitor thread also set the exit status, we set up a
|
||||
// race between debugserver & us for who will find out about the debugged process's death.
|
||||
launch_info.GetFlags().Set(eLaunchFlagsDontSetExitStatus);
|
||||
process_sp = Platform::DebugProcess (launch_info, debugger, target, listener, error);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -239,7 +239,7 @@ spawn_kqueue_thread (pid_t pid)
|
|||
|
||||
struct kevent reg_event;
|
||||
|
||||
EV_SET(®_event, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT|NOTE_EXIT_DETAIL, 0, NULL);
|
||||
EV_SET(®_event, pid, EVFILT_PROC, EV_ADD, NOTE_EXIT|NOTE_EXITSTATUS|NOTE_EXIT_DETAIL, 0, NULL);
|
||||
// Register the event:
|
||||
int result = kevent (kq_id, ®_event, 1, NULL, 0, NULL);
|
||||
if (result != 0)
|
||||
|
|
Loading…
Reference in New Issue