make output binaries deterministic

We were leaking temporary file paths, which is no longer the case.
pull/22/head
Daniel Martí 5 years ago
parent 22e7e4e848
commit 0058dfc12a

@ -18,7 +18,7 @@ information about the original source code as possible.
The tool is designed to be:
* Coupled with `cmd/go`, to support both `GOPATH` and modules with ease
* Deterministic, though the output is not yet reproducible
* Deterministic and reproducible, given the same initial source code
* Reversible given the original source, to un-garble panic stack traces
### Mechanism

@ -197,10 +197,24 @@ func transformCompile(args []string) ([]string, error) {
return nil, fmt.Errorf("typecheck error: %v", err)
}
tempDir, err := ioutil.TempDir("", "garble-build")
if err != nil {
return nil, err
}
deferred = append(deferred, func() error {
return os.RemoveAll(tempDir)
})
// Add our temporary dir to the beginning of -trimpath, so that we don't
// leak temporary dirs. Needs to be at the beginning, since there may be
// shorter prefixes later in the list, such as $PWD if TMPDIR=$PWD/tmp.
flags = flagSetValue(flags, "-trimpath", tempDir+"=>;"+trimpath)
// log.Println(flags)
args = flags
for _, file := range files {
// TODO: randomize the order and names of the files
for i, file := range files {
file := transformGo(file, info)
f, err := ioutil.TempFile("", "garble")
tempFile := filepath.Join(tempDir, fmt.Sprintf("z%d.go", i))
f, err := os.Create(tempFile)
if err != nil {
return nil, err
}
@ -212,9 +226,6 @@ func transformCompile(args []string) ([]string, error) {
if err := f.Close(); err != nil {
return nil, err
}
deferred = append(deferred, func() error {
return os.Remove(f.Name())
})
args = append(args, f.Name())
}
return args, nil
@ -397,3 +408,31 @@ func flagValue(flags []string, name string) string {
}
return ""
}
func flagSetValue(flags []string, name, value string) []string {
for i, arg := range flags {
if strings.HasPrefix(arg, name+"=") {
// -name=value
if value == "true" {
flags[i] = name
} else {
flags[i] = name + "=" + value
}
return flags
}
if arg == name {
if i+1 < len(flags) {
if val := flags[i+1]; !strings.HasPrefix(val, "-") {
flags[i+1] = value
return flags
}
}
// -name, equivalent to -name=true
if value != "true" {
flags[i] = name + "=" + value
}
return flags
}
}
return append(flags, name+"="+value)
}

@ -7,6 +7,7 @@ import (
"flag"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
@ -95,7 +96,14 @@ func bincmp(ts *testscript.TestScript, neg bool, args []string) {
data1 := ts.ReadFile(args[0])
data2 := ts.ReadFile(args[1])
if data1 != data2 {
if _, err := exec.LookPath("diffoscope"); err != nil {
ts.Logf("diffoscope is not installing; skipping binary diff")
} else {
// We'll error below; ignore the exec error here.
ts.Exec("diffoscope", ts.MkAbs(args[0]), ts.MkAbs(args[1]))
}
sizeDiff := len(data2) - len(data1)
ts.Fatalf("%s and %s differ; size diff: %+d", args[0], args[1], sizeDiff)
ts.Fatalf("%s and %s differ; diffoscope above, size diff: %+d",
args[0], args[1], sizeDiff)
}
}

@ -26,11 +26,13 @@ cmp stderr main.stderr
! bingrep main$exe ${WORK@R} 'globalVar' 'globalFunc'
# Finally, check that the 'garble build' shortcut works.
# cp main main_old
# Finally, check that the 'garble build' shortcut works, and produces the same
# binary.
cp main main_old
rm main
garble build main.go
! bingrep main$exe 'globalVar'
# bincmp main main_old
bincmp main main_old
-- main.go --
package main

@ -4,6 +4,12 @@ cmp stdout main.stdout
! bingrep main$exe 'ImportedVar' 'ImportedConst' 'ImportedFunc' 'ImportedType'
# Also check that the binary is reproducible when many imports are involved.
cp main main_old
rm main
garble build
bincmp main main_old
-- go.mod --
module foo.com/main
-- main.go --

Loading…
Cancel
Save