delve/pkg/proc/proc_unix_test.go
2023-10-03 08:50:11 -07:00

102 lines
2.4 KiB
Go

//go:build linux || darwin
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"
)
type errIssue419 struct {
pid int
err error
}
func (npe errIssue419) Error() string {
return fmt.Sprintf("Pid is zero or negative: %d", npe.pid)
}
func TestIssue419(t *testing.T) {
if testBackend == "rr" {
return
}
errChan := make(chan error, 2)
// SIGINT directed at the inferior should be passed along not swallowed by delve
withTestProcess("issue419", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) {
setFunctionBreakpoint(p, t, "main.main")
assertNoError(grp.Continue(), t, "Continue()")
resumeChan := make(chan struct{}, 1)
go func() {
time.Sleep(500 * time.Millisecond)
<-resumeChan
if p.Pid() <= 0 {
// if we don't stop the inferior the test will never finish
grp.RequestManualStop()
err := grp.Detach(true)
errChan <- errIssue419{pid: p.Pid(), err: err}
return
}
err := syscall.Kill(p.Pid(), syscall.SIGINT)
errChan <- errIssue419{pid: p.Pid(), err: err}
}()
grp.ResumeNotify(resumeChan)
errChan <- grp.Continue()
})
for i := 0; i < 2; i++ {
err := <-errChan
t.Logf("error %T %#v\n", err, err)
if v, ok := err.(errIssue419); ok {
assertNoError(v.err, t, "syscall.Kill")
continue
}
if _, exited := err.(proc.ErrProcessExited); !exited {
t.Fatalf("Unexpected error after Continue(): %v\n", err)
}
}
}
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, nil, []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)
}
}