-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cmd/go: insert goroot to the hash of build cache when the packages in…
…clude C files There are some absolute paths in the object file of the packages include C files. The path in C objects file can't be rewritten by linker. The goroot must be used as input for the hash when the packages include C files. So that the debug_info of the binary is correctly. Fixes #48319 Change-Id: I659a3d6d71c4e49fff83f5bcf53a0a417e552a93 Reviewed-on: https://go-review.googlesource.com/c/go/+/348991 Reviewed-by: Bryan C. Mills <[email protected]> Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Meng Zhuo <[email protected]> Trust: Jay Conrod <[email protected]>
- Loading branch information
1 parent
d0dd26a
commit abbfec2
Showing
2 changed files
with
177 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
[short] skip | ||
[!cgo] skip | ||
|
||
# Set up fresh GOCACHE | ||
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' | ||
|
||
-- go.mod -- | ||
module main | ||
|
||
go 1.18 | ||
-- main.go -- | ||
package main | ||
|
||
import "C" | ||
import ( | ||
"debug/dwarf" | ||
"fmt" | ||
"log" | ||
"os" | ||
"path/filepath" | ||
"strings" | ||
) | ||
|
||
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() | ||
} |