]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: refactor TestScript/build_issue48319 to check a more general property
authorBryan C. Mills <bcmills@google.com>
Wed, 26 Jan 2022 14:24:25 +0000 (09:24 -0500)
committerBryan Mills <bcmills@google.com>
Wed, 26 Jan 2022 16:15:53 +0000 (16:15 +0000)
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>

src/cmd/go/testdata/script/build_issue48319.txt

index f58a5faa3fdd93584425c2afc244d7f07e778a9a..3979247f2fd962b065f5c36b2225208fe5c35cc2 100644 (file)
@@ -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())
 }