Skip to content

Commit 9b05922

Browse files
Bryan C. Millsjproberts
Bryan C. Mills
authored andcommitted
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 golang#50183 Updates golang#48319 Change-Id: I0b1151d9ba3d0ff903f72e27850306406e5cb518 Reviewed-on: https://go-review.googlesource.com/c/go/+/380914 Trust: Bryan Mills <[email protected]> Run-TryBot: Bryan Mills <[email protected]> Reviewed-by: Russ Cox <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent ce6e2a5 commit 9b05922

File tree

1 file changed

+27
-133
lines changed

1 file changed

+27
-133
lines changed
+27-133
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,33 @@
1+
# Regression test for https://go.dev/issue/48319:
2+
# cgo builds should not include debug information from a stale GOROOT_FINAL.
3+
14
[short] skip
25
[!cgo] skip
6+
[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.
37

4-
# Set up fresh GOCACHE
8+
# This test is sensitive to cache invalidation,
9+
# so use a separate build cache that we can control.
510
env GOCACHE=$WORK/gocache
611
mkdir $GOCACHE
712

8-
# 1. unset GOROOT_FINAL, Build a simple binary with cgo by origin go.
9-
# The DW_AT_comp_dir of runtime/cgo should have a prefix with origin goroot.
10-
env GOROOT_FINAL=
11-
# If using "go run", it is no debuginfo in binary. So use "go build".
12-
# And we can check the stderr to judge if the cache of "runtime/cgo"
13-
# was used or not.
14-
go build -o binary.exe
15-
exec ./binary.exe $TESTGO_GOROOT
16-
stdout 'cgo DW_AT_comp_dir is right in binary'
17-
18-
19-
# 2. GOROOT_FINAL will be changed, the runtime/cgo will be rebuild.
20-
env GOROOT_FINAL=$WORK/gorootfinal
21-
go build -x -o binary.exe
22-
stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
23-
exec ./binary.exe $GOROOT_FINAL
24-
stdout 'cgo DW_AT_comp_dir is right in binary'
25-
26-
27-
[!symlink] skip
28-
29-
# Symlink the compiler to another path
30-
env GOROOT=$WORK/goroot
31-
symlink $GOROOT -> $TESTGO_GOROOT
32-
33-
# 3. GOROOT_FINAL is same with 2, build with the other go
34-
# the runtime/cgo will not be rebuild.
35-
go build -x -o binary.exe
36-
! stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
37-
exec ./binary.exe $GOROOT_FINAL
38-
stdout 'cgo DW_AT_comp_dir is right in binary'
39-
40-
41-
# 4. unset GOROOT_FINAL, build with the other go
42-
# the runtime/cgo will be rebuild.
43-
env GOROOT_FINAL=
44-
go build -x -o binary.exe
45-
stderr '(clang|gcc)( |\.exe).*gcc_.*\.c'
46-
exec ./binary.exe $GOROOT
47-
stdout 'cgo DW_AT_comp_dir is right in binary'
13+
# Build a binary using a specific value of GOROOT_FINAL.
14+
env GOROOT_FINAL=$WORK${/}goroot1
15+
go build -o main.exe
16+
mv main.exe main1.exe
17+
18+
# Now clean the cache and build using a different GOROOT_FINAL.
19+
# The resulting binaries should differ in their debug metadata.
20+
go clean -cache
21+
env GOROOT_FINAL=$WORK${/}goroot2
22+
go build -o main.exe
23+
mv main.exe main2.exe
24+
! cmp main2.exe main1.exe
25+
26+
# Set GOROOT_FINAL back to the first value.
27+
# If the build is properly reproducible, the two binaries should match.
28+
env GOROOT_FINAL=$WORK${/}goroot1
29+
go build -o main.exe
30+
cmp -q main.exe main1.exe
4831

4932
-- go.mod --
5033
module main
@@ -54,100 +37,11 @@ go 1.18
5437
package main
5538

5639
import "C"
57-
import (
58-
"debug/dwarf"
59-
"fmt"
60-
"log"
61-
"os"
62-
"path/filepath"
63-
"strings"
64-
)
40+
41+
import "runtime"
6542

6643
var _ C.int
6744

6845
func main() {
69-
dwarfData, err := readDWARF(os.Args[0])
70-
if err != nil {
71-
log.Fatal(err)
72-
}
73-
goroot := filepath.Join(os.Args[1], "src")
74-
dwarfReader := dwarfData.Reader()
75-
cgopackage := filepath.Join("runtime", "cgo")
76-
var hascgo bool
77-
for {
78-
e, err := dwarfReader.Next()
79-
if err != nil {
80-
log.Fatal(err)
81-
}
82-
if e == nil {
83-
break
84-
}
85-
field := e.AttrField(dwarf.AttrCompDir)
86-
if field == nil {
87-
continue
88-
}
89-
compdir := field.Val.(string)
90-
if strings.HasSuffix(compdir, cgopackage) {
91-
hascgo = true
92-
if !strings.HasPrefix(compdir, goroot) {
93-
fmt.Printf("cgo DW_AT_comp_dir %s contains incorrect path in binary.\n", compdir)
94-
return
95-
}
96-
}
97-
}
98-
if hascgo {
99-
fmt.Println("cgo DW_AT_comp_dir is right in binary")
100-
} else {
101-
fmt.Println("binary does not contain cgo")
102-
}
103-
}
104-
-- read_darwin.go --
105-
package main
106-
107-
import (
108-
"debug/dwarf"
109-
"debug/macho"
110-
)
111-
112-
func readDWARF(exePath string) (*dwarf.Data, error) {
113-
machoFile, err := macho.Open(exePath)
114-
if err != nil {
115-
return nil, err
116-
}
117-
defer machoFile.Close()
118-
return machoFile.DWARF()
119-
}
120-
-- read_elf.go --
121-
// +build android dragonfly freebsd illumos linux netbsd openbsd solaris
122-
123-
package main
124-
125-
import (
126-
"debug/dwarf"
127-
"debug/elf"
128-
)
129-
130-
func readDWARF(exePath string) (*dwarf.Data, error) {
131-
elfFile, err := elf.Open(exePath)
132-
if err != nil {
133-
return nil, err
134-
}
135-
defer elfFile.Close()
136-
return elfFile.DWARF()
137-
}
138-
-- read_windows.go --
139-
package main
140-
141-
import (
142-
"debug/dwarf"
143-
"debug/pe"
144-
)
145-
146-
func readDWARF(exePath string) (*dwarf.Data, error) {
147-
peFile, err := pe.Open(exePath)
148-
if err != nil {
149-
return nil, err
150-
}
151-
defer peFile.Close()
152-
return peFile.DWARF()
46+
println(runtime.GOROOT())
15347
}

0 commit comments

Comments
 (0)