Improve trap error messages (#831)
* Improve trap error messages The new trap error message for the issue #828 looks like: ``` thread 'main' panicked at 'a', /proc/self/fd/11:1:13 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. Error: failed to run main module `test.wasm` Caused by: 0: failed to invoke `_start` 1: wasm trap: unreachable, source location: @6cea wasm backtrace: 0: __rust_start_panic 1: rust_panic 2: std::panicking::rust_panic_with_hook::h57f0cff11449798f 3: std::panicking::begin_panic::hd620695467c5dd1f 4: test::main::ha54db001eabbde1b 5: std::rt::lang_start::{{closure}}::h5acfb82693695869 6: std::sys_common::backtrace::__rust_begin_short_backtrace::h39e8b9420da241f9 7: std::panicking::try::do_call::hb7ebfcd70d5f703e 8: __rust_maybe_catch_panic 9: std::rt::lang_start_internal::hd5f64f52a5c5315c 10: std::rt::lang_start::h2a51d79994dd0c4b 11: __original_main 12: _start ``` Closes #828 * Tidy up the style of the traps tests * Add some tests and module names
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
use anyhow::Result;
|
||||
use std::rc::Rc;
|
||||
use wasmtime::*;
|
||||
use wat::parse_str;
|
||||
|
||||
#[test]
|
||||
fn test_trap_return() -> Result<(), String> {
|
||||
fn test_trap_return() -> Result<()> {
|
||||
struct HelloCallback;
|
||||
|
||||
impl Callable for HelloCallback {
|
||||
@@ -13,24 +13,20 @@ fn test_trap_return() -> Result<(), String> {
|
||||
}
|
||||
|
||||
let store = Store::default();
|
||||
let binary = parse_str(
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module
|
||||
(func $hello (import "" "hello"))
|
||||
(func (export "run") (call $hello))
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;
|
||||
)?;
|
||||
|
||||
let module =
|
||||
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?;
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let hello_type = FuncType::new(Box::new([]), Box::new([]));
|
||||
let hello_func = Func::new(&store, hello_type, Rc::new(HelloCallback));
|
||||
|
||||
let imports = vec![hello_func.into()];
|
||||
let instance = Instance::new(&module, &imports)
|
||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||
let instance = Instance::new(&module, &[hello_func.into()])?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
@@ -43,22 +39,19 @@ fn test_trap_return() -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trap_trace() -> Result<(), String> {
|
||||
fn test_trap_trace() -> Result<()> {
|
||||
let store = Store::default();
|
||||
let binary = parse_str(
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $hello_mod
|
||||
(func (export "run") (call $hello))
|
||||
(func $hello (unreachable))
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;
|
||||
)?;
|
||||
|
||||
let module =
|
||||
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?;
|
||||
let instance = Instance::new(&module, &[])
|
||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[])?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
@@ -79,7 +72,7 @@ fn test_trap_trace() -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trap_trace_cb() -> Result<(), String> {
|
||||
fn test_trap_trace_cb() -> Result<()> {
|
||||
struct ThrowCallback;
|
||||
|
||||
impl Callable for ThrowCallback {
|
||||
@@ -89,7 +82,7 @@ fn test_trap_trace_cb() -> Result<(), String> {
|
||||
}
|
||||
|
||||
let store = Store::default();
|
||||
let binary = parse_str(
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $hello_mod
|
||||
(import "" "throw" (func $throw))
|
||||
@@ -97,16 +90,13 @@ fn test_trap_trace_cb() -> Result<(), String> {
|
||||
(func $hello (call $throw))
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;
|
||||
)?;
|
||||
|
||||
let fn_type = FuncType::new(Box::new([]), Box::new([]));
|
||||
let fn_func = Func::new(&store, fn_type, Rc::new(ThrowCallback));
|
||||
|
||||
let module =
|
||||
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?;
|
||||
let instance = Instance::new(&module, &[fn_func.into()])
|
||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[fn_func.into()])?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
@@ -125,21 +115,18 @@ fn test_trap_trace_cb() -> Result<(), String> {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_trap_stack_overflow() -> Result<(), String> {
|
||||
fn test_trap_stack_overflow() -> Result<()> {
|
||||
let store = Store::default();
|
||||
let binary = parse_str(
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $rec_mod
|
||||
(func $run (export "run") (call $run))
|
||||
)
|
||||
"#,
|
||||
)
|
||||
.map_err(|e| format!("failed to parse WebAssembly text source: {}", e))?;
|
||||
)?;
|
||||
|
||||
let module =
|
||||
Module::new(&store, &binary).map_err(|e| format!("failed to compile module: {}", e))?;
|
||||
let instance = Instance::new(&module, &[])
|
||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[])?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
@@ -151,9 +138,94 @@ fn test_trap_stack_overflow() -> Result<(), String> {
|
||||
for i in 0..trace.len() {
|
||||
assert_eq!(trace[i].module_name().unwrap(), "rec_mod");
|
||||
assert_eq!(trace[i].func_index(), 0);
|
||||
assert_eq!(trace[1].func_name(), Some("run"));
|
||||
assert_eq!(trace[i].func_name(), Some("run"));
|
||||
}
|
||||
assert!(e.message().contains("call stack exhausted"));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trap_display_pretty() -> Result<()> {
|
||||
let store = Store::default();
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $m
|
||||
(func $die unreachable)
|
||||
(func call $die)
|
||||
(func $foo call 1)
|
||||
(func (export "bar") call $foo)
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[])?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
|
||||
let e = run_func.call(&[]).err().expect("error calling function");
|
||||
assert_eq!(
|
||||
e.to_string(),
|
||||
"\
|
||||
wasm trap: unreachable, source location: @0023
|
||||
wasm backtrace:
|
||||
0: m!die
|
||||
1: m!<wasm function 1>
|
||||
2: m!foo
|
||||
3: m!<wasm function 3>
|
||||
"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trap_display_multi_module() -> Result<()> {
|
||||
let store = Store::default();
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $a
|
||||
(func $die unreachable)
|
||||
(func call $die)
|
||||
(func $foo call 1)
|
||||
(func (export "bar") call $foo)
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[])?;
|
||||
let bar = instance.exports()[0].clone();
|
||||
|
||||
let binary = wat::parse_str(
|
||||
r#"
|
||||
(module $b
|
||||
(import "" "" (func $bar))
|
||||
(func $middle call $bar)
|
||||
(func (export "bar2") call $middle)
|
||||
)
|
||||
"#,
|
||||
)?;
|
||||
let module = Module::new(&store, &binary)?;
|
||||
let instance = Instance::new(&module, &[bar])?;
|
||||
let bar2 = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
|
||||
let e = bar2.call(&[]).err().expect("error calling function");
|
||||
assert_eq!(
|
||||
e.to_string(),
|
||||
"\
|
||||
wasm trap: unreachable, source location: @0023
|
||||
wasm backtrace:
|
||||
0: a!die
|
||||
1: a!<wasm function 1>
|
||||
2: a!foo
|
||||
3: a!<wasm function 3>
|
||||
4: b!middle
|
||||
5: b!<wasm function 2>
|
||||
"
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user