Skip to content

fix(jit): SHEN_JIT=off switch + arm64/beta warning for boot SIGSEGV (#43) - #44

Merged
pyrex41 merged 1 commit into
mainfrom
fix/jit-off-switch-43
Jul 23, 2026
Merged

fix(jit): SHEN_JIT=off switch + arm64/beta warning for boot SIGSEGV (#43)#44
pyrex41 merged 1 commit into
mainfrom
fix/jit-off-switch-43

Conversation

@pyrex41

@pyrex41 pyrex41 commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses #43 — the intermittent boot-time SIGSEGV under LuaJIT on aarch64.

I reproduced it on real aarch64 Linux (OrbStack) and root-caused it: an old (2.1.0-beta3-era) LuaJIT mis-compiles one of the ~1500 traces generated while loading the kernel; the bad trace branches into unmapped memory and faults. It is a LuaJIT backend bug, already fixed upstream — the identical kernel boot is clean under a current 2.1 rolling release.

Build JIT Result
LuaJIT 2.1.0-beta3 (2017 tag) on 50/50 SIGSEGV
LuaJIT 2.1.0-beta3 SHEN_JIT=off 0/30
LuaJIT 2.1.ROLLING (current) on 0/60

gdb shows the fault PC landing just outside LuaJIT's executable mcode region with a corrupt stack — a compiled trace jumping to a bad target, not anything in shen-lua's C surface or the interpreter.

Changes

  • Primary guidance (docs): upgrade to a current LuaJIT 2.1 rolling release — that is the fix.
  • Fallback mitigation for hosts pinned to an old LuaJIT:
    • SHEN_JIT=offjit.off() at boot (equivalent to luajit -j off). Distinct from the pre-existing SHEN_JIT_OPT=off, which only reset jit.opt and left the JIT on (so it never prevented the crash).
    • shen.boot{jit=false} → the programmatic equivalent for embedders.
    • A one-time stderr warning on the exact risky combo (arm64 + a beta-versioned LuaJIT, JIT left on), pointing at both remedies; silenced by SHEN_JIT=on/off and never fires on a rolling build.
  • Test: test/jit_spec.lua drives a fresh LuaJIT per case and asserts via jit.status() that the switch reaches the JIT-off state while boot still evaluates; skips cleanly on PUC Lua.

Verification

  • test/jit_spec.lua: 11/11.
  • Full port suite: 500 pass, 0 fail across 14 specs.
  • Reproduction table above verified on OrbStack linux/arm64.

🤖 Generated with Claude Code

…GV (#43)

On aarch64, an old (2.1.0-beta3-era) LuaJIT mis-compiles one of the ~1500
traces generated while loading the kernel; the bad trace branches into
unmapped memory and SIGSEGVs during boot. Reproduced on aarch64 Linux
(OrbStack): 50/50 boots crash on the genuine v2.1.0-beta3 tag with the JIT on,
0/30 with it off. The same boot is clean 0/60 under a current 2.1 rolling
release — this is a LuaJIT backend bug already fixed upstream, so the primary
fix is to upgrade LuaJIT.

For hosts pinned to an old LuaJIT, add an in-library mitigation:

- SHEN_JIT=off  -> jit.off() at boot (the equivalent of `luajit -j off`).
  Distinct from the existing SHEN_JIT_OPT=off, which only resets jit.opt and
  leaves the JIT on (so it never prevented the crash).
- shen.boot{jit=false} -> the programmatic equivalent for embedders.
- A one-time stderr warning on the exact risky combo (arm64 + a beta-versioned
  LuaJIT, JIT left on) pointing at both remedies; silenced by SHEN_JIT=on/off
  and never fires on a rolling build.

test/jit_spec.lua drives a fresh LuaJIT per case and asserts, via jit.status(),
that the switch reaches the JIT-off state while boot still evaluates; it skips
cleanly on PUC Lua. README documents the crash, the upgrade-first fix, and the
fallback switch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pyrex41
pyrex41 merged commit c85ad7e into main Jul 23, 2026
2 checks passed
@pyrex41
pyrex41 deleted the fix/jit-off-switch-43 branch July 23, 2026 16:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant