Skip to content

src: keep global list of addon-provided cleanup hooks - #63985

Closed
addaleax wants to merge 1 commit into
nodejs:mainfrom
addaleax:fix-63923
Closed

src: keep global list of addon-provided cleanup hooks#63985
addaleax wants to merge 1 commit into
nodejs:mainfrom
addaleax:fix-63923

Conversation

@addaleax

Copy link
Copy Markdown
Member

A recent change, 215027c, introduced flakiness into our test suite that exposed an issue with the cleanup hook API design.

Specifically, the signatures of AddEnvironmentCleanupHook() and RemoveEnvironmentCleanupHook() are problematic. Both functions take Isolate* arguments, as addons are not generally expected to have to care about the Node.js Environment as a first-class scope provider.

However, this model made the incorrect assumption that in the situations in which RemoveEnvironmentCleanupHook() would be invoked an Environment would always be associated with the current Isolate (via the current V8 Context, if there is one).

This occasionally breaks down when RemoveEnvironmentCleanupHook() is called during garbage collection -- which would be an expected use case of the functionality, but one that has not been covered through our tests before 215027c.

Since Node.js guarantees API and ABI stability within a major version, and this is a bug that is independent from the aforementioned change, this commit resolves it by adding global mutable state to keep track off cleanup hooks registered through the Node.js public API.

Obviously, this solution does not represent a desirable long-term state, and a semver-minor follow up should add an API that does not require modifications to these data structures, likely based on the async cleanup hook API which already solves this issue properly.

Refs: #63642
Fixes: #63923

A recent change, 215027c, introduced flakiness into our
test suite that exposed an issue with the cleanup hook API design.

Specifically, the signatures of `AddEnvironmentCleanupHook()` and
`RemoveEnvironmentCleanupHook()` are problematic. Both functions
take `Isolate*` arguments, as addons are not generally expected
to have to care about the Node.js `Environment` as a first-class
scope provider.

However, this model made the incorrect assumption that in the
situations in which `RemoveEnvironmentCleanupHook()` would be
invoked an `Environment` would always be associated with the
current `Isolate` (via the current V8 `Context`, if there is one).

This occasionally breaks down when `RemoveEnvironmentCleanupHook()`
is called during garbage collection -- which would be an expected
use case of the functionality, but one that has not been covered
through our tests before 215027c.

Since Node.js guarantees API and ABI stability within a major version,
and this is a bug that is independent from the aforementioned change,
this commit resolves it by adding global mutable state to keep track
off cleanup hooks registered through the Node.js public API.

Obviously, this solution does not represent a desirable long-term
state, and a semver-minor follow up should add an API that does not
require modifications to these data structures, likely based on
the async cleanup hook API which already solves this issue properly.

Refs: nodejs#63642
Fixes: nodejs#63923
Signed-off-by: Anna Henningsen <anna@addaleax.net>
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. needs-ci PRs that need a full CI run. labels Jun 18, 2026
@addaleax addaleax added request-ci Add this label to start a Jenkins CI on a PR. author ready PRs with CI started, the required approvals, and no outstanding review comments. labels Jun 19, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 19, 2026
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mcollina mcollina added the commit-queue PRs queued for automated landing through the Commit Queue. label Jun 20, 2026
@mcollina

Copy link
Copy Markdown
Member

The windows coverage job is now skipped on main

