fix(wx): thread-safe wxString for the AsyncLoad fan-out — CvPcb-open trap solved
The ~1/9 wasm trap on CvPcb open ("index out of bounds" / "indirect call to
null" in a footprint AsyncLoad pool worker, then eeschema aborting on the
broken future — and the eeschema-fp-selector "CI-only" trap family, which was
never llvmpipe-specific) was wxString's UTF-8 build mutating SHARED strings on
read-only access from concurrent pool workers: every iterator ctor/dtor
spliced an intrusive list inside the string object, and torn splices wrote
through dead node pointers into other threads' stack frames. Second defect:
the UTF-8 position cache returned stale offsets when another thread's string
died and its address was reused.
Fixed in the wxwidgets fork (per-thread iterator registry + position cache
disabled under Emscripten) — kicad is untouched and AsyncLoad keeps its full
multi-worker fan-out. Falsified along the way (all perturbation masks, not
fixes): serializing the items, mimalloc vs dlmalloc, pthread stack size,
ASYNCIFY_STACK_SIZE, private-copy EnumFromStr, hot-path logging.
New red-first standalone app tests/apps/standalone/wxstring-mt (+ spec
coroutine-wxstring-mt.spec.ts, wx-chromium + coroutine-firefox): shared-string
compares alternating with wide-literal conversions reproduce the exact editor
trap signatures on the unfixed wx and run 4.7M rounds clean on the fixed one;
the pos-cache address-reuse dance corrupts on the first reuse before and
survives 673 after; two guard modes keep the iterator fix-up feature honest
(incl. an anti-elision liveness check — balanced register/unregister pairs in
tight loops can legally be optimized away, so a naive red test tests nothing).
Verification: wx+coroutine suites 382 passed; in-app AsyncLoad hammer 3x1000
rounds clean (baseline died <10); eeschema-assign-footprints spec 20/20
firefox + 20/20 chromium on the final build; lint:determinism clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rb9jsqtHsC3tHTaJ45244j
This commit is contained in:
parent
f3b43c831f
commit
d538b73557
5 changed files with 580 additions and 9 deletions
|
|
@ -131,14 +131,16 @@ test('Tools → Assign Footprints opens CvPcb (merged third kiface)', async ({ p
|
|||
}
|
||||
}, item);
|
||||
|
||||
// TODO(cvpcb-open-trap): ~1/9 local web-firefox runs die right here — the
|
||||
// EVT.MENU dispatch traps ("wx_dom_event(48,9) failed" + worker
|
||||
// "RuntimeError: index out of bounds"), eeschema survives, CvPcb never
|
||||
// appears, zero libs-bridge calls. Same trap signature as the
|
||||
// eeschema-fp-selector CI trap (docs/features/web-e2e-rot/01) — which
|
||||
// reproduced on macOS real GL, so it is NOT llvmpipe-only. Needs a
|
||||
// debug-symbol repro; post-link binaryen rewriting makes the shipped
|
||||
// module's DWARF useless for symbolizing the trap offset.
|
||||
// The ~1/9 "index out of bounds" trap that used to fire right here (a pool
|
||||
// worker dying in the footprint AsyncLoad items, then eeschema's EVT.MENU
|
||||
// dispatch aborting on the broken future) was root-caused to wxString's
|
||||
// UTF-8 build mutating SHARED strings on read-only access from the
|
||||
// concurrent workers — fixed in the wx fork (per-thread iterator registry +
|
||||
// position cache disabled under Emscripten, include/wx/string.h), with the
|
||||
// red/green repro in tests/apps/standalone/wxstring-mt. The
|
||||
// eeschema-fp-selector "CI-only" trap (docs/features/web-e2e-rot/01) is the
|
||||
// same family (it reproduced on macOS real GL, so it was never
|
||||
// llvmpipe-specific).
|
||||
//
|
||||
// The frame construction + netlist mail runs off wxPostEvent'd follow-ups,
|
||||
// which the wx WASM port only flushes on input events — wiggle the mouse
|
||||
|
|
|
|||
Loading…
Reference in a new issue