Skip to content

Commit 3b07e0e

Browse files
committed
Fix core dumps for composed components
Signed-off-by: subotac <73706465+subotac@users.noreply.github.com>
1 parent e8ac8c2 commit 3b07e0e

2 files changed

Lines changed: 71 additions & 2 deletions

File tree

crates/wasmtime/src/runtime/coredump.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::hash_map::HashMap;
2+
use crate::hash_set::HashSet;
23
use crate::prelude::*;
34
use crate::{
45
AsContextMut, FrameInfo, Global, HeapType, Instance, Memory, Module, StoreContextMut, Val,
@@ -48,8 +49,27 @@ impl WasmCoreDump {
4849
let store_memories: Vec<Memory> =
4950
store.all_memories().filter_map(|m| m.unshared()).collect();
5051

51-
let mut store_globals: Vec<Global> = vec![];
52-
store.for_each_global(|_store, global| store_globals.push(global));
52+
let mut store_globals = Vec::new();
53+
let mut seen_globals = HashSet::new();
54+
store.for_each_global(|store, global| {
55+
seen_globals.insert(global.hash_key(store));
56+
store_globals.push(global);
57+
});
58+
59+
// Component adapters can import synthetic globals that aren't defined
60+
// by a core instance and therefore aren't visited above. Include every
61+
// global visible to an instance so serialization can reference it.
62+
for instance in &instances {
63+
let globals = instance
64+
.all_globals(store)
65+
.map(|(_, global)| global)
66+
.collect::<Vec<_>>();
67+
for global in globals {
68+
if seen_globals.insert(global.hash_key(store)) {
69+
store_globals.push(global);
70+
}
71+
}
72+
}
5373

5474
WasmCoreDump {
5575
name: String::from("store_name"),

tests/all/coredump.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,52 @@ fn core_dump_with_shared_memory() -> Result<()> {
293293

294294
Ok(())
295295
}
296+
297+
#[test]
298+
#[cfg_attr(miri, ignore)]
299+
fn coredump_with_composed_component_adapters() -> Result<()> {
300+
use wasmtime::component::{Component, Linker};
301+
302+
let mut config = Config::new();
303+
config.coredump_on_trap(true);
304+
let engine = Engine::new(&config)?;
305+
let component = Component::new(
306+
&engine,
307+
r#"
308+
(component
309+
(component $A
310+
(core module $m
311+
(func (export "f") (param i32) (result i32) unreachable)
312+
)
313+
(core instance $i (instantiate $m))
314+
(func (export "f") (param "x" u32) (result u32)
315+
(canon lift (core func $i "f")))
316+
)
317+
(component $B
318+
(import "f" (func $f (param "x" u32) (result u32)))
319+
(core func $fl (canon lower (func $f)))
320+
(core module $m
321+
(import "" "f" (func $f (param i32) (result i32)))
322+
(func (export "run") (call $f (i32.const 1)) drop)
323+
)
324+
(core instance $i (instantiate $m
325+
(with "" (instance (export "f" (func $fl))))))
326+
(func (export "run") (canon lift (core func $i "run")))
327+
)
328+
(instance $a (instantiate $A))
329+
(instance $b (instantiate $B (with "f" (func $a "f"))))
330+
(func (export "run") (alias export $b "run"))
331+
)
332+
"#,
333+
)?;
334+
let mut store = Store::new(&engine, ());
335+
let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
336+
let run = instance.get_typed_func::<(), ()>(&mut store, "run")?;
337+
338+
let err = run.call(&mut store, ()).unwrap_err();
339+
let coredump = err.downcast_ref::<WasmCoreDump>().unwrap();
340+
let bytes = coredump.serialize(&mut store, "composed-component-adapters");
341+
wasmparser::Validator::new().validate_all(&bytes)?;
342+
343+
Ok(())
344+
}

0 commit comments

Comments
 (0)