proc/native/linux: get exit status if proc exits after receiving signal (#2195)

If the process receives a signal (or sends a singal to itself) and then
dies before we can route the signal back to it we still need to
retrieve its exit status.

Fixes a rare failure of TestIssue1101 in proc_test.go

Co-authored-by: a <a@kra>
This commit is contained in:
Alessandro Arzilli 2020-10-13 00:02:55 +02:00 committed by GitHub
parent 5632cf92be
commit 1374962f72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -276,6 +276,7 @@ type trapWaitOptions uint8
const ( const (
trapWaitHalt trapWaitOptions = 1 << iota trapWaitHalt trapWaitOptions = 1 << iota
trapWaitNohang trapWaitNohang
trapWaitDontCallExitGuard
) )
func (dbp *nativeProcess) trapWaitInternal(pid int, options trapWaitOptions) (*nativeThread, error) { func (dbp *nativeProcess) trapWaitInternal(pid int, options trapWaitOptions) (*nativeThread, error) {
@ -371,12 +372,11 @@ func (dbp *nativeProcess) trapWaitInternal(pid int, options trapWaitOptions) (*n
th.os.running = false th.os.running = false
return th, nil return th, nil
} else if err := th.resumeWithSig(int(status.StopSignal())); err != nil { } else if err := th.resumeWithSig(int(status.StopSignal())); err != nil {
if err == sys.ESRCH { if options&trapWaitDontCallExitGuard != 0 {
dbp.postExit()
return nil, proc.ErrProcessExited{Pid: dbp.pid}
}
return nil, err return nil, err
} }
return nil, dbp.exitGuard(err)
}
} }
} }
@ -445,7 +445,7 @@ func (dbp *nativeProcess) exitGuard(err error) error {
return err return err
} }
if status(dbp.pid, dbp.os.comm) == statusZombie { if status(dbp.pid, dbp.os.comm) == statusZombie {
_, err := dbp.trapWaitInternal(-1, 0) _, err := dbp.trapWaitInternal(-1, trapWaitDontCallExitGuard)
return err return err
} }