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 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