Skip to content

fix(apple/v8): stop the runtime aborting on teardown - #118

Merged
ammarahm-ed merged 1 commit into
refactorfrom
fix/apple-v8-teardown-abort
Nov 8, 2026
Merged

ammarahm-ed merged 1 commit into
refactorfrom
fix/apple-v8-teardown-abort

Conversation

@ammarahm-ed

Copy link
Copy Markdown
Collaborator

Every V8 nsr run on macOS aborts at exit with:

# Fatal error in v8::Context::Exit()
# Cannot exit non-entered context

It happens even for an empty script, after the script has finished. The Performance (v8) CI job runs the CLI, so it has failed on every PR into refactor, including #68 and #69.

Cause

  1. ~Runtime keeps a NapiScope open around js_free_napi_env. NapiScope enters env->context(), which is a Local pointing straight into the env's own persistent slot. The header warns against resetting that slot while the Local is in use. Freeing the env destroys the slot, so when the scope closes, Context::Exit reads a dead handle and V8 aborts.
  2. Fixing that exposed a second crash. The ES module cache keeps Global<Module>s per isolate in a thread-local map, and nothing released them. CleanupESModuleSystem exists but was never called, so the map was cleared at process exit, after the isolate was already disposed, and crashed.

Fix

  • The env is freed in its own scope, after globalScope_ is closed. That scope enters a copy of the context owned by its own HandleScope, so the env's finalizers still run inside the context. Non-V8 engines are unchanged.
  • js_free_runtime calls CleanupESModuleSystem before disposing the isolate.

Testing

  • Empty and small scripts: exit 0. Before the fix they exited with 133.
  • Objective-C dispatch benchmark: exits 0 in 3 of 3 runs, with all results reported.
  • macOS V8 runtime suite: 720 specs, 0 failures.

This PR's own Performance (v8) check will still fail: it builds its baseline from refactor, which still has the bug. Once this is merged, the baseline is fixed for every later PR, including #117.

🤖 Generated with Claude Code

Every V8 'nsr run' aborted at exit with 'Cannot exit non-entered context',
so the Performance (v8) job failed on every PR into refactor.

~Runtime kept NapiScope open around js_free_napi_env. NapiScope enters
env->context(), a Local that aliases the env's own persistent slot, and
freeing the env destroys that slot; the scope's Context::Exit then read a
dead handle. The env is now freed in its own scope that enters a
HandleScope-owned copy of the context, after globalScope_ is closed.

That exposed a second crash: the ES module cache keeps thread-local
Globals per isolate and nothing released them, so they were reset at exit
against the disposed isolate. js_free_runtime now calls the existing
CleanupESModuleSystem before disposing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Nov 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 62297855-f764-4689-bc05-f6b6295ecc29

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@ammarahm-ed
ammarahm-ed merged commit e608b1c into refactor Nov 8, 2026
6 of 9 checks passed
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