wasm-emu: rule out function-table reuse (E18); consolidate race diagnosis

This commit is contained in:
2026-07-22 21:57:51 -04:00
parent c608b65ef5
commit 3c6e85a7fe
3 changed files with 35 additions and 1 deletions
+33
View File
@@ -537,3 +537,36 @@ device/timer callbacks are properly serialized against vCPU stores (BQL/memory
barriers), or run device memory access on the vCPU thread. Opt-in repro/debug
controls now available: `?nostoretci`, `?sthash`, `?stcw/stcmask/stcval`,
`?yieldtrace`. Production default remains blanket store-TCI.
## E18: not dynamic function-table churn either
Confirmed the threading model: the build uses `-pthread -sPROXY_TO_PTHREAD=1
-sASYNCIFY=1`, and `qemu_thread_create` runs the vCPU in its own pthread,
concurrent with the main/IO-loop thread over shared memory. So a genuine
guest-RAM data race is possible.
Tested the most tractable non-thread hypothesis first: each compiled TB adds a
WASM table function and batch-`removeFunction`s once >500 removals are pending;
more compiled stores (both widths) means more churn, which is timing-dependent.
Added opt-in `?noremove` (`wasm_set_disable_tb_removal`) to leak functions
instead of recycling table indices.
Result: `?nostoretci&noremove` crashed 4/4 (Load access faults). Recycling of
WASM table indices is **not** the corruption source.
### Ruled out so far
- specific store-TB identity (E15)
- store `DONE_FLAG` block-replay/redispatch (E17)
- WASM function-table index reuse (E18)
### Standing conclusion
The corruption is a nondeterministic concurrency issue between the vCPU pthread
(compiled `i64.storeN`) and the concurrent main/IO thread (timer/device
callbacks, AIO/block completions) over shared guest memory or QEMU softmmu
metadata — the class of bug upstream qemu-wasm avoids with blanket store-TCI.
Confirming the exact racing access needs thread-aware instrumentation (e.g.,
logging IO-thread guest-RAM writes and TLB mutations during reader open) rather
than more store-gating experiments. Production stays on blanket store-TCI.
Opt-in debug knobs now available: `?nostoretci`, `?sthash`,
`?stcw/stcmask/stcval`, `?yieldtrace`, `?noremove`.
+1
View File
@@ -494,6 +494,7 @@ async function boot(file, variant, setStatus) {
else if (params.has('tcgdiff')) options._wasm_diff_enable();
if (params.has('nostoretci')) options._wasm_disable_store_tci();
if (params.has('yieldtrace')) options._wasm_enable_yield_trace();
if (params.has('noremove')) options._wasm_set_disable_tb_removal();
if (params.has('sthash')) options._wasm_set_store_tci_hash(Number(params.get('sthash')) || 1);
if (params.has('stcmask')) options._wasm_set_store_bisect(Number(params.get('stcw')) || 0, Number(params.get('stcmask')) >>> 0, (Number(params.get('stcval')) || 0) >>> 0);
options.FS.mkdirTree('/bios');