Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/tests/all/coredump.rs
1690 views
1
use anyhow::bail;
2
use wasmtime::*;
3
4
#[test]
5
#[cfg_attr(miri, ignore)]
6
fn coredump_attached_to_error() -> Result<()> {
7
let mut config = Config::default();
8
config.coredump_on_trap(true);
9
let engine = Engine::new(&config).unwrap();
10
let mut store = Store::<()>::new(&engine, ());
11
12
let wat = r#"
13
(module
14
(func $hello (import "" "hello"))
15
(func (export "run") (call $hello))
16
)
17
"#;
18
19
let module = Module::new(store.engine(), wat)?;
20
let hello_type = FuncType::new(store.engine(), None, None);
21
let hello_func = Func::new(&mut store, hello_type, |_, _, _| bail!("test 123"));
22
23
let instance = Instance::new(&mut store, &module, &[hello_func.into()])?;
24
let run_func = instance.get_typed_func::<(), ()>(&mut store, "run")?;
25
26
let e = run_func.call(&mut store, ()).unwrap_err();
27
assert!(format!("{e:?}").contains("test 123"));
28
29
assert!(
30
e.downcast_ref::<WasmCoreDump>().is_some(),
31
"error should contain a WasmCoreDump"
32
);
33
34
Ok(())
35
}
36
37
#[test]
38
#[cfg_attr(miri, ignore)]
39
fn coredump_has_stack() -> Result<()> {
40
let mut config = Config::default();
41
config.coredump_on_trap(true);
42
let engine = Engine::new(&config).unwrap();
43
let mut store = Store::<()>::new(&engine, ());
44
45
let wat = r#"
46
(module
47
(func $a (export "a")
48
call $b
49
)
50
(func $b
51
call $c
52
)
53
(func $c
54
unreachable
55
)
56
)
57
"#;
58
59
let module = Module::new(store.engine(), wat)?;
60
let instance = Instance::new(&mut store, &module, &[])?;
61
let a_func = instance.get_typed_func::<(), ()>(&mut store, "a")?;
62
63
let e = a_func.call(&mut store, ()).unwrap_err();
64
let cd = e.downcast_ref::<WasmCoreDump>().unwrap();
65
assert_eq!(cd.frames().len(), 3);
66
assert_eq!(cd.frames()[0].func_name().unwrap(), "c");
67
assert_eq!(cd.frames()[1].func_name().unwrap(), "b");
68
assert_eq!(cd.frames()[2].func_name().unwrap(), "a");
69
let _ = cd.serialize(&mut store, "stack");
70
Ok(())
71
}
72
73
#[test]
74
#[cfg_attr(miri, ignore)]
75
fn coredump_has_modules_and_instances() -> Result<()> {
76
let mut config = Config::default();
77
config.coredump_on_trap(true);
78
let engine = Engine::new(&config).unwrap();
79
let mut linker = Linker::new(&engine);
80
let mut store = Store::<()>::new(&engine, ());
81
82
let wat1 = r#"
83
(module $foo
84
(import "bar" "b" (func $b))
85
(func (export "a")
86
call $b
87
)
88
)
89
"#;
90
let wat2 = r#"
91
(module $bar
92
(func (export "b")
93
unreachable
94
)
95
)
96
"#;
97
let module1 = Module::new(store.engine(), wat1)?;
98
let module2 = Module::new(store.engine(), wat2)?;
99
let linking2 = linker.instantiate(&mut store, &module2)?;
100
linker.instance(&mut store, "bar", linking2)?;
101
102
let linking1 = linker.instantiate(&mut store, &module1)?;
103
let a_func = linking1.get_typed_func::<(), ()>(&mut store, "a")?;
104
105
let e = a_func.call(&mut store, ()).unwrap_err();
106
let cd = e.downcast_ref::<WasmCoreDump>().unwrap();
107
assert_eq!(cd.modules().len(), 2);
108
assert_eq!(cd.instances().len(), 2);
109
let _ = cd.serialize(&mut store, "modules-and-instances");
110
Ok(())
111
}
112
113
#[test]
114
#[cfg_attr(miri, ignore)]
115
fn coredump_has_host_globals_and_memory() -> Result<()> {
116
let mut config = Config::default();
117
config.coredump_on_trap(true);
118
let engine = Engine::new(&config).unwrap();
119
120
let module = Module::new(
121
&engine,
122
r#"
123
(module
124
(import "memory" "memory" (memory 1))
125
(global $myglobal (import "global" "global") (mut i32))
126
(func (export "a") (result i32)
127
unreachable
128
)
129
(export "memory" (memory 0))
130
(export "global" (global 0))
131
)
132
"#,
133
)?;
134
135
let mut store = Store::<()>::new(&engine, ());
136
let mut linker = Linker::new(&engine);
137
138
let memory = Memory::new(&mut store, MemoryType::new(1, None))?;
139
linker.define(&mut store, "memory", "memory", memory)?;
140
141
let global = Global::new(
142
&mut store,
143
GlobalType::new(ValType::I32, Mutability::Var),
144
Val::I32(0),
145
)?;
146
linker.define(&mut store, "global", "global", global)?;
147
148
let instance = linker.instantiate(&mut store, &module)?;
149
150
// Each time we extract the exports, it puts them in the `StoreData`. Our
151
// core dumps need to be robust to duplicate entries in the `StoreData`.
152
for _ in 0..10 {
153
let _ = instance.get_global(&mut store, "global").unwrap();
154
let _ = instance.get_memory(&mut store, "memory").unwrap();
155
}
156
157
let a_func = instance.get_typed_func::<(), i32>(&mut store, "a")?;
158
let err = a_func.call(&mut store, ()).unwrap_err();
159
let core_dump = err.downcast_ref::<WasmCoreDump>().unwrap();
160
assert_eq!(core_dump.globals().len(), 1);
161
assert_eq!(core_dump.memories().len(), 1);
162
assert_eq!(core_dump.instances().len(), 1);
163
let _ = core_dump.serialize(&mut store, "host-globals-and-memory");
164
165
Ok(())
166
}
167
168
#[test]
169
#[cfg_attr(miri, ignore)]
170
fn coredump_has_defined_globals_and_memory() -> Result<()> {
171
let mut config = Config::default();
172
config.coredump_on_trap(true);
173
let engine = Engine::new(&config).unwrap();
174
175
let module = Module::new(
176
&engine,
177
r#"
178
(module
179
(global (mut i32) (i32.const 42))
180
(memory 1)
181
(func (export "a")
182
unreachable
183
)
184
)
185
"#,
186
)?;
187
188
let mut store = Store::<()>::new(&engine, ());
189
let instance = Instance::new(&mut store, &module, &[])?;
190
191
let a_func = instance.get_typed_func::<(), ()>(&mut store, "a")?;
192
let err = a_func.call(&mut store, ()).unwrap_err();
193
let core_dump = err.downcast_ref::<WasmCoreDump>().unwrap();
194
assert_eq!(core_dump.globals().len(), 1);
195
assert_eq!(core_dump.memories().len(), 1);
196
assert_eq!(core_dump.instances().len(), 1);
197
let _ = core_dump.serialize(&mut store, "defined-globals-and-memory");
198
199
Ok(())
200
}
201
202
#[test]
203
#[cfg_attr(miri, ignore)]
204
fn multiple_globals_memories_and_instances() -> Result<()> {
205
let mut config = Config::default();
206
config.wasm_multi_memory(true);
207
config.coredump_on_trap(true);
208
let engine = Engine::new(&config).unwrap();
209
let mut store = Store::<()>::new(&engine, ());
210
let mut linker = Linker::new(&engine);
211
212
let memory = Memory::new(&mut store, MemoryType::new(1, None))?;
213
linker.define(&mut store, "host", "memory", memory)?;
214
215
let global = Global::new(
216
&mut store,
217
GlobalType::new(ValType::I32, Mutability::Var),
218
Val::I32(0),
219
)?;
220
linker.define(&mut store, "host", "global", global)?;
221
222
let module_a = Module::new(
223
&engine,
224
r#"
225
(module
226
(memory (export "memory") 1)
227
(global (export "global") (mut i32) (i32.const 0))
228
)
229
"#,
230
)?;
231
let instance_a = linker.instantiate(&mut store, &module_a)?;
232
linker.instance(&mut store, "a", instance_a)?;
233
234
let module_b = Module::new(
235
&engine,
236
r#"
237
(module
238
(import "host" "memory" (memory 1))
239
(import "host" "global" (global (mut i32)))
240
(import "a" "memory" (memory 1))
241
(import "a" "global" (global (mut i32)))
242
243
(func (export "trap")
244
unreachable
245
)
246
)
247
"#,
248
)?;
249
let instance_b = linker.instantiate(&mut store, &module_b)?;
250
251
let trap_func = instance_b.get_typed_func::<(), ()>(&mut store, "trap")?;
252
let err = trap_func.call(&mut store, ()).unwrap_err();
253
let core_dump = err.downcast_ref::<WasmCoreDump>().unwrap();
254
assert_eq!(core_dump.globals().len(), 2);
255
assert_eq!(core_dump.memories().len(), 2);
256
assert_eq!(core_dump.instances().len(), 2);
257
let _ = core_dump.serialize(&mut store, "multi");
258
259
Ok(())
260
}
261
262