delve/pkg/proc/proc_linux_test.go
Alessandro Arzilli 1a1e215fac
TeamCity: speed up ppc64le CI (#3622)
The builder is currently spending 15 to 20 minutes installing gcc and
upgrading packages every time we run the tests.
Because of this the build fails sometimes by running out of time.
This change reduces that to 5 minutes by:

* switching from curl to wget (which seems to have fewer dependencies)
* not installing gcc on ppc64le
* skipping tests that depend on gcc or other binutils
2024-01-09 14:13:00 -08:00

96 lines
3.0 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 mustHaveObjcopy(t *testing.T) {
t.Helper()
if objcopyPath, _ := exec.LookPath("objcopy"); objcopyPath == "" {
t.Skip("no objcopy in path")
}
}
func TestLoadingExternalDebugInfo(t *testing.T) {
mustHaveObjcopy(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) {
mustHaveObjcopy(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)
}
}