support reverse on packages using cgo

The reverse feature relied on `GoFiles` from `go list`,
but that list may not be enough to typecheck a package:

	typecheck error: $WORK/main.go:3:15: undeclared name: longMain

`go help list` shows:

	GoFiles         []string   // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
	CgoFiles        []string   // .go source files that import "C"
	CompiledGoFiles []string   // .go files presented to compiler (when using -compiled)

In other words, to mimic the same list of Go files fed to the compiler,
we want CompiledGoFiles.

Note that, since the cgo files show up as generated files,
we currently do not support reversing their filenames.
That is left as a TODO for now.

Updates #555.
pull/585/head
Daniel Martí 2 years ago
parent fc91758b49
commit e8e06f6ad6

@ -80,9 +80,14 @@ One can reverse a captured panic stack trace as follows:
addHashedWithPackage(lpkg.ImportPath) addHashedWithPackage(lpkg.ImportPath)
var files []*ast.File var files []*ast.File
for _, goFile := range lpkg.GoFiles { for _, goFile := range lpkg.CompiledGoFiles {
fullGoFile := filepath.Join(lpkg.Dir, goFile) // Direct Go files may be relative paths like "foo.go".
file, err := parser.ParseFile(fset, fullGoFile, nil, parser.SkipObjectResolution) // Compiled Go files, such as those generated from cgo,
// may be absolute paths inside the Go build cache.
if !filepath.IsAbs(goFile) {
goFile = filepath.Join(lpkg.Dir, goFile)
}
file, err := parser.ParseFile(fset, goFile, nil, parser.SkipObjectResolution)
if err != nil { if err != nil {
return err return err
} }
@ -93,7 +98,7 @@ One can reverse a captured panic stack trace as follows:
return err return err
} }
for i, file := range files { for i, file := range files {
goFile := lpkg.GoFiles[i] goFile := lpkg.CompiledGoFiles[i]
ast.Inspect(file, func(node ast.Node) bool { ast.Inspect(file, func(node ast.Node) bool {
switch node := node.(type) { switch node := node.(type) {

@ -140,10 +140,10 @@ type listedPackage struct {
ImportMap map[string]string ImportMap map[string]string
Standard bool Standard bool
Dir string Dir string
GoFiles []string CompiledGoFiles []string
Imports []string Imports []string
Incomplete bool Incomplete bool
// The fields below are not part of 'go list', but are still reused // The fields below are not part of 'go list', but are still reused
// between garble processes. Use "Garble" as a prefix to ensure no // between garble processes. Use "Garble" as a prefix to ensure no
@ -180,7 +180,7 @@ func appendListedPackages(packages []string, withDeps bool) error {
// TODO: perhaps include all top-level build flags set by garble, // TODO: perhaps include all top-level build flags set by garble,
// including -buildvcs=false. // including -buildvcs=false.
// They shouldn't affect "go list" here, but might as well be consistent. // They shouldn't affect "go list" here, but might as well be consistent.
args := []string{"list", "-json", "-export", "-trimpath", "-e"} args := []string{"list", "-json", "-export", "-compiled", "-trimpath", "-e"}
if withDeps { if withDeps {
args = append(args, "-deps") args = append(args, "-deps")
} }

@ -10,6 +10,15 @@ cmp stdout main.stdout
[short] stop # no need to verify this with -short [short] stop # no need to verify this with -short
# Ensure that reversing works with cgo.
env GARBLE_TEST_REVERSING=true
exec ./main
cp stdout reversing.stdout
stdin reversing.stdout
garble reverse .
cmp stdout reversed.stdout
env GARBLE_TEST_REVERSING=false
env GOGARBLE=* env GOGARBLE=*
garble build garble build
exec ./main exec ./main
@ -33,7 +42,34 @@ go 1.18
-- main.go -- -- main.go --
package main package main
import "os/user" func main() {
regularFunc()
cgoFunc()
}
-- regular_main.go --
package main
import (
"fmt"
"os"
"runtime"
)
func regularFunc() {
if os.Getenv("GARBLE_TEST_REVERSING") == "true" {
_, filename, _, _ := runtime.Caller(0)
fmt.Println("regular filename:", filename)
}
}
-- cgo_main.go --
package main
import (
"fmt"
"os"
"os/user"
"runtime"
)
/* /*
#include "separate.h" #include "separate.h"
@ -54,9 +90,8 @@ struct portedStruct {
}; };
*/ */
import "C" import "C"
import "fmt"
func main() { func cgoFunc() {
fmt.Println(C.privateAdd(C.int(1), C.int(2))) fmt.Println(C.privateAdd(C.int(1), C.int(2)))
_, _ = user.Current() _, _ = user.Current()
@ -69,6 +104,11 @@ func main() {
//export goCallback //export goCallback
func goCallback() { func goCallback() {
fmt.Println("go callback") fmt.Println("go callback")
// TODO: support reversing filenames in cgo files
if false && os.Getenv("GARBLE_TEST_REVERSING") == "true" {
_, filename, _, _ := runtime.Caller(0)
fmt.Println("cgo filename:", filename)
}
} }
-- separate.h -- -- separate.h --
void separateFunction(); void separateFunction();
@ -83,3 +123,9 @@ void separateFunction() {
true true
go callback go callback
go callback go callback
-- reversed.stdout --
regular filename: test/main/regular_main.go
3
true
go callback
go callback

Loading…
Cancel
Save