refuse to delete unknown files with -debugdir

When creating a new debugdir directory, add a sentinel .garble-debugdir
file at its root so that we can later know that we created it
and the user is very unlikely to have left important data there.

When emptying an existing debugdir directory, only do so if it has
that sentinel file, for added safety.

Fixes #932.
pull/940/head
Daniel Martí 2 weeks ago
parent 8ee4c91196
commit a3a92356d9

@ -602,16 +602,30 @@ This command wraps "go %s". Below is its help:
os.Setenv("GARBLE_SHARED", sharedTempDir) os.Setenv("GARBLE_SHARED", sharedTempDir)
if flagDebugDir != "" { if flagDebugDir != "" {
origDir := flagDebugDir
flagDebugDir, err = filepath.Abs(flagDebugDir) flagDebugDir, err = filepath.Abs(flagDebugDir)
if err != nil { if err != nil {
return nil, err return nil, err
} }
sentinel := filepath.Join(flagDebugDir, ".garble-debugdir")
if err := os.RemoveAll(flagDebugDir); err != nil { if entries, err := os.ReadDir(flagDebugDir); errors.Is(err, fs.ErrNotExist) {
return nil, fmt.Errorf("could not empty debugdir: %v", err) } else if err == nil && len(entries) == 0 {
// It's OK to delete an existing directory as long as it's empty.
} else if _, err := os.Lstat(sentinel); err == nil {
// It's OK to delete a non-empty directory which was created by an earlier
// invocation of `garble -debugdir`, which we know by leaving a sentinel file.
if err := os.RemoveAll(flagDebugDir); err != nil {
return nil, fmt.Errorf("could not empty debugdir: %v", err)
}
} else {
return nil, fmt.Errorf("debugdir %q has unknown contents; empty it first", origDir)
} }
if err := os.MkdirAll(flagDebugDir, 0o755); err != nil { if err := os.MkdirAll(flagDebugDir, 0o755); err != nil {
return nil, err return nil, fmt.Errorf("could not create debugdir directory: %v", err)
}
if err := os.WriteFile(sentinel, nil, 0o666); err != nil {
return nil, fmt.Errorf("could not create debugdir sentinel: %v", err)
} }
} }

@ -1,4 +1,4 @@
exec garble -debugdir ./debug1 build exec garble -debugdir=debug1 build
exists 'debug1/test/main/imported/imported.go' 'debug1/test/main/main.go' 'debug1/reflect/type.go' exists 'debug1/test/main/imported/imported.go' 'debug1/test/main/main.go' 'debug1/reflect/type.go'
exists 'debug1/runtime/error.go' 'debug1/runtime/funcdata.h' 'debug1/runtime/asm.s' exists 'debug1/runtime/error.go' 'debug1/runtime/funcdata.h' 'debug1/runtime/asm.s'
[amd64] exists 'debug1/runtime/cpuflags_amd64.go' 'debug1/runtime/asm_amd64.s' [amd64] exists 'debug1/runtime/cpuflags_amd64.go' 'debug1/runtime/asm_amd64.s'
@ -7,14 +7,26 @@ exists 'debug1/runtime/error.go' 'debug1/runtime/funcdata.h' 'debug1/runtime/asm
! grep ImportedFunc $WORK/debug1/test/main/main.go ! grep ImportedFunc $WORK/debug1/test/main/main.go
! grep 'some comment' $WORK/debug1/test/main/main.go ! grep 'some comment' $WORK/debug1/test/main/main.go
# We should refuse to delete non-empty directories which weren't created
# by an earlier invocation of garble -debugdir, as that could lead to data loss.
! exec garble -debugdir=notdebug build
stderr 'debugdir "notdebug" has unknown contents; empty it first'
exists notdebug/important_data.txt
exists notdebug/subdir/important_data.txt
[short] stop [short] stop
# Sources from previous builds should be deleted # Sources from previous builds should be deleted
cp $WORK/debug1/test/main/main.go $WORK/debug1/some_file_from_prev_build.go cp $WORK/debug1/test/main/main.go $WORK/debug1/some_file_from_prev_build.go
exec garble -debugdir ./debug1 build -v exec garble -debugdir=debug1 build -v
stderr 'test/main' # we force rebuilds with -debugdir stderr 'test/main' # we force rebuilds with -debugdir
! exists $WORK/debug1/some_file_from_prev_build.go ! exists $WORK/debug1/some_file_from_prev_build.go
-- notdebug/important_data.txt --
This file should not be deleted by -debugdir.
-- notdebug/subdir/important_data.txt --
This file should not be deleted by -debugdir.
-- go.mod -- -- go.mod --
module test/main module test/main

Loading…
Cancel
Save