env GOPRIVATE=test/main # Unknown build flags should result in errors. ! garble reverse -badflag stderr 'flag provided but not defined' garble build exec ./main cp stderr main.stderr exec cat main.stderr # Ensure that the garbled panic output looks correct. # This output is not reproducible between 'go test' runs, # so we can't use a static golden file. grep 'goroutine 1 \[running\]' main.stderr ! grep 'ExportedLibFunc|unexportedMainFunc|test/main|main.go|lib.go' main.stderr stdin main.stderr garble reverse stdout -count=1 'test/main/lib\.ExportedLibFunc' stdout -count=1 'main\.unexportedMainFunc' # TODO: this is what we want when "reverse" is finished # cmp stdout reverse.stdout # Ensure that the reversed output matches the non-garbled output. go build -trimpath exec ./main cmp stderr reverse.stdout -- go.mod -- module test/main go 1.15 -- main.go -- package main import ( "os" "test/main/lib" ) func main() { unexportedMainFunc() } func unexportedMainFunc() { if err := lib.ExportedLibFunc(os.Stderr); err != nil { panic(err) } } -- lib/lib.go -- package lib import ( "io" "regexp" "runtime/debug" ) func ExportedLibFunc(w io.Writer) error { // Panic outputs include "0xNN" pointers and offsets which change // between platforms. // Strip them out here, to have portable static stdout files. rxVariableSuffix := regexp.MustCompile(`0x[0-9a-f]+`) stack := debug.Stack() stack = rxVariableSuffix.ReplaceAll(stack, []byte("0x??")) _, err := w.Write(stack) return err } -- reverse.stdout -- goroutine 1 [running]: runtime/debug.Stack(0x??, 0x??, 0x??) runtime/debug/stack.go:24 +0x?? test/main/lib.ExportedLibFunc(0x??, 0x??, 0x??, 0x??) test/main/lib/lib.go:15 +0x?? main.unexportedMainFunc(...) test/main/main.go:14 main.main() test/main/main.go:10 +0x??