design-b D-1a: retire the legacy-shim ablation builds + redundancy pins
Doc 20 D-1 (legacy runtime deletion), first slice: races_test_noheal / races_test_nosleepfix pinned behavior of the legacy handlesleep shim, which is being deleted — the pins now assert properties of a runtime that no longer exists. Drops the two Makefile.wasm link+inject variants (SHIM_DISABLE_TRAMPOLINE_HEAL / SHIM_DISABLE_HANDLESLEEP), the shim-redundancy pin specs in asyncify-races.spec.ts, and resolves the tests/README.md open task. The green battery still runs every scenario against the scheduler glue. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TEHGiiXMShNXbBr7gSJ7iz
This commit is contained in:
parent
e19ef6cf65
commit
e7b8c2725b
4 changed files with 23 additions and 113 deletions
|
|
@ -303,18 +303,14 @@ Button positions (relative to canvas):
|
|||
|
||||
## Open tasks
|
||||
|
||||
- **Research: are the Asyncify fiber shims still needed under native-EH?** Two
|
||||
`scripts/common/inject-dyncall-shims.sh` fixes — the fiber trampoline self-heal
|
||||
(§3c) and the nested-Asyncify handleSleep save/restore (§3) — were written for the
|
||||
legacy-EH *park-throw* model. Under native wasm-EH the top loop is a per-frame-yield
|
||||
while-loop with no park-throw, so ablating either shim
|
||||
(`SHIM_DISABLE_TRAMPOLINE_HEAL` / `SHIM_DISABLE_HANDLESLEEP`, wired in
|
||||
`tests/apps/Makefile.wasm`) no longer reproduces the disease it guarded — the old
|
||||
red "ablation pins" in `asyncify/asyncify-races.spec.ts` have been flipped to
|
||||
green "shim-redundancy pins" that now prove the native-EH path stays clean *with the
|
||||
shim ablated*. **To do:** sweep the real apps (modals, nested fibers, long sleeps,
|
||||
pthread pool) with each shim ablated; if all stay green, drop the shim injection and
|
||||
these pins. Until proven, they stay injected (belt-and-suspenders).
|
||||
- ~~Research: are the Asyncify fiber shims still needed under native-EH?~~
|
||||
**Resolved at doc 20 D-1** (legacy-runtime deletion): the ablation builds
|
||||
(`races_test_noheal` / `races_test_nosleepfix`) and their shim-redundancy pins in
|
||||
`asyncify/asyncify-races.spec.ts` pinned a runtime that no longer exists — the
|
||||
scheduler shim (`scripts/common/shims/asyncify-scheduler.js`) is the only runtime
|
||||
and subsumes the handleSleep save/restore; the fiber trampoline self-heal (§3c)
|
||||
remains injected unconditionally. The green battery runs every scenario against
|
||||
the scheduler glue.
|
||||
|
||||
## Collab e2e — legacy vs v2 bundles, and repro markers
|
||||
|
||||
|
|
|
|||
|
|
@ -200,8 +200,6 @@ all: minimal_test.html \
|
|||
$(S)/coroutine/coroutine_test.html \
|
||||
$(S)/coroutine-nested/nested_test.html \
|
||||
$(S)/asyncify-races/races_test.html \
|
||||
$(S)/asyncify-races/races_test_noheal.html \
|
||||
$(S)/asyncify-races/races_test_nosleepfix.html \
|
||||
$(S)/coroutine-pthread/coroutine_test_wxpt.html \
|
||||
$(S)/coroutine-pthread/embind_repro.html \
|
||||
$(S)/coroutine-pthread/gl_repro.html \
|
||||
|
|
@ -747,9 +745,9 @@ $(S)/coroutine-nested/nested_test.html: $(S)/coroutine-nested/nested_test.o $(S)
|
|||
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
|
||||
|
||||
# Asyncify race-condition red-green harness (tests/asyncify/). Three variants of
|
||||
# the same app: full shims, trampoline-heal ablated, handleSleep-fix ablated.
|
||||
# The ablated builds keep the historical bugs reproducible (red) so the shim
|
||||
# fixes stay pinned by tests. Same .o, three link+inject passes.
|
||||
# (The trampoline-heal / handleSleep ablation variants — races_test_noheal /
|
||||
# races_test_nosleepfix — were retired at doc 20 D-1 together with the legacy
|
||||
# runtime they pinned.)
|
||||
$(S)/asyncify-races/races_test.o: $(S)/asyncify-races/races_test.cpp $(S)/coroutine/kicad_coroutine_harness.h
|
||||
$(CXX) -c $(CXXFLAGS) -I$(KICAD_ROOT)/thirdparty/libcontext -I$(S)/coroutine $< -o $@
|
||||
|
||||
|
|
@ -757,14 +755,6 @@ $(S)/asyncify-races/races_test.html: $(S)/asyncify-races/races_test.o $(S)/corou
|
|||
$(CXX) $^ $(LDFLAGS_RACES) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
|
||||
|
||||
$(S)/asyncify-races/races_test_noheal.html: $(S)/asyncify-races/races_test.o $(S)/coroutine/libcontext.o $(WX_CORE_LIB)
|
||||
$(CXX) $^ $(LDFLAGS_RACES) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
SHIM_DISABLE_TRAMPOLINE_HEAL=1 ../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
|
||||
|
||||
$(S)/asyncify-races/races_test_nosleepfix.html: $(S)/asyncify-races/races_test.o $(S)/coroutine/libcontext.o $(WX_CORE_LIB)
|
||||
$(CXX) $^ $(LDFLAGS_RACES) --pre-js $(JS) --shell-file $(HTML) -o $@
|
||||
SHIM_DISABLE_HANDLESLEEP=1 ../../scripts/common/inject-dyncall-shims.sh $(basename $@).js
|
||||
|
||||
|
||||
# Convenience targets
|
||||
menu: $(S)/menu/menu_test.html
|
||||
|
|
@ -836,7 +826,7 @@ $(S)/retinascale/retinascale_test.html: $(S)/retinascale/retinascale_test.o $(WX
|
|||
retinascale: $(S)/retinascale/retinascale_test.html
|
||||
coroutine: $(S)/coroutine/coroutine_test.html
|
||||
coroutine-nested: $(S)/coroutine-nested/nested_test.html
|
||||
asyncify-races: $(S)/asyncify-races/races_test.html $(S)/asyncify-races/races_test_noheal.html $(S)/asyncify-races/races_test_nosleepfix.html
|
||||
asyncify-races: $(S)/asyncify-races/races_test.html
|
||||
|
||||
# Only delete generated app files (*_test*, *_repro*) — a bare $(S)/*/*.js would
|
||||
# also delete checked-in sources like coroutine-pthread/worker_dom_stub.js.
|
||||
|
|
|
|||
|
|
@ -411,9 +411,9 @@ private:
|
|||
|
||||
// ----- scenario 1: post_park_fiber_swap -------------------------------------
|
||||
// The KiCad hang topology. OnInit already did a fiber swap, so the park throw
|
||||
// went through the live trampoline. With the self-heal shim the guard was
|
||||
// reset and this swap works; with SHIM_DISABLE_TRAMPOLINE_HEAL=1 the guard is
|
||||
// stuck true, the Call() below never returns, and the watchdog fires.
|
||||
// went through the live trampoline. With the self-heal shim the guard is
|
||||
// reset and this swap works; historically (ablated heal, retired at doc 20
|
||||
// D-1) the guard stuck true, Call() never returned, and the watchdog fired.
|
||||
void Scenario_PostParkFiberSwap()
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
@ -608,9 +608,9 @@ private:
|
|||
|
||||
// ----- scenario 5: long_parked_sleep_clobbered_by_swap ------------------------
|
||||
// The KiCad clipboard crash shape: a long-parked sleep crossed by complete
|
||||
// fiber-swap cycles on fresh stacks. With handlesleep.js the sleep's buffer
|
||||
// is restored at wakeUp; with SHIM_DISABLE_HANDLESLEEP=1 doRewind reads a
|
||||
// clobbered currData -> "index out of bounds".
|
||||
// fiber-swap cycles on fresh stacks. The scheduler shim restores the sleep's
|
||||
// buffer at wakeUp; historically (no save/restore, ablation retired at doc 20
|
||||
// D-1) doRewind read a clobbered currData -> "index out of bounds".
|
||||
void Scenario_LongParkedSleep()
|
||||
{
|
||||
#ifdef __EMSCRIPTEN__
|
||||
|
|
|
|||
|
|
@ -3,12 +3,11 @@ import { test, expect, tryLoadApp } from '../e2e/utils/fixtures';
|
|||
// Red-green specs for the Asyncify race-condition harness
|
||||
// (tests/apps/standalone/asyncify-races/races_test.cpp — see docs/features/async/).
|
||||
//
|
||||
// Two kinds of tests here:
|
||||
// - GREEN-target tests assert the desired end state (clean pass, clean console).
|
||||
// While a fix is missing they FAIL — that failing run is the recorded "red".
|
||||
// - ABLATION tests run the shim-ablated builds (races_test_noheal.js /
|
||||
// races_test_nosleepfix.js) and assert the historical bug REPRODUCES.
|
||||
// They pin the disease so the shim fixes stay testable forever.
|
||||
// GREEN-target tests assert the desired end state (clean pass, clean console).
|
||||
// While a fix is missing they FAIL — that failing run is the recorded "red".
|
||||
// (The shim-ablation builds and their pins were retired at doc 20 D-1 together
|
||||
// with the legacy runtime they exercised; the scheduler shim is the only
|
||||
// runtime, and the battery below runs every scenario against it.)
|
||||
|
||||
const BATTERY = [
|
||||
'post_park_fiber_swap',
|
||||
|
|
@ -176,78 +175,3 @@ test.describe('Asyncify races — green targets (full shims)', () => {
|
|||
expect(unwindLeaks, `unwind escaped the park: ${unwindLeaks.join(' || ')}`).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
// These two were "ablation pins": they ablated a JS-shim fix (via SHIM_DISABLE_*,
|
||||
// see tests/apps/Makefile.wasm) and asserted the LEGACY-EH disease came back — a
|
||||
// stuck Fibers.trampoline guard (trampolineRunning=true) / a clobbered parked-sleep
|
||||
// buffer. Under native wasm-EH the top loop is a per-frame-yield while-loop with NO
|
||||
// park-throw (docs/features/wasm-exceptions; native-EH top-loop redesign), so the
|
||||
// disease's *trigger* is gone at the root: ablating the shim no longer reproduces
|
||||
// it. (The green "battery" above already runs both scenarios full-shim.)
|
||||
//
|
||||
// So they are flipped red->green: each now pins that the native-EH path stays clean
|
||||
// EVEN with the legacy shim ablated — i.e. the scenario completes with no disease
|
||||
// signature. That keeps them as the live signal for the open question below.
|
||||
//
|
||||
// TODO(research): are these shims still needed AT ALL under native-EH-only? The
|
||||
// fiber trampoline self-heal (§3c) and the nested-Asyncify handleSleep save/restore
|
||||
// (§3) in scripts/common/inject-dyncall-shims.sh were written for the legacy
|
||||
// park-throw model; ablating either no longer breaks the scenario it guarded. If a
|
||||
// full sweep of the real apps (modals / nested fibers / long sleeps / pthread pool)
|
||||
// confirms they're dead weight under native-EH, drop the shim injection AND these
|
||||
// pins. Until then they stay injected (belt-and-suspenders). Tracked in
|
||||
// tests/README.md "Open tasks".
|
||||
test.describe('Asyncify races — shim-redundancy pins (native-EH stays clean with the legacy shim ablated)', () => {
|
||||
test('trampoline-heal ablated: native-EH post-park swap still completes (no stuck guard)', async ({
|
||||
page,
|
||||
testLogger,
|
||||
}) => {
|
||||
await page.goto(
|
||||
'/standalone/asyncify-races/races_test_noheal.html#only=post_park_fiber_swap'
|
||||
);
|
||||
await tryLoadApp(page, 30000);
|
||||
|
||||
await expect
|
||||
.poll(() => findSummary(testLogger.consoleLogs) ?? null, {
|
||||
timeout: 45000,
|
||||
message: 'post-park swap should complete even with the trampoline self-heal ablated',
|
||||
})
|
||||
.not.toBeNull();
|
||||
|
||||
const { passed, failed } = parseSummary(findSummary(testLogger.consoleLogs)!);
|
||||
expect(passed).toBe(1);
|
||||
expect(failed).toBe(0);
|
||||
|
||||
// The legacy disease signature must be ABSENT: no stuck-trampoline watchdog dump.
|
||||
expect(
|
||||
testLogger.consoleLogs.some((l) =>
|
||||
l.includes('[ASYNCIFY_RACES] WATCHDOG post_park_fiber_swap')
|
||||
),
|
||||
'no stuck-trampoline watchdog should fire under native-EH'
|
||||
).toBe(false);
|
||||
expect(crashLines(testLogger), 'no crash signatures in console').toHaveLength(0);
|
||||
});
|
||||
|
||||
test('handleSleep ablated: native-EH long parked sleep is not clobbered by a swap', async ({
|
||||
page,
|
||||
testLogger,
|
||||
}) => {
|
||||
await page.goto(
|
||||
'/standalone/asyncify-races/races_test_nosleepfix.html#only=long_parked_sleep_clobbered_by_swap'
|
||||
);
|
||||
await tryLoadApp(page, 30000);
|
||||
|
||||
await expect
|
||||
.poll(() => findSummary(testLogger.consoleLogs) ?? null, {
|
||||
timeout: 45000,
|
||||
message: 'long parked sleep should resolve even with the handleSleep fix ablated',
|
||||
})
|
||||
.not.toBeNull();
|
||||
|
||||
const { passed, failed } = parseSummary(findSummary(testLogger.consoleLogs)!);
|
||||
expect(passed).toBe(1);
|
||||
expect(failed).toBe(0);
|
||||
expect(crashLines(testLogger), 'no crash signatures in console').toHaveLength(0);
|
||||
expect(realErrors(testLogger), 'no page errors').toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue