whatcanGOwrong
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,35 @@
|
||||
package debugger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func init() {
|
||||
attachErrorMessage = attachErrorMessageLinux
|
||||
}
|
||||
|
||||
//lint:file-ignore ST1005 errors here can be capitalized
|
||||
|
||||
func attachErrorMessageLinux(pid int, err error) error {
|
||||
fallbackerr := fmt.Errorf("could not attach to pid %d: %s", pid, err)
|
||||
if serr, ok := err.(syscall.Errno); ok {
|
||||
switch serr {
|
||||
case syscall.EPERM:
|
||||
bs, err := os.ReadFile("/proc/sys/kernel/yama/ptrace_scope")
|
||||
if err == nil && len(bs) >= 1 && bs[0] != '0' {
|
||||
// Yama documentation: https://www.kernel.org/doc/Documentation/security/Yama.txt
|
||||
return fmt.Errorf("Could not attach to pid %d: this could be caused by a kernel security setting, try writing \"0\" to /proc/sys/kernel/yama/ptrace_scope", pid)
|
||||
}
|
||||
fi, err := os.Stat(fmt.Sprintf("/proc/%d", pid))
|
||||
if err != nil {
|
||||
return fallbackerr
|
||||
}
|
||||
if fi.Sys().(*syscall.Stat_t).Uid != uint32(os.Getuid()) {
|
||||
return fmt.Errorf("Could not attach to pid %d: current user does not own the process", pid)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallbackerr
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package debugger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/go-delve/delve/pkg/gobuild"
|
||||
protest "github.com/go-delve/delve/pkg/proc/test"
|
||||
"github.com/go-delve/delve/service/api"
|
||||
)
|
||||
|
||||
func TestDebugger_LaunchNoMain(t *testing.T) {
|
||||
fixturesDir := protest.FindFixturesDir()
|
||||
nomaindir := filepath.Join(fixturesDir, "nomaindir")
|
||||
debugname := "debug"
|
||||
exepath := filepath.Join(nomaindir, debugname)
|
||||
defer os.Remove(exepath)
|
||||
if err := gobuild.GoBuild(debugname, []string{nomaindir}, fmt.Sprintf("-o %s", exepath)); err != nil {
|
||||
t.Fatalf("go build error %v", err)
|
||||
}
|
||||
|
||||
d := new(Debugger)
|
||||
_, err := d.Launch([]string{exepath}, ".")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error but none was generated")
|
||||
}
|
||||
if err != api.ErrNotExecutable {
|
||||
t.Fatalf("expected error \"%v\" got \"%v\"", api.ErrNotExecutable, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDebugger_LaunchInvalidFormat(t *testing.T) {
|
||||
fixturesDir := protest.FindFixturesDir()
|
||||
buildtestdir := filepath.Join(fixturesDir, "buildtest")
|
||||
debugname := "debug"
|
||||
switchOS := map[string]string{
|
||||
"darwin": "linux",
|
||||
"windows": "linux",
|
||||
"freebsd": "windows",
|
||||
"linux": "windows",
|
||||
}
|
||||
if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" {
|
||||
t.Setenv("GOARCH", "amd64")
|
||||
}
|
||||
if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
|
||||
t.Setenv("GOARCH", "amd64")
|
||||
}
|
||||
t.Setenv("GOOS", switchOS[runtime.GOOS])
|
||||
exepath := filepath.Join(buildtestdir, debugname)
|
||||
if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil {
|
||||
t.Fatalf("go build error %v", err)
|
||||
}
|
||||
defer os.Remove(exepath)
|
||||
|
||||
d := new(Debugger)
|
||||
_, err := d.Launch([]string{exepath}, ".")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error but none was generated")
|
||||
}
|
||||
if err != api.ErrNotExecutable {
|
||||
t.Fatalf("expected error %q got \"%v\"", api.ErrNotExecutable, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDebugger_LaunchCurrentDir(t *testing.T) {
|
||||
fixturesDir := protest.FindFixturesDir()
|
||||
testDir := filepath.Join(fixturesDir, "buildtest")
|
||||
debugname := "debug"
|
||||
exepath := filepath.Join(testDir, debugname)
|
||||
originalPath, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Chdir(originalPath)
|
||||
defer func() {
|
||||
if err := os.Remove(exepath); err != nil {
|
||||
t.Fatalf("error removing executable %v", err)
|
||||
}
|
||||
}()
|
||||
if err := gobuild.GoBuild(debugname, []string{testDir}, fmt.Sprintf("-o %s", exepath)); err != nil {
|
||||
t.Fatalf("go build error %v", err)
|
||||
}
|
||||
|
||||
os.Chdir(testDir)
|
||||
|
||||
d := new(Debugger)
|
||||
d.config = &Config{}
|
||||
_, err = d.Launch([]string{debugname}, ".")
|
||||
if err == nil {
|
||||
t.Fatal("expected error but none was generated")
|
||||
}
|
||||
if err != nil && !strings.Contains(err.Error(), "unknown backend") {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
//go:build !windows
|
||||
|
||||
package debugger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/creack/pty"
|
||||
"github.com/go-delve/delve/pkg/gobuild"
|
||||
protest "github.com/go-delve/delve/pkg/proc/test"
|
||||
"github.com/go-delve/delve/service/api"
|
||||
)
|
||||
|
||||
func TestDebugger_LaunchNoExecutablePerm(t *testing.T) {
|
||||
fixturesDir := protest.FindFixturesDir()
|
||||
buildtestdir := filepath.Join(fixturesDir, "buildtest")
|
||||
debugname := "debug"
|
||||
switchOS := map[string]string{
|
||||
"darwin": "linux",
|
||||
"windows": "linux",
|
||||
"freebsd": "windows",
|
||||
"linux": "windows",
|
||||
}
|
||||
if runtime.GOARCH == "arm64" && runtime.GOOS == "linux" {
|
||||
t.Setenv("GOARCH", "amd64")
|
||||
}
|
||||
if runtime.GOARCH == "ppc64le" && runtime.GOOS == "linux" {
|
||||
t.Setenv("GOARCH", "amd64")
|
||||
}
|
||||
t.Setenv("GOOS", switchOS[runtime.GOOS])
|
||||
exepath := filepath.Join(buildtestdir, debugname)
|
||||
defer os.Remove(exepath)
|
||||
if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil {
|
||||
t.Fatalf("go build error %v", err)
|
||||
}
|
||||
if err := os.Chmod(exepath, 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d := new(Debugger)
|
||||
_, err := d.Launch([]string{exepath}, ".")
|
||||
if err == nil {
|
||||
t.Fatalf("expected error but none was generated")
|
||||
}
|
||||
if err != api.ErrNotExecutable {
|
||||
t.Fatalf("expected error %q got \"%v\"", api.ErrNotExecutable, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDebugger_LaunchWithTTY(t *testing.T) {
|
||||
if os.Getenv("CI") == "true" {
|
||||
if _, err := exec.LookPath("lsof"); err != nil {
|
||||
t.Skip("skipping test in CI, system does not contain lsof")
|
||||
}
|
||||
}
|
||||
// Ensure no env meddling is leftover from previous tests.
|
||||
t.Setenv("GOOS", runtime.GOOS)
|
||||
t.Setenv("GOARCH", runtime.GOARCH)
|
||||
|
||||
p, tty, err := pty.Open()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer p.Close()
|
||||
defer tty.Close()
|
||||
|
||||
fixturesDir := protest.FindFixturesDir()
|
||||
buildtestdir := filepath.Join(fixturesDir, "buildtest")
|
||||
debugname := "debugtty"
|
||||
exepath := filepath.Join(buildtestdir, debugname)
|
||||
if err := gobuild.GoBuild(debugname, []string{buildtestdir}, fmt.Sprintf("-o %s", exepath)); err != nil {
|
||||
t.Fatalf("go build error %v", err)
|
||||
}
|
||||
defer os.Remove(exepath)
|
||||
var backend string
|
||||
protest.DefaultTestBackend(&backend)
|
||||
conf := &Config{TTY: tty.Name(), Backend: backend}
|
||||
pArgs := []string{exepath}
|
||||
d, err := New(conf, pArgs)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
openFileCmd, wantTTYName := "lsof", tty.Name()
|
||||
if runtime.GOOS == "freebsd" {
|
||||
openFileCmd = "fstat"
|
||||
wantTTYName = strings.TrimPrefix(wantTTYName, "/dev/")
|
||||
}
|
||||
cmd := exec.Command(openFileCmd, "-p", fmt.Sprintf("%d", d.ProcessPid()))
|
||||
result, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Contains(result, []byte(wantTTYName)) {
|
||||
t.Fatalf("process open file list does not contain expected tty %q", wantTTYName)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user