Skip to content

Commit ec9a1dd

Browse files
committed
fix: handle NULL method in LMF during WASM exception unwinding
When hot reload applies metadata deltas across multiple generations, the LMF (Last Managed Frame) chain can contain entries with NULL method pointers — caused by partially initialized JIT frames during skeleton type creation or ALC unloading. WASM is the only architecture that hard-asserts on (*lmf)->method (exceptions-wasm.c:66). x86 returns FALSE gracefully; AMD64/ARM64 don't depend on the method field at all. - Add patch 0005 to Uno.DotnetRuntime.WebAssembly: skip NULL method LMF entries and return FALSE, matching x86 behavior - Add WASM runtime test exercising multi-generation hot reload via MetadataUpdater.ApplyUpdate with Roslyn EmitDifference deltas
1 parent cafd697 commit ec9a1dd

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: Studio Live <noreply@platform.uno>
3+
Date: Wed, 09 Apr 2026 00:00:00 +0000
4+
Subject: [PATCH] fix: handle NULL method in LMF during WASM exception
5+
unwinding
6+
7+
During hot reload or ALC (AssemblyLoadContext) unloading, LMF (Last
8+
Managed Frame) entries can have a NULL method pointer — the method may
9+
have been invalidated by a metadata delta or collected when the ALC was
10+
unloaded. The existing code crashes with g_assert((*lmf)->method) in
11+
mono_arch_unwind_frame (exceptions-wasm.c:66).
12+
13+
WASM is the only architecture that hard-asserts on the method field.
14+
x86 handles this gracefully:
15+
if (!(*lmf)->method) return FALSE;
16+
AMD64 and ARM64 do not depend on the method field at all.
17+
18+
Follow the x86 pattern: when an LMF entry has a NULL method, advance
19+
the LMF chain past the bad entry and return FALSE to stop unwinding
20+
gracefully. This prevents a hard runtime abort while allowing the
21+
runtime to continue operating.
22+
23+
Fixes: unoplatform/studio.live#1406
24+
---
25+
src/mono/mono/mini/exceptions-wasm.c | 9 ++++++---
26+
1 file changed, 6 insertions(+), 3 deletions(-)
27+
28+
diff --git a/src/mono/mono/mini/exceptions-wasm.c b/src/mono/mono/mini/exceptions-wasm.c
29+
index 4bf30f05162..dc3853e7c3f 100644
30+
--- a/src/mono/mono/mini/exceptions-wasm.c
31+
+++ b/src/mono/mono/mini/exceptions-wasm.c
32+
@@ -62,8 +62,13 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls,
33+
if (*lmf == jit_tls->first_lmf)
34+
return FALSE;
35+
36+
- /* This will compute the original method address */
37+
- g_assert ((*lmf)->method);
38+
+ /* LMF entry with NULL method can occur during hot reload
39+
+ * (method invalidated) or ALC unloading (assembly collected).
40+
+ * Skip the bad entry and stop unwinding, matching x86 behavior. */
41+
+ if (!(*lmf)->method) {
42+
+ *lmf = (MonoLMF *)(((guint64)(*lmf)->previous_lmf) & ~3);
43+
+ return FALSE;
44+
+ }
45+
gpointer addr = mono_compile_method_checked ((*lmf)->method, error);
46+
mono_error_assert_ok (error);
47+
48+
--
49+
2.43.0
50+

0 commit comments

Comments
 (0)