proc/native/linux: better handling of process death due to signals (#2477)

Handle the signaled status for the thread leader like we handle the
exited status, by returning ErrProcessExited and recording the killer
signal  in it.
Prior to this commit we would find out about the death of the thread
later in the loop, the condition would still be reported as
ErrProcessExited, but without recording the signal number anywhere.

Also fixes a bug in TestAttachStopOnEntry where the test would
inadvertently cause a SIGPIPE to be sent to the target process, making
it terminate early.
This commit is contained in:
Alessandro Arzilli
2021-05-17 18:48:48 +02:00
committed by GitHub
parent 30cdedae69
commit bd2a4fe56e
3 changed files with 65 additions and 31 deletions

View File

@ -4,11 +4,17 @@ package proc_test
import (
"fmt"
"os"
"os/exec"
"runtime"
"syscall"
"testing"
"time"
"golang.org/x/sys/unix"
"github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/native"
protest "github.com/go-delve/delve/pkg/proc/test"
)
@ -66,3 +72,31 @@ func TestIssue419(t *testing.T) {
}
}
}
func TestSignalDeath(t *testing.T) {
if testBackend != "native" || runtime.GOOS != "linux" {
t.Skip("skipped on non-linux non-native backends")
}
var buildFlags protest.BuildFlags
if buildMode == "pie" {
buildFlags |= protest.BuildModePIE
}
fixture := protest.BuildFixture("loopprog", buildFlags)
cmd := exec.Command(fixture.Path)
stdout, err := cmd.StdoutPipe()
assertNoError(err, t, "StdoutPipe")
cmd.Stderr = os.Stderr
assertNoError(cmd.Start(), t, "starting fixture")
p, err := native.Attach(cmd.Process.Pid, []string{})
assertNoError(err, t, "Attach")
stdout.Close() // target will receive SIGPIPE later on
err = p.Continue()
t.Logf("error is %v", err)
exitErr, isexited := err.(proc.ErrProcessExited)
if !isexited {
t.Fatal("did not exit")
}
if exitErr.Status != -int(unix.SIGPIPE) {
t.Fatalf("expected SIGPIPE got %d\n", exitErr.Status)
}
}