@nodejs-github-bot nodejs-github-bot added commit-queue-failed PRs whose Commit Queue landing failed and need manual intervention before retrying. and removed commit-queue PRs queued for automated landing through the Commit Queue. labels Jun 20, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator
Commit Queue failed
- Loading data for nodejs/node/pull/63985
✔  Done loading data for nodejs/node/pull/63985
----------------------------------- PR info ------------------------------------
Title      src: keep global list of addon-provided cleanup hooks (#63985)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     addaleax:fix-63923 -> nodejs:main
Labels     c++, author ready, needs-ci
Commits    1
 - src: keep global list of addon-provided cleanup hooks
Committers 1
 - Anna Henningsen <anna@addaleax.net>
PR-URL: https://github.com/nodejs/node/pull/63985
Fixes: https://github.com/nodejs/node/issues/63923
Refs: https://github.com/nodejs/node/pull/63642
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/63985
Fixes: https://github.com/nodejs/node/issues/63923
Refs: https://github.com/nodejs/node/pull/63642
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Thu, 18 Jun 2026 16:04:55 GMT
   ✔  Approvals: 3
   ✔  - James M Snell (@jasnell) (TSC): https://github.com/nodejs/node/pull/63985#pullrequestreview-4530362095
   ✔  - Santiago Gimeno (@santigimeno): https://github.com/nodejs/node/pull/63985#pullrequestreview-4532738398
   ✔  - Matteo Collina (@mcollina) (TSC): https://github.com/nodejs/node/pull/63985#pullrequestreview-4537144735
   ✘  1 GitHub CI job(s) failed:
   ✘    - coverage-windows: FAILURE (https://github.com/nodejs/node/actions/runs/27772695943/job/82176628881)
   ℹ  Last Full PR CI on 2026-06-19T12:10:44Z: https://ci.nodejs.org/job/node-test-pull-request/74255/
- Querying data for job/node-test-pull-request/74255/
✔  Build data downloaded
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/27876670330

addaleax added a commit that referenced this pull request Jun 20, 2026
A recent change, 215027c, introduced flakiness into our
test suite that exposed an issue with the cleanup hook API design.

Specifically, the signatures of `AddEnvironmentCleanupHook()` and
`RemoveEnvironmentCleanupHook()` are problematic. Both functions
take `Isolate*` arguments, as addons are not generally expected
to have to care about the Node.js `Environment` as a first-class
scope provider.

However, this model made the incorrect assumption that in the
situations in which `RemoveEnvironmentCleanupHook()` would be
invoked an `Environment` would always be associated with the
current `Isolate` (via the current V8 `Context`, if there is one).

This occasionally breaks down when `RemoveEnvironmentCleanupHook()`
is called during garbage collection -- which would be an expected
use case of the functionality, but one that has not been covered
through our tests before 215027c.

Since Node.js guarantees API and ABI stability within a major version,
and this is a bug that is independent from the aforementioned change,
this commit resolves it by adding global mutable state to keep track
off cleanup hooks registered through the Node.js public API.

Obviously, this solution does not represent a desirable long-term
state, and a semver-minor follow up should add an API that does not
require modifications to these data structures, likely based on
the async cleanup hook API which already solves this issue properly.

Refs: #63642
Fixes: #63923
Signed-off-by: Anna Henningsen <anna@addaleax.net>
PR-URL: #63985
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@addaleax

Copy link
Copy Markdown
Member Author

Landed in 68321ef

@addaleax addaleax closed this Jun 20, 2026
aduh95 pushed a commit that referenced this pull request Jun 20, 2026
A recent change, 215027c, introduced flakiness into our
test suite that exposed an issue with the cleanup hook API design.

Specifically, the signatures of `AddEnvironmentCleanupHook()` and
`RemoveEnvironmentCleanupHook()` are problematic. Both functions
take `Isolate*` arguments, as addons are not generally expected
to have to care about the Node.js `Environment` as a first-class
scope provider.

However, this model made the incorrect assumption that in the
situations in which `RemoveEnvironmentCleanupHook()` would be
invoked an `Environment` would always be associated with the
current `Isolate` (via the current V8 `Context`, if there is one).

This occasionally breaks down when `RemoveEnvironmentCleanupHook()`
is called during garbage collection -- which would be an expected
use case of the functionality, but one that has not been covered
through our tests before 215027c.

Since Node.js guarantees API and ABI stability within a major version,
and this is a bug that is independent from the aforementioned change,
this commit resolves it by adding global mutable state to keep track
off cleanup hooks registered through the Node.js public API.

Obviously, this solution does not represent a desirable long-term
state, and a semver-minor follow up should add an API that does not
require modifications to these data structures, likely based on
the async cleanup hook API which already solves this issue properly.

Refs: #63642
Fixes: #63923
Signed-off-by: Anna Henningsen <anna@addaleax.net>
PR-URL: #63985
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@aduh95 aduh95 added the backport-requested-v24.x PRs awaiting manual backport to the v24.x-staging branch. label Aug 6, 2026
@aduh95

aduh95 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

This doesn't land cleanly on v24.x-staging, it would require a manual backport PR if we want it on Node.js 24

@aduh95 aduh95 added backport-open-v24.x Indicate that the PR has an open backport and removed backport-requested-v24.x PRs awaiting manual backport to the v24.x-staging branch. labels Aug 19, 2026
Tomoya7001 pushed a commit to Tomoya7001/protocol-radar that referenced this pull request Aug 20, 2026
Production was returning HTTP 500 on roughly a third to a half of all requests,
with no deploy on our side. Vercel logs showed:

  Node.js process exited with signal: 6 (SIGABRT) (core dumped)
  # node::RemoveEnvironmentCleanupHook(...) at ../src/api/hooks.cc:142
  # Assertion failed: (env) != nullptr
  ... Statement::~Statement() ... better-sqlite3

Cause is upstream and has nothing to do with this codebase. Node 24.19.0
(2026-08-03) added cleanup hooks to node::ObjectWrap (nodejs/node#63642) without
the change that makes RemoveEnvironmentCleanupHook safe to call during garbage
collection — that landed only in Node 26 (nodejs/node#63985) and has not been
backported to 24.x. better-sqlite3's Statement extends node::ObjectWrap, so when
V8 collects a statement there is no entered context, Environment::GetCurrent()
returns nullptr, and the assertion aborts the whole process, killing every
in-flight request on that instance. Node 22 and 20 predate the ObjectWrap change
and are unaffected; the same trace is reported downstream in nexu-io/open-design#6462,
where reverting from 24.19.0 to 24.18.0 fixed it.

The host exposes only major versions and applies minors automatically, so
24.18.x cannot be pinned and 24.x will keep resolving to the broken build. The
only available defence is pinning the major to 22.x.

Also:
- /api/health now reports process.version, so a runtime regression is
  diagnosable from outside without reading platform logs.
- A test asserts the pin, so "upgrade to the latest Node" cannot silently
  reintroduce this before the upstream backport ships.

Not done deliberately: bumping better-sqlite3 (every version extends ObjectWrap;
#6462 crashed on 12.10.0), closing the DB on exit (the abort is at GC time, not
teardown), and disabling Fluid compute (no evidence it addresses the assertion).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWrmd97evyLqwXLGqM3xae
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 23, 2026
The Karakeep SSO VM aborted in better-sqlite3’s Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node’s deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix is merged on Node main in nodejs/node#63985, but its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported-LTS workaround while preserving explicit package overrides.
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 23, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix is merged on Node main in nodejs/node#63985, but its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 23, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix is merged on Node main in nodejs/node#63985, but its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 23, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix is merged on Node main in nodejs/node#63985, but its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 23, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix is merged on Node main in nodejs/node#63985, but its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
dniku pushed a commit to dniku/selfhostblocks that referenced this pull request Aug 24, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix proposed in nodejs/node#63985 was manually landed on main as nodejs/node@68321ef. Its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
ibizaman pushed a commit to ibizaman/selfhostblocks that referenced this pull request Aug 24, 2026
The Karakeep SSO VM aborted in better-sqlite3's Statement destructor under Node 24.19.0, as observed in https://github.com/ibizaman/selfhostblocks/actions/runs/32601131491/job/97099512653.

This matches Node's deterministic reproducer for a Node 24.19 ObjectWrap cleanup regression at nodejs/node#65446. The fix proposed in nodejs/node#63985 was manually landed on main as nodejs/node@68321ef. Its Node 24 backport at nodejs/node#65042 remains open.

nixpkgs defaults to the affected Node 24.19. Node 26 does not enter LTS until October 2026, while Node 22 remains supported through April 2027 according to https://github.com/nodejs/Release#release-schedule. Use Node 22 as a temporary supported LTS workaround while preserving explicit package overrides.
MarshallOfSound pushed a commit to electron/electron that referenced this pull request Sep 3, 2026
…53390)

* fix: backport Node.js cleanup hook fixes for node::ObjectWrap addons

Node.js 24.19.0 made node::ObjectWrap register an environment cleanup
hook but did not carry the fix that makes RemoveEnvironmentCleanupHook()
safe to call from ~ObjectWrap() during garbage collection, so any addon
built against the 24.19.0+ headers aborts with
"Assertion failed: (env) != nullptr" once one of its wrapped objects is
collected while no context is entered.

Cherry-picks:
* nodejs/node#63985 "src: keep global list of addon-provided cleanup
  hooks" (68321eff80918e324e9fdaf1aa8cee6db14b84f7 on nodejs/node main).
* nodejs/node#65630 "src: fix use-after-free in CleanupHookThunkRun" at
  dd2fa31b1d99e5a6710e08ce4139da7c2e344598 and its regression cctest at
  fd325a7fc2b33839c024220aa0c44b9104749686 (not yet landed upstream).

Fixes: #53387

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: add node::ObjectWrap native addon GC regression spec

Adds a minimal node::ObjectWrap addon fixture with a helper that runs a
full garbage collection while no context is entered, and a spec that
loads it in an ELECTRON_RUN_AS_NODE child process and asserts the
process exits cleanly. Reproduces
#53387 on unfixed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: rebuild native addon fixtures against Electron's node headers

The native addon fixtures under spec/fixtures/native-addon are yarn
workspaces, so yarn only runs their build scripts once per install state.
In CI the root `yarn install` builds them first, against the system
Node.js headers, and the later spec install with npm_config_nodedir set
never rebuilds them. N-API fixtures load anyway, but the object-wrap
fixture uses Node's C++ API, embeds the system NODE_MODULE_VERSION, and
is rejected by Electron with ERR_DLOPEN_FAILED.

Rebuild every native addon fixture with node-gyp after the spec install
so they are compiled against the configured Electron headers, which is
what spec-runner already intended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: build C++ API addon fixtures with the Chromium toolchain on Linux

The rebuild of the native addon fixtures against Electron's node headers
broke every Linux test shard: the CI test image ships GCC 11, which
cannot parse the V8 headers (`class V8_DEPRECATE_SOON(...) V8_EXPORT
Value` mixes a C++11 attribute with a GNU attribute, rejected by GCC
<= 12, see #53284):

  v8config.h:865:20: error: expected identifier before '__attribute__'
  v8-primitive.h:658:4: error: expected '}' before 'public'

Only addons registering through Node's C++ module API (NODE_MODULE /
NODE_MODULE_INIT) embed NODE_MODULE_VERSION and need Electron's headers,
so limit the rebuild to those; the N-API fixtures keep loading fine as
built by the root install. On Linux, when the Chromium toolchain from
the source checkout is present (CI restores third_party/llvm-build and
libc++ into the test job via src_artifacts, and the nan tests already
build with it), compile the fixture with clang and Electron's libc++
exactly as script/nan-spec-runner.js does; otherwise, and for the
--electronVersion prebuilt path, keep using the system compiler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: make the Electron-header fixture rebuild opt-in and fix it on Windows

The Windows test shards failed the fixture rebuild before configure:
node-gyp inherits NPM_CONFIG_MSVS_VERSION=2022 from the test step's env,
but the runners only ship a newer Visual Studio ("msvs_version does not
match this version"). The root install that built the same fixtures ran
without that pin and picked the installed toolset, so strip it from the
rebuild environment and let node-gyp detect Visual Studio. The Electron
import library it links against is already staged by
script/actions/move-artifacts.sh as gen/node_headers/Release/node.lib.

Also replace the source scan for NODE_MODULE usage with an explicit
"electron:requiresElectronHeaders" flag in the fixture's package.json, so
only fixtures that declare they need Electron's headers (currently
object-wrap) are rebuilt and the N-API fixtures are left untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: cope with hosts that cannot build the Electron-header addon fixture

The rebuild of spec/fixtures/native-addon/object-wrap against Electron's
headers broke two more sets of Linux test shards:

* linux-arm64: the test job runs on an arm64 host but restores the x64
  Chromium toolchain of the cross-compiling build job, so node-gyp died
  with "Exec format error: .../llvm-build/Release+Asserts/bin/clang".
  The image's GCC is the one that rejects the V8 headers
  (#53284), so nothing on that
  host can compile the fixture. Check that the Chromium clang actually
  runs before selecting it; when it does not, warn loudly, skip the
  rebuild and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so the
  ObjectWrap spec is reported as skipped there (with a comment pointing
  at this gap) instead of failing with an ABI error. Every other platform
  keeps running the spec for real.

* linux-x64-asan / -ubsan: the link failed with "ld.lld: error: unable to
  find library -lc++abi". Sanitizer builds compile libc++abi into the
  electron executable and export it from there
  (export_libcxxabi_from_executables) rather than producing libc++abi.a,
  so only pass -lc++abi when that archive exists; the symbols resolve
  from the executable when the addon is loaded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: skip the Electron-header addon specs when the spec install is skipped

The linux-arm test job runs the specs with --skipYarnInstall, so the spec
install that rebuilds spec/fixtures/native-addon/object-wrap against
Electron's headers never happens there and the ObjectWrap spec failed to
load the fixture the root install built against the system Node.js
headers ("was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 146"). When the install is needed but skipped, warn
and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so those specs are
reported as skipped, as on linux-arm64 where no toolchain can build the
fixture.

Also format the previous change with oxfmt, which `yarn lint:fmt`
flagged in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

---------

Co-authored-by: Claude <noreply@anthropic.com>
MarshallOfSound pushed a commit to electron/electron that referenced this pull request Sep 3, 2026
…(44-x-y) (#53392)

* fix: backport Node.js cleanup hook fixes for node::ObjectWrap addons

Node.js 24.19.0 made node::ObjectWrap register an environment cleanup
hook but did not carry the fix that makes RemoveEnvironmentCleanupHook()
safe to call from ~ObjectWrap() during garbage collection, so any addon
built against the 24.19.0+ headers aborts with
"Assertion failed: (env) != nullptr" once one of its wrapped objects is
collected while no context is entered.

Cherry-picks:
* nodejs/node#63985 "src: keep global list of addon-provided cleanup
  hooks" (68321eff80918e324e9fdaf1aa8cee6db14b84f7 on nodejs/node main).
* nodejs/node#65630 "src: fix use-after-free in CleanupHookThunkRun" at
  dd2fa31b1d99e5a6710e08ce4139da7c2e344598 and its regression cctest at
  fd325a7fc2b33839c024220aa0c44b9104749686 (not yet landed upstream).

Fixes: #53387

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: add node::ObjectWrap native addon GC regression spec

Adds a minimal node::ObjectWrap addon fixture with a helper that runs a
full garbage collection while no context is entered, and a spec that
loads it in an ELECTRON_RUN_AS_NODE child process and asserts the
process exits cleanly. Reproduces
#53387 on unfixed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: rebuild native addon fixtures against Electron's node headers

The native addon fixtures under spec/fixtures/native-addon are yarn
workspaces, so yarn only runs their build scripts once per install state.
In CI the root `yarn install` builds them first, against the system
Node.js headers, and the later spec install with npm_config_nodedir set
never rebuilds them. N-API fixtures load anyway, but the object-wrap
fixture uses Node's C++ API, embeds the system NODE_MODULE_VERSION, and
is rejected by Electron with ERR_DLOPEN_FAILED.

Rebuild every native addon fixture with node-gyp after the spec install
so they are compiled against the configured Electron headers, which is
what spec-runner already intended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: build C++ API addon fixtures with the Chromium toolchain on Linux

The rebuild of the native addon fixtures against Electron's node headers
broke every Linux test shard: the CI test image ships GCC 11, which
cannot parse the V8 headers (`class V8_DEPRECATE_SOON(...) V8_EXPORT
Value` mixes a C++11 attribute with a GNU attribute, rejected by GCC
<= 12, see #53284):

  v8config.h:865:20: error: expected identifier before '__attribute__'
  v8-primitive.h:658:4: error: expected '}' before 'public'

Only addons registering through Node's C++ module API (NODE_MODULE /
NODE_MODULE_INIT) embed NODE_MODULE_VERSION and need Electron's headers,
so limit the rebuild to those; the N-API fixtures keep loading fine as
built by the root install. On Linux, when the Chromium toolchain from
the source checkout is present (CI restores third_party/llvm-build and
libc++ into the test job via src_artifacts, and the nan tests already
build with it), compile the fixture with clang and Electron's libc++
exactly as script/nan-spec-runner.js does; otherwise, and for the
--electronVersion prebuilt path, keep using the system compiler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: make the Electron-header fixture rebuild opt-in and fix it on Windows

The Windows test shards failed the fixture rebuild before configure:
node-gyp inherits NPM_CONFIG_MSVS_VERSION=2022 from the test step's env,
but the runners only ship a newer Visual Studio ("msvs_version does not
match this version"). The root install that built the same fixtures ran
without that pin and picked the installed toolset, so strip it from the
rebuild environment and let node-gyp detect Visual Studio. The Electron
import library it links against is already staged by
script/actions/move-artifacts.sh as gen/node_headers/Release/node.lib.

Also replace the source scan for NODE_MODULE usage with an explicit
"electron:requiresElectronHeaders" flag in the fixture's package.json, so
only fixtures that declare they need Electron's headers (currently
object-wrap) are rebuilt and the N-API fixtures are left untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: cope with hosts that cannot build the Electron-header addon fixture

The rebuild of spec/fixtures/native-addon/object-wrap against Electron's
headers broke two more sets of Linux test shards:

* linux-arm64: the test job runs on an arm64 host but restores the x64
  Chromium toolchain of the cross-compiling build job, so node-gyp died
  with "Exec format error: .../llvm-build/Release+Asserts/bin/clang".
  The image's GCC is the one that rejects the V8 headers
  (#53284), so nothing on that
  host can compile the fixture. Check that the Chromium clang actually
  runs before selecting it; when it does not, warn loudly, skip the
  rebuild and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so the
  ObjectWrap spec is reported as skipped there (with a comment pointing
  at this gap) instead of failing with an ABI error. Every other platform
  keeps running the spec for real.

* linux-x64-asan / -ubsan: the link failed with "ld.lld: error: unable to
  find library -lc++abi". Sanitizer builds compile libc++abi into the
  electron executable and export it from there
  (export_libcxxabi_from_executables) rather than producing libc++abi.a,
  so only pass -lc++abi when that archive exists; the symbols resolve
  from the executable when the addon is loaded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit a723f64)

* test: skip the Electron-header addon specs when the spec install is skipped

The linux-arm test job runs the specs with --skipYarnInstall, so the spec
install that rebuilds spec/fixtures/native-addon/object-wrap against
Electron's headers never happens there and the ObjectWrap spec failed to
load the fixture the root install built against the system Node.js
headers ("was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 146"). When the install is needed but skipped, warn
and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so those specs are
reported as skipped, as on linux-arm64 where no toolchain can build the
fixture.

Also format the previous change with oxfmt, which `yarn lint:fmt`
flagged in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit de4cc41)

---------

Co-authored-by: Claude <noreply@anthropic.com>
MarshallOfSound pushed a commit to electron/electron that referenced this pull request Sep 3, 2026
…(43-x-y) (#53393)

* fix: backport Node.js cleanup hook fixes for node::ObjectWrap addons

Node.js 24.19.0 made node::ObjectWrap register an environment cleanup
hook but did not carry the fix that makes RemoveEnvironmentCleanupHook()
safe to call from ~ObjectWrap() during garbage collection, so any addon
built against the 24.19.0+ headers aborts with
"Assertion failed: (env) != nullptr" once one of its wrapped objects is
collected while no context is entered.

Cherry-picks:
* nodejs/node#63985 "src: keep global list of addon-provided cleanup
  hooks" (68321eff80918e324e9fdaf1aa8cee6db14b84f7 on nodejs/node main).
* nodejs/node#65630 "src: fix use-after-free in CleanupHookThunkRun" at
  dd2fa31b1d99e5a6710e08ce4139da7c2e344598 and its regression cctest at
  fd325a7fc2b33839c024220aa0c44b9104749686 (not yet landed upstream).

Fixes: #53387

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: add node::ObjectWrap native addon GC regression spec

Adds a minimal node::ObjectWrap addon fixture with a helper that runs a
full garbage collection while no context is entered, and a spec that
loads it in an ELECTRON_RUN_AS_NODE child process and asserts the
process exits cleanly. Reproduces
#53387 on unfixed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: rebuild native addon fixtures against Electron's node headers

The native addon fixtures under spec/fixtures/native-addon are yarn
workspaces, so yarn only runs their build scripts once per install state.
In CI the root `yarn install` builds them first, against the system
Node.js headers, and the later spec install with npm_config_nodedir set
never rebuilds them. N-API fixtures load anyway, but the object-wrap
fixture uses Node's C++ API, embeds the system NODE_MODULE_VERSION, and
is rejected by Electron with ERR_DLOPEN_FAILED.

Rebuild every native addon fixture with node-gyp after the spec install
so they are compiled against the configured Electron headers, which is
what spec-runner already intended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: build C++ API addon fixtures with the Chromium toolchain on Linux

The rebuild of the native addon fixtures against Electron's node headers
broke every Linux test shard: the CI test image ships GCC 11, which
cannot parse the V8 headers (`class V8_DEPRECATE_SOON(...) V8_EXPORT
Value` mixes a C++11 attribute with a GNU attribute, rejected by GCC
<= 12, see #53284):

  v8config.h:865:20: error: expected identifier before '__attribute__'
  v8-primitive.h:658:4: error: expected '}' before 'public'

Only addons registering through Node's C++ module API (NODE_MODULE /
NODE_MODULE_INIT) embed NODE_MODULE_VERSION and need Electron's headers,
so limit the rebuild to those; the N-API fixtures keep loading fine as
built by the root install. On Linux, when the Chromium toolchain from
the source checkout is present (CI restores third_party/llvm-build and
libc++ into the test job via src_artifacts, and the nan tests already
build with it), compile the fixture with clang and Electron's libc++
exactly as script/nan-spec-runner.js does; otherwise, and for the
--electronVersion prebuilt path, keep using the system compiler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: make the Electron-header fixture rebuild opt-in and fix it on Windows

The Windows test shards failed the fixture rebuild before configure:
node-gyp inherits NPM_CONFIG_MSVS_VERSION=2022 from the test step's env,
but the runners only ship a newer Visual Studio ("msvs_version does not
match this version"). The root install that built the same fixtures ran
without that pin and picked the installed toolset, so strip it from the
rebuild environment and let node-gyp detect Visual Studio. The Electron
import library it links against is already staged by
script/actions/move-artifacts.sh as gen/node_headers/Release/node.lib.

Also replace the source scan for NODE_MODULE usage with an explicit
"electron:requiresElectronHeaders" flag in the fixture's package.json, so
only fixtures that declare they need Electron's headers (currently
object-wrap) are rebuilt and the N-API fixtures are left untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: cope with hosts that cannot build the Electron-header addon fixture

The rebuild of spec/fixtures/native-addon/object-wrap against Electron's
headers broke two more sets of Linux test shards:

* linux-arm64: the test job runs on an arm64 host but restores the x64
  Chromium toolchain of the cross-compiling build job, so node-gyp died
  with "Exec format error: .../llvm-build/Release+Asserts/bin/clang".
  The image's GCC is the one that rejects the V8 headers
  (#53284), so nothing on that
  host can compile the fixture. Check that the Chromium clang actually
  runs before selecting it; when it does not, warn loudly, skip the
  rebuild and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so the
  ObjectWrap spec is reported as skipped there (with a comment pointing
  at this gap) instead of failing with an ABI error. Every other platform
  keeps running the spec for real.

* linux-x64-asan / -ubsan: the link failed with "ld.lld: error: unable to
  find library -lc++abi". Sanitizer builds compile libc++abi into the
  electron executable and export it from there
  (export_libcxxabi_from_executables) rather than producing libc++abi.a,
  so only pass -lc++abi when that archive exists; the symbols resolve
  from the executable when the addon is loaded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit a723f64)

* test: skip the Electron-header addon specs when the spec install is skipped

The linux-arm test job runs the specs with --skipYarnInstall, so the spec
install that rebuilds spec/fixtures/native-addon/object-wrap against
Electron's headers never happens there and the ObjectWrap spec failed to
load the fixture the root install built against the system Node.js
headers ("was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 146"). When the install is needed but skipped, warn
and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so those specs are
reported as skipped, as on linux-arm64 where no toolchain can build the
fixture.

Also format the previous change with oxfmt, which `yarn lint:fmt`
flagged in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit de4cc41)

---------

Co-authored-by: Claude <noreply@anthropic.com>
MarshallOfSound pushed a commit to electron/electron that referenced this pull request Sep 3, 2026
…(42-x-y) (#53394)

* fix: backport Node.js cleanup hook fixes for node::ObjectWrap addons

Node.js 24.19.0 made node::ObjectWrap register an environment cleanup
hook but did not carry the fix that makes RemoveEnvironmentCleanupHook()
safe to call from ~ObjectWrap() during garbage collection, so any addon
built against the 24.19.0+ headers aborts with
"Assertion failed: (env) != nullptr" once one of its wrapped objects is
collected while no context is entered.

Cherry-picks:
* nodejs/node#63985 "src: keep global list of addon-provided cleanup
  hooks" (68321eff80918e324e9fdaf1aa8cee6db14b84f7 on nodejs/node main).
* nodejs/node#65630 "src: fix use-after-free in CleanupHookThunkRun" at
  dd2fa31b1d99e5a6710e08ce4139da7c2e344598 and its regression cctest at
  fd325a7fc2b33839c024220aa0c44b9104749686 (not yet landed upstream).

Fixes: #53387

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: add node::ObjectWrap native addon GC regression spec

Adds a minimal node::ObjectWrap addon fixture with a helper that runs a
full garbage collection while no context is entered, and a spec that
loads it in an ELECTRON_RUN_AS_NODE child process and asserts the
process exits cleanly. Reproduces
#53387 on unfixed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: rebuild native addon fixtures against Electron's node headers

The native addon fixtures under spec/fixtures/native-addon are yarn
workspaces, so yarn only runs their build scripts once per install state.
In CI the root `yarn install` builds them first, against the system
Node.js headers, and the later spec install with npm_config_nodedir set
never rebuilds them. N-API fixtures load anyway, but the object-wrap
fixture uses Node's C++ API, embeds the system NODE_MODULE_VERSION, and
is rejected by Electron with ERR_DLOPEN_FAILED.

Rebuild every native addon fixture with node-gyp after the spec install
so they are compiled against the configured Electron headers, which is
what spec-runner already intended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: build C++ API addon fixtures with the Chromium toolchain on Linux

The rebuild of the native addon fixtures against Electron's node headers
broke every Linux test shard: the CI test image ships GCC 11, which
cannot parse the V8 headers (`class V8_DEPRECATE_SOON(...) V8_EXPORT
Value` mixes a C++11 attribute with a GNU attribute, rejected by GCC
<= 12, see #53284):

  v8config.h:865:20: error: expected identifier before '__attribute__'
  v8-primitive.h:658:4: error: expected '}' before 'public'

Only addons registering through Node's C++ module API (NODE_MODULE /
NODE_MODULE_INIT) embed NODE_MODULE_VERSION and need Electron's headers,
so limit the rebuild to those; the N-API fixtures keep loading fine as
built by the root install. On Linux, when the Chromium toolchain from
the source checkout is present (CI restores third_party/llvm-build and
libc++ into the test job via src_artifacts, and the nan tests already
build with it), compile the fixture with clang and Electron's libc++
exactly as script/nan-spec-runner.js does; otherwise, and for the
--electronVersion prebuilt path, keep using the system compiler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: make the Electron-header fixture rebuild opt-in and fix it on Windows

The Windows test shards failed the fixture rebuild before configure:
node-gyp inherits NPM_CONFIG_MSVS_VERSION=2022 from the test step's env,
but the runners only ship a newer Visual Studio ("msvs_version does not
match this version"). The root install that built the same fixtures ran
without that pin and picked the installed toolset, so strip it from the
rebuild environment and let node-gyp detect Visual Studio. The Electron
import library it links against is already staged by
script/actions/move-artifacts.sh as gen/node_headers/Release/node.lib.

Also replace the source scan for NODE_MODULE usage with an explicit
"electron:requiresElectronHeaders" flag in the fixture's package.json, so
only fixtures that declare they need Electron's headers (currently
object-wrap) are rebuilt and the N-API fixtures are left untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: cope with hosts that cannot build the Electron-header addon fixture

The rebuild of spec/fixtures/native-addon/object-wrap against Electron's
headers broke two more sets of Linux test shards:

* linux-arm64: the test job runs on an arm64 host but restores the x64
  Chromium toolchain of the cross-compiling build job, so node-gyp died
  with "Exec format error: .../llvm-build/Release+Asserts/bin/clang".
  The image's GCC is the one that rejects the V8 headers
  (#53284), so nothing on that
  host can compile the fixture. Check that the Chromium clang actually
  runs before selecting it; when it does not, warn loudly, skip the
  rebuild and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so the
  ObjectWrap spec is reported as skipped there (with a comment pointing
  at this gap) instead of failing with an ABI error. Every other platform
  keeps running the spec for real.

* linux-x64-asan / -ubsan: the link failed with "ld.lld: error: unable to
  find library -lc++abi". Sanitizer builds compile libc++abi into the
  electron executable and export it from there
  (export_libcxxabi_from_executables) rather than producing libc++abi.a,
  so only pass -lc++abi when that archive exists; the symbols resolve
  from the executable when the addon is loaded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit a723f64)

* test: skip the Electron-header addon specs when the spec install is skipped

The linux-arm test job runs the specs with --skipYarnInstall, so the spec
install that rebuilds spec/fixtures/native-addon/object-wrap against
Electron's headers never happens there and the ObjectWrap spec failed to
load the fixture the root install built against the system Node.js
headers ("was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 146"). When the install is needed but skipped, warn
and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so those specs are
reported as skipped, as on linux-arm64 where no toolchain can build the
fixture.

Also format the previous change with oxfmt, which `yarn lint:fmt`
flagged in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit de4cc41)

---------

Co-authored-by: Claude <noreply@anthropic.com>
MarshallOfSound pushed a commit to electron/electron that referenced this pull request Sep 3, 2026
…(45-x-y) (#53391)

* fix: backport Node.js cleanup hook fixes for node::ObjectWrap addons

Node.js 24.19.0 made node::ObjectWrap register an environment cleanup
hook but did not carry the fix that makes RemoveEnvironmentCleanupHook()
safe to call from ~ObjectWrap() during garbage collection, so any addon
built against the 24.19.0+ headers aborts with
"Assertion failed: (env) != nullptr" once one of its wrapped objects is
collected while no context is entered.

Cherry-picks:
* nodejs/node#63985 "src: keep global list of addon-provided cleanup
  hooks" (68321eff80918e324e9fdaf1aa8cee6db14b84f7 on nodejs/node main).
* nodejs/node#65630 "src: fix use-after-free in CleanupHookThunkRun" at
  dd2fa31b1d99e5a6710e08ce4139da7c2e344598 and its regression cctest at
  fd325a7fc2b33839c024220aa0c44b9104749686 (not yet landed upstream).

Fixes: #53387

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: add node::ObjectWrap native addon GC regression spec

Adds a minimal node::ObjectWrap addon fixture with a helper that runs a
full garbage collection while no context is entered, and a spec that
loads it in an ELECTRON_RUN_AS_NODE child process and asserts the
process exits cleanly. Reproduces
#53387 on unfixed builds.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: rebuild native addon fixtures against Electron's node headers

The native addon fixtures under spec/fixtures/native-addon are yarn
workspaces, so yarn only runs their build scripts once per install state.
In CI the root `yarn install` builds them first, against the system
Node.js headers, and the later spec install with npm_config_nodedir set
never rebuilds them. N-API fixtures load anyway, but the object-wrap
fixture uses Node's C++ API, embeds the system NODE_MODULE_VERSION, and
is rejected by Electron with ERR_DLOPEN_FAILED.

Rebuild every native addon fixture with node-gyp after the spec install
so they are compiled against the configured Electron headers, which is
what spec-runner already intended.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: build C++ API addon fixtures with the Chromium toolchain on Linux

The rebuild of the native addon fixtures against Electron's node headers
broke every Linux test shard: the CI test image ships GCC 11, which
cannot parse the V8 headers (`class V8_DEPRECATE_SOON(...) V8_EXPORT
Value` mixes a C++11 attribute with a GNU attribute, rejected by GCC
<= 12, see #53284):

  v8config.h:865:20: error: expected identifier before '__attribute__'
  v8-primitive.h:658:4: error: expected '}' before 'public'

Only addons registering through Node's C++ module API (NODE_MODULE /
NODE_MODULE_INIT) embed NODE_MODULE_VERSION and need Electron's headers,
so limit the rebuild to those; the N-API fixtures keep loading fine as
built by the root install. On Linux, when the Chromium toolchain from
the source checkout is present (CI restores third_party/llvm-build and
libc++ into the test job via src_artifacts, and the nan tests already
build with it), compile the fixture with clang and Electron's libc++
exactly as script/nan-spec-runner.js does; otherwise, and for the
--electronVersion prebuilt path, keep using the system compiler.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: make the Electron-header fixture rebuild opt-in and fix it on Windows

The Windows test shards failed the fixture rebuild before configure:
node-gyp inherits NPM_CONFIG_MSVS_VERSION=2022 from the test step's env,
but the runners only ship a newer Visual Studio ("msvs_version does not
match this version"). The root install that built the same fixtures ran
without that pin and picked the installed toolset, so strip it from the
rebuild environment and let node-gyp detect Visual Studio. The Electron
import library it links against is already staged by
script/actions/move-artifacts.sh as gen/node_headers/Release/node.lib.

Also replace the source scan for NODE_MODULE usage with an explicit
"electron:requiresElectronHeaders" flag in the fixture's package.json, so
only fixtures that declare they need Electron's headers (currently
object-wrap) are rebuilt and the N-API fixtures are left untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U

* test: cope with hosts that cannot build the Electron-header addon fixture

The rebuild of spec/fixtures/native-addon/object-wrap against Electron's
headers broke two more sets of Linux test shards:

* linux-arm64: the test job runs on an arm64 host but restores the x64
  Chromium toolchain of the cross-compiling build job, so node-gyp died
  with "Exec format error: .../llvm-build/Release+Asserts/bin/clang".
  The image's GCC is the one that rejects the V8 headers
  (#53284), so nothing on that
  host can compile the fixture. Check that the Chromium clang actually
  runs before selecting it; when it does not, warn loudly, skip the
  rebuild and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so the
  ObjectWrap spec is reported as skipped there (with a comment pointing
  at this gap) instead of failing with an ABI error. Every other platform
  keeps running the spec for real.

* linux-x64-asan / -ubsan: the link failed with "ld.lld: error: unable to
  find library -lc++abi". Sanitizer builds compile libc++abi into the
  electron executable and export it from there
  (export_libcxxabi_from_executables) rather than producing libc++abi.a,
  so only pass -lc++abi when that archive exists; the symbols resolve
  from the executable when the addon is loaded.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit a723f64)

* test: skip the Electron-header addon specs when the spec install is skipped

The linux-arm test job runs the specs with --skipYarnInstall, so the spec
install that rebuilds spec/fixtures/native-addon/object-wrap against
Electron's headers never happens there and the ObjectWrap spec failed to
load the fixture the root install built against the system Node.js
headers ("was compiled against a different Node.js version using
NODE_MODULE_VERSION 127. This version of Node.js requires
NODE_MODULE_VERSION 146"). When the install is needed but skipped, warn
and export ELECTRON_SKIP_ELECTRON_HEADER_ADDON_SPECS so those specs are
reported as skipped, as on linux-arm64 where no toolchain can build the
fixture.

Also format the previous change with oxfmt, which `yarn lint:fmt`
flagged in CI.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NawBg2exXYXTXt12SBGe9U
(cherry picked from commit de4cc41)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs with CI started, the required approvals, and no outstanding review comments. backport-open-v24.x Indicate that the PR has an open backport c++ Issues and PRs that require attention from people who are familiar with C++. commit-queue-failed PRs whose Commit Queue landing failed and need manual intervention before retrying. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Flaky crash on worker-addon-exit test

6 participants