aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2022-01-26 09:24:25 -0500
committerBryan Mills <bcmills@google.com>2022-01-26 16:15:53 +0000
commita9eedc0789085f55193bdbf0d777b8eaeccb1890 (patch)
treef6c30b999ac4645420b1f06c6ca83da186f78fd6
parent5b1b80beb1a2a9a353738e80777d1e25cfdfa095 (diff)
downloadgo-a9eedc0789085f55193bdbf0d777b8eaeccb1890.tar.gz
go-a9eedc0789085f55193bdbf0d777b8eaeccb1890.zip
cmd/go: refactor TestScript/build_issue48319 to check a more general property
The test previously checked that the DWARF DW_AT_comp_dir attribute matched GOROOT_FINAL. However, on further consideration, we believe that DW_AT_comp_dir should not actually match GOROOT_FINAL: the DWARF spec says that DW_AT_comp_dir records “the current working directory of the compilation command that produced this compilation unit”, but the actual working directory of the compilation command proper is a throwaway directory in the build cache — it is neither stable nor meaningful. However, the test was getting at a real issue that we do care about: namely, that the binary produced by a 'go build' command with cgo enabled should not reuse a dependency that embeds a stale GOROOT_FINAL. This change refactors the test to verify the latter property instead of checking DW_AT_comp_dir specifically. For #50183 Updates #48319 Change-Id: I0b1151d9ba3d0ff903f72e27850306406e5cb518 Reviewed-on: https://go-review.googlesource.com/c/go/+/380914 Trust: Bryan Mills <bcmills@google.com> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
-rw-r--r--src/cmd/go/testdata/script/build_issue48319.txt160
1 files changed, 27 insertions, 133 deletions
diff --git a/src/cmd/go/testdata/script/build_issue48319.txt b/src/cmd/go/testdata/script/build_issue48319.txt
index f58a5faa3f..3979247f2f 100644
--- a/src/cmd/go/testdata/script/build_issue48319.txt
+++ b/src/cmd/go/testdata/script/build_issue48319.txt
@@ -1,50 +1,33 @@
+# Regression test for https://go.dev/issue/48319:
+# cgo builds should not include debug information from a stale GOROOT_FINAL.
+
[short] skip
[!cgo] skip
+[windows] skip # The Go Windows builders have an extremely out-of-date gcc that does not support reproducible builds; see https://go.dev/issue/50824.
-# Set up fresh GOCACHE
+# This test is sensitive to cache invalidation,
+# so use a separate build cache that we can control.
env GOCACHE=$WORK/gocache
mkdir $GOCACHE
-# 1. unset GOROOT_FINAL, Build a simple binary with cgo by origin go.
-# The DW_AT_comp_dir of runtime/cgo should have a prefix with origin goroot.
-env GOROOT_FINAL=
-# If using "go run", it is no debuginfo in binary. So use "go build".
-# And we can check the stderr to judge if the cache of "runtime/cgo"
-# was used or not.
-go build -o binary.exe
-exec ./binary.exe $TESTGO_GOROOT
-stdout 'cgo DW_AT_comp_dir is right in binary'
-
-
-# 2. GOROOT_FINAL will be changed, the runtime/cgo will be rebuild.
-env GOROOT_FINAL=$WORK/gorootfinal
-go build -x -o binary.exe
-stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
-exec ./binary.exe $GOROOT_FINAL
-stdout 'cgo DW_AT_comp_dir is right in binary'
-
-
-[!symlink] skip
-
-# Symlink the compiler to another path
-env GOROOT=$WORK/goroot
-symlink $GOROOT -> $TESTGO_GOROOT
-
-# 3. GOROOT_FINAL is same with 2, build with the other go
-# the runtime/cgo will not be rebuild.
-go build -x -o binary.exe
-! stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
-exec ./binary.exe $GOROOT_FINAL
-stdout 'cgo DW_AT_comp_dir is right in binary'
-
-
-# 4. unset GOROOT_FINAL, build with the other go
-# the runtime/cgo will be rebuild.
-env GOROOT_FINAL=
-go build -x -o binary.exe
-stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
-exec ./binary.exe $GOROOT
-stdout 'cgo DW_AT_comp_dir is right in binary'
+# Build a binary using a specific value of GOROOT_FINAL.
+env GOROOT_FINAL=$WORK${/}goroot1
+go build -o main.exe
+mv main.exe main1.exe
+
+# Now clean the cache and build using a different GOROOT_FINAL.
+# The resulting binaries should differ in their debug metadata.
+go clean -cache
+env GOROOT_FINAL=$WORK${/}goroot2
+go build -o main.exe
+mv main.exe main2.exe
+! cmp main2.exe main1.exe
+
+# Set GOROOT_FINAL back to the first value.
+# If the build is properly reproducible, the two binaries should match.
+env GOROOT_FINAL=$WORK${/}goroot1
+go build -o main.exe
+cmp -q main.exe main1.exe
-- go.mod --
module main
@@ -54,100 +37,11 @@ go 1.18
package main
import "C"
-import (
- "debug/dwarf"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "strings"
-)
+
+import "runtime"
var _ C.int
func main() {
- dwarfData, err := readDWARF(os.Args[0])
- if err != nil {
- log.Fatal(err)
- }
- goroot := filepath.Join(os.Args[1], "src")
- dwarfReader := dwarfData.Reader()
- cgopackage := filepath.Join("runtime", "cgo")
- var hascgo bool
- for {
- e, err := dwarfReader.Next()
- if err != nil {
- log.Fatal(err)
- }
- if e == nil {
- break
- }
- field := e.AttrField(dwarf.AttrCompDir)
- if field == nil {
- continue
- }
- compdir := field.Val.(string)
- if strings.HasSuffix(compdir, cgopackage) {
- hascgo = true
- if !strings.HasPrefix(compdir, goroot) {
- fmt.Printf("cgo DW_AT_comp_dir %s contains incorrect path in binary.\n", compdir)
- return
- }
- }
- }
- if hascgo {
- fmt.Println("cgo DW_AT_comp_dir is right in binary")
- } else {
- fmt.Println("binary does not contain cgo")
- }
-}
--- read_darwin.go --
-package main
-
-import (
- "debug/dwarf"
- "debug/macho"
-)
-
-func readDWARF(exePath string) (*dwarf.Data, error) {
- machoFile, err := macho.Open(exePath)
- if err != nil {
- return nil, err
- }
- defer machoFile.Close()
- return machoFile.DWARF()
-}
--- read_elf.go --
-// +build android dragonfly freebsd illumos linux netbsd openbsd solaris
-
-package main
-
-import (
- "debug/dwarf"
- "debug/elf"
-)
-
-func readDWARF(exePath string) (*dwarf.Data, error) {
- elfFile, err := elf.Open(exePath)
- if err != nil {
- return nil, err
- }
- defer elfFile.Close()
- return elfFile.DWARF()
-}
--- read_windows.go --
-package main
-
-import (
- "debug/dwarf"
- "debug/pe"
-)
-
-func readDWARF(exePath string) (*dwarf.Data, error) {
- peFile, err := pe.Open(exePath)
- if err != nil {
- return nil, err
- }
- defer peFile.Close()
- return peFile.DWARF()
+ println(runtime.GOROOT())
}