Exit with a more severe error code if the program traps. (#1274)

* Exit with a more severe error code if the program traps.

Previously, the wasmtime CLI would return with a regular failure
error code, such as 1 on Unix. However, a program trap indicates a bug
in the program, which can be useful to distinguish from a simple error
status. Check for the trap case, and return an appropriate OS-specific
exit status.

* Use a loop to iterate over the error causes to find Traps.

* Use anyhow's `chain()` iterator.

* For completeness, handle non-Unix and non-Windows platforms too.

* Add a CLI test for a trapping program.

* Replace a manual `.cause` loop with a `.is` call.

* Correct the expected exit status on Windows.

* Use assert_eq/assert_ne so that if these fail, it prints the output.
This commit is contained in:
Dan Gohman
2020-03-11 13:12:26 -07:00
committed by GitHub
parent 81d9a5e6db
commit d44384da8a
3 changed files with 66 additions and 6 deletions

View File

@@ -6,10 +6,11 @@ use std::{
ffi::{OsStr, OsString},
fs::File,
path::{Component, Path, PathBuf},
process,
};
use structopt::{clap::AppSettings, StructOpt};
use wasi_common::preopen_dir;
use wasmtime::{Engine, Instance, Module, Store};
use wasmtime::{Engine, Instance, Module, Store, Trap};
use wasmtime_interface_types::ModuleData;
use wasmtime_wasi::{old::snapshot_0::Wasi as WasiSnapshot0, Wasi};
@@ -113,8 +114,31 @@ impl RunCommand {
}
// Load the main wasm module.
self.handle_module(&store, &module_registry)
.with_context(|| format!("failed to run main module `{}`", self.module.display()))?;
match self
.handle_module(&store, &module_registry)
.with_context(|| format!("failed to run main module `{}`", self.module.display()))
{
Ok(()) => (),
Err(e) => {
// If the program exited because of a trap, return an error code
// to the outside environment indicating a more severe problem
// than a simple failure.
if e.is::<Trap>() {
// Print the error message in the usual way.
eprintln!("Error: {:?}", e);
if cfg!(unix) {
// On Unix, return the error code of an abort.
process::exit(128 + libc::SIGABRT);
} else if cfg!(windows) {
// On Windows, return 3.
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/abort?view=vs-2019
process::exit(3);
}
}
return Err(e);
}
}
Ok(())
}