1 //! An example of how to configure capturing core dumps when the guest Wasm
2 //! traps that can then be passed to external tools for post-mortem analysis.
3
4 // You can execute this example with `cargo run --example coredump`.
5
6 use wasmtime::*;
7
main() -> Result<()>8 fn main() -> Result<()> {
9 println!("Configure core dumps to be captured on trap.");
10 let mut config = Config::new();
11 config.coredump_on_trap(true);
12 let engine = Engine::new(&config)?;
13 let mut store = Store::new(&engine, ());
14
15 println!("Define a Wasm module that will mutate local state and then trap.");
16 let module = Module::new(
17 store.engine(),
18 r#"
19 (module $trapper
20 (memory 10)
21 (global $g (mut i32) (i32.const 0))
22
23 (func (export "run")
24 call $a
25 )
26
27 (func $a
28 i32.const 0x1234
29 i64.const 42
30 i64.store
31 call $b
32 )
33
34 (func $b
35 i32.const 36
36 global.set $g
37 call $c
38 )
39
40 (func $c
41 unreachable
42 )
43 )
44 "#,
45 )?;
46
47 println!("Instantiate the module.");
48 let instance = Instance::new(&mut store, &module, &[])?;
49
50 println!("Invoke its 'run' function.");
51 let run = instance
52 .get_func(&mut store, "run")
53 .expect("should have 'run' export");
54 let args = &[];
55 let results = &mut [];
56 let ok = run.call(&mut store, args, results);
57
58 println!("Calling that function trapped.");
59 assert!(ok.is_err());
60 let err = ok.unwrap_err();
61 assert!(err.is::<Trap>());
62
63 println!("Extract the captured core dump.");
64 let dump = err
65 .downcast_ref::<WasmCoreDump>()
66 .expect("should have an attached core dump, since we configured core dumps on");
67
68 println!(
69 "Number of memories in the core dump: {}",
70 dump.memories().len()
71 );
72 for (i, mem) in dump.memories().iter().enumerate() {
73 if let Some(addr) = mem.data(&store).iter().position(|byte| *byte != 0) {
74 let val = mem.data(&store)[addr];
75 println!(" First nonzero byte for memory {i}: {val} @ {addr:#x}");
76 } else {
77 println!(" Memory {i} is all zeroes.");
78 }
79 }
80
81 println!(
82 "Number of globals in the core dump: {}",
83 dump.globals().len()
84 );
85 for (i, global) in dump.globals().iter().enumerate() {
86 let val = global.get(&mut store);
87 println!(" Global {i} = {val:?}");
88 }
89
90 println!("Serialize the core dump and write it to ./example.coredump");
91 let serialized = dump.serialize(&mut store, "trapper.wasm");
92 std::fs::write("./example.coredump", serialized)?;
93
94 Ok(())
95 }
96