sbox: print failing command line before output

The full command line run inside sbox can be very long, and printing it
after the errors printed by the failing command can hide the error
messages.  Buffer the output of the command and print the failing command
line before the output if it fails.

Bug: 185516277
Test: m out/soong/.intermediates/frameworks/base/system-api-stubs-docs-non-updatable/android_common/metalava/api_lint.timestamp with lint error
Change-Id: I893f3dd01f1baf195e182111c5c49e92eb82f3b0
This commit is contained in:
Colin Cross 2021-04-15 18:50:11 -07:00
parent fc2d842dfd
commit 4258a39bd1
1 changed files with 18 additions and 7 deletions

View File

@ -255,12 +255,11 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er
return "", err return "", err
} }
commandDescription := rawCommand
cmd := exec.Command("bash", "-c", rawCommand) cmd := exec.Command("bash", "-c", rawCommand)
buf := &bytes.Buffer{}
cmd.Stdin = os.Stdin cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout cmd.Stdout = buf
cmd.Stderr = os.Stderr cmd.Stderr = buf
if command.GetChdir() { if command.GetChdir() {
cmd.Dir = tempDir cmd.Dir = tempDir
@ -284,9 +283,21 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er
copyFiles(command.CopyAfter, tempDir, "", true) copyFiles(command.CopyAfter, tempDir, "", true)
} }
// If the command was executed but failed with an error, print a debugging message before
// the command's output so it doesn't scroll the real error message off the screen.
if exit, ok := err.(*exec.ExitError); ok && !exit.Success() { if exit, ok := err.(*exec.ExitError); ok && !exit.Success() {
return "", fmt.Errorf("sbox command failed with err:\n%s\n%w\n", commandDescription, err) fmt.Fprintf(os.Stderr,
} else if err != nil { "The failing command was run inside an sbox sandbox in temporary directory\n"+
"%s\n"+
"The failing command line was:\n"+
"%s\n",
tempDir, rawCommand)
}
// Write the command's combined stdout/stderr.
os.Stdout.Write(buf.Bytes())
if err != nil {
return "", err return "", err
} }
@ -298,7 +309,7 @@ func runCommand(command *sbox_proto.Command, tempDir string) (depFile string, er
// build error message // build error message
errorMessage := "mismatch between declared and actual outputs\n" errorMessage := "mismatch between declared and actual outputs\n"
errorMessage += "in sbox command(" + commandDescription + ")\n\n" errorMessage += "in sbox command(" + rawCommand + ")\n\n"
errorMessage += "in sandbox " + tempDir + ",\n" errorMessage += "in sandbox " + tempDir + ",\n"
errorMessage += fmt.Sprintf("failed to create %v files:\n", len(missingOutputErrors)) errorMessage += fmt.Sprintf("failed to create %v files:\n", len(missingOutputErrors))
for _, missingOutputError := range missingOutputErrors { for _, missingOutputError := range missingOutputErrors {