tcg/wasm32: add opt-in ?yieldtrace store-yield counter

Counts compiled-TB DONE_FLAG redispatch/resume re-entries. Three crashing
nostoretci runs showed zero such re-entries, ruling out the store
block-replay-via-redispatch path as the corruption trigger and pointing at a
guest-RAM data race with concurrent device/timer callbacks.
This commit is contained in:
2026-07-22 21:43:06 -04:00
parent a18a2991c6
commit 9e9184949d
+22
View File
@@ -1318,6 +1318,13 @@ int wasm_store_tci_disabled;
int wasm_store_tci_hash;
int wasm_store_bisect_on;
int wasm_store_bisect_width;
int wasm_yield_trace;
uint32_t wasm_yield_reentries;
EMSCRIPTEN_KEEPALIVE void wasm_enable_yield_trace(void)
{
wasm_yield_trace = 1;
}
uint32_t wasm_store_bisect_mask;
uint32_t wasm_store_bisect_val;
@@ -1704,12 +1711,15 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
while (true) {
int tb_entry_ptr = (uint32_t)ctx.tb_ptr + export_vec_off;
uint32_t res;
uint32_t prev_tb = (uint32_t)ctx.tb_ptr;
bool was_compiled = false;
bool diff_store_tci = wasm_diff_mode == 1 &&
wasm_diff_lookup_store_tb(ctx.tb_ptr, NULL);
if (diff_store_tci) {
res = tcg_qemu_tb_exec_tci(env);
} else if (*(int32_t*)tb_entry_ptr > 0) {
res = ((wasm_func_ptr)(*(uint32_t*)tb_entry_ptr))(&ctx);
was_compiled = true;
} else if (*(int32_t *)tb_entry_ptr == WASM_TCI_ONLY_ENTRY) {
res = tcg_qemu_tb_exec_tci(env);
} else if (*(int32_t*)tb_entry_ptr > (-1 * INSTANTIATE_NUM)) {
@@ -1719,6 +1729,18 @@ uintptr_t QEMU_DISABLE_CFI tcg_qemu_tb_exec(CPUArchState *env,
instantiate_wasm();
qatomic_inc(&instantiated_wasm_count);
res = ((wasm_func_ptr)(*(uint32_t*)tb_entry_ptr))(&ctx);
was_compiled = true;
}
/* E17: a compiled TB that returns non-zero with the same tb_ptr and
* do_init still clear is a mid-TB yield/resume (rewind path), not a
* chain (chains set do_init=1) and not completion (tb_ptr==0). */
if (wasm_yield_trace && was_compiled && (uint32_t)ctx.tb_ptr == prev_tb &&
(uint32_t)ctx.tb_ptr != 0 && ctx.do_init == 0) {
wasm_yield_reentries++;
if (wasm_yield_reentries <= 20 || (wasm_yield_reentries % 5000) == 0) {
printf("YIELD reentry #%u tb=0x%x\n", wasm_yield_reentries, prev_tb);
fflush(stdout);
}
}
if ((uint32_t)ctx.tb_ptr == 0) {
return res;