delve/pkg/proc/proc_linux_test.go

87 lines
2.8 KiB
Go

package proc_test
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/go-delve/delve/pkg/proc"
"github.com/go-delve/delve/pkg/proc/native"
protest "github.com/go-delve/delve/pkg/proc/test"
)
func TestLoadingExternalDebugInfo(t *testing.T) {
fixture := protest.BuildFixture("locationsprog", 0)
defer os.Remove(fixture.Path)
stripAndCopyDebugInfo(fixture, t)
p, err := native.Launch(append([]string{fixture.Path}, ""), "", 0, []string{filepath.Dir(fixture.Path)}, "", "", proc.OutputRedirect{}, proc.OutputRedirect{})
if err != nil {
t.Fatal(err)
}
p.Detach(true)
}
func TestGnuDebuglink(t *testing.T) {
// build math.go and make a copy of the executable
fixture := protest.BuildFixture("math", 0)
buf, err := os.ReadFile(fixture.Path)
assertNoError(err, t, "ReadFile")
debuglinkPath := fixture.Path + "-gnu_debuglink"
assertNoError(os.WriteFile(debuglinkPath, buf, 0666), t, "WriteFile")
defer os.Remove(debuglinkPath)
run := func(exe string, args ...string) {
cmd := exec.Command(exe, args...)
out, err := cmd.CombinedOutput()
assertNoError(err, t, fmt.Sprintf("%s %q: %s", cmd, strings.Join(args, " "), out))
}
// convert the executable copy to use .gnu_debuglink
debuglinkDwoPath := debuglinkPath + ".dwo"
run("objcopy", "--only-keep-debug", debuglinkPath, debuglinkDwoPath)
defer os.Remove(debuglinkDwoPath)
run("objcopy", "--strip-debug", debuglinkPath)
run("objcopy", "--add-gnu-debuglink="+debuglinkDwoPath, debuglinkPath)
// open original executable
normalBinInfo := proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH)
assertNoError(normalBinInfo.LoadBinaryInfo(fixture.Path, 0, []string{"/debugdir"}), t, "LoadBinaryInfo (normal exe)")
// open .gnu_debuglink executable
debuglinkBinInfo := proc.NewBinaryInfo(runtime.GOOS, runtime.GOARCH)
assertNoError(debuglinkBinInfo.LoadBinaryInfo(debuglinkPath, 0, []string{"/debugdir"}), t, "LoadBinaryInfo (gnu_debuglink exe)")
if len(normalBinInfo.Functions) != len(debuglinkBinInfo.Functions) {
t.Fatalf("function list mismatch")
}
for i := range normalBinInfo.Functions {
normalFn := normalBinInfo.Functions[i]
debuglinkFn := debuglinkBinInfo.Functions[i]
if normalFn.Entry != debuglinkFn.Entry || normalFn.Name != debuglinkFn.Name {
t.Fatalf("function definition mismatch")
}
}
}
func stripAndCopyDebugInfo(f protest.Fixture, t *testing.T) {
name := filepath.Base(f.Path)
// Copy the debug information to an external file.
copyCmd := exec.Command("objcopy", "--only-keep-debug", name, name+".debug")
copyCmd.Dir = filepath.Dir(f.Path)
if err := copyCmd.Run(); err != nil {
t.Fatal(err)
}
// Strip the original binary of the debug information.
stripCmd := exec.Command("strip", "--strip-debug", "--strip-unneeded", name)
stripCmd.Dir = filepath.Dir(f.Path)
if err := stripCmd.Run(); err != nil {
t.Fatal(err)
}
}