github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/proc/proc_unix_test.go (about) 1 //go:build linux || darwin 2 // +build linux darwin 3 4 package proc_test 5 6 import ( 7 "fmt" 8 "os" 9 "os/exec" 10 "runtime" 11 "syscall" 12 "testing" 13 "time" 14 15 "golang.org/x/sys/unix" 16 17 "github.com/go-delve/delve/pkg/proc" 18 "github.com/go-delve/delve/pkg/proc/native" 19 protest "github.com/go-delve/delve/pkg/proc/test" 20 ) 21 22 type errIssue419 struct { 23 pid int 24 err error 25 } 26 27 func (npe errIssue419) Error() string { 28 return fmt.Sprintf("Pid is zero or negative: %d", npe.pid) 29 } 30 31 func TestIssue419(t *testing.T) { 32 if testBackend == "rr" { 33 return 34 } 35 36 errChan := make(chan error, 2) 37 38 // SIGINT directed at the inferior should be passed along not swallowed by delve 39 withTestProcess("issue419", t, func(p *proc.Target, grp *proc.TargetGroup, fixture protest.Fixture) { 40 setFunctionBreakpoint(p, t, "main.main") 41 assertNoError(grp.Continue(), t, "Continue()") 42 resumeChan := make(chan struct{}, 1) 43 go func() { 44 time.Sleep(500 * time.Millisecond) 45 <-resumeChan 46 if p.Pid() <= 0 { 47 // if we don't stop the inferior the test will never finish 48 grp.RequestManualStop() 49 err := grp.Detach(true) 50 errChan <- errIssue419{pid: p.Pid(), err: err} 51 return 52 } 53 err := syscall.Kill(p.Pid(), syscall.SIGINT) 54 errChan <- errIssue419{pid: p.Pid(), err: err} 55 }() 56 grp.ResumeNotify(resumeChan) 57 errChan <- grp.Continue() 58 }) 59 60 for i := 0; i < 2; i++ { 61 err := <-errChan 62 63 t.Logf("error %T %#v\n", err, err) 64 65 if v, ok := err.(errIssue419); ok { 66 assertNoError(v.err, t, "syscall.Kill") 67 continue 68 } 69 70 if _, exited := err.(proc.ErrProcessExited); !exited { 71 t.Fatalf("Unexpected error after Continue(): %v\n", err) 72 } 73 } 74 } 75 76 func TestSignalDeath(t *testing.T) { 77 if testBackend != "native" || runtime.GOOS != "linux" { 78 t.Skip("skipped on non-linux non-native backends") 79 } 80 var buildFlags protest.BuildFlags 81 if buildMode == "pie" { 82 buildFlags |= protest.BuildModePIE 83 } 84 fixture := protest.BuildFixture("loopprog", buildFlags) 85 cmd := exec.Command(fixture.Path) 86 stdout, err := cmd.StdoutPipe() 87 assertNoError(err, t, "StdoutPipe") 88 cmd.Stderr = os.Stderr 89 assertNoError(cmd.Start(), t, "starting fixture") 90 p, err := native.Attach(cmd.Process.Pid, nil, []string{}) 91 assertNoError(err, t, "Attach") 92 stdout.Close() // target will receive SIGPIPE later on 93 err = p.Continue() 94 t.Logf("error is %v", err) 95 exitErr, isexited := err.(proc.ErrProcessExited) 96 if !isexited { 97 t.Fatal("did not exit") 98 } 99 if exitErr.Status != -int(unix.SIGPIPE) { 100 t.Fatalf("expected SIGPIPE got %d\n", exitErr.Status) 101 } 102 }