Stage 3 follow-on: fix stack-ownership corruption + DoE switch columns (FABRIC-3.md §XXVIII.1)
DoE CSV gained 6 switch-signal columns (switch_count_cumulative, switch_current_slot, switch_*_readiness, switch_ticks_since), and verifying them with a boot-time HB-ON probe surfaced a real livelock: the preemption checkpoint could fire inside a VM-EXEC-nested execute_colon_word() call and switch away from a stack it didn't own, parking a borrowed region of the caller's stack under the wrong VM's saved-context pointer. The trampoline bounce was the visible (safe) half of this; the corruption was the quiet half, live in every prior "clean" Stage 3 boot without ever showing up in the log. Fixed by gating the checkpoint on being at the outermost vm_interpret() call (g_vm_interpret_depth / sk_vm_at_outermost_interpret(), vm_core.c), per Bob's decision. Also fixed two related bugs found in the same pass: g_switch_back_to was a single global stale after first entry, now per-VM state (native_switch_back_to); note_switch_performed() fired on resume instead of switch-out, now called before the switch. Verified on all 3 architectures: steady log growth (no freeze), zero leaked QEMU processes, DoE columns internally consistent, Hermes/Artemis confirmed genuinely executing (not just trampoline-bouncing). Temporary HB-ON boot probe reverted after capture. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016UNhH1mhi52i6Qihh7ZV5S
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
986d042aa7
commit
862d7d9c48
@@ -658,6 +658,17 @@ typedef struct VM
|
||||
* entered (no context parked yet); non-zero only
|
||||
* while VMRegistryEntry.state ==
|
||||
* VM_STATE_SWITCHED_OUT for this VM. */
|
||||
struct VM *native_switch_back_to; /**< Stage 3 correction (FABRIC-3.md §XXVIII,
|
||||
* 2026-09-13): who most recently switched INTO
|
||||
* this VM. Updated by sk_vm_context_switch() on
|
||||
* every switch-in (first-ever or resumed), so the
|
||||
* placeholder trampoline (sk_vm_switch_entry())
|
||||
* always yields back to whoever actually switched
|
||||
* in, not a stale value captured once at this
|
||||
* VM's very first entry -- a single global there
|
||||
* let a later switch-in from a different VM get
|
||||
* silently bounced to the original caller instead
|
||||
* of itself. */
|
||||
/** @} */
|
||||
|
||||
/** @name Stadium Identity (item 4.2, FABRIC-0.md §25.5)
|
||||
|
||||
Reference in New Issue
Block a user