Skip to content

crypto: avoid TLSWrap callbacks during GC#62965

Open
alexkozy wants to merge 1 commit intonodejs:mainfrom
alexkozy:fix-tlswrap-gc-destroy
Open

crypto: avoid TLSWrap callbacks during GC#62965
alexkozy wants to merge 1 commit intonodejs:mainfrom
alexkozy:fix-tlswrap-gc-destroy

Conversation

@alexkozy
Copy link
Copy Markdown
Member

@alexkozy alexkozy commented Apr 26, 2026

Description

  • Avoid invoking queued TLS write callbacks during TLSWrap destructor cleanup.
  • Preserve the existing JS-initiated destroySSL() behavior so explicit cleanup still cancels queued writes normally.

TLSWrap destructors may run during V8 weak callback processing. Calling InvokeQueued() from that path can enter StreamReq::Done(), which mutates JS-visible request objects via v8::Object::Set() and may allocate on the V8 heap while weak callbacks are being processed. V8 first-pass weak callbacks are expected to clean up native state only, not perform JS-visible heap mutation or trigger nested GC work.

We have observed a small number of production crashes consistent with this path. I attempted to build a deterministic JavaScript-only reproducer for the full failure mode, including abandoned TLS sockets with queued writes, forced major GC, debug builds, stress GC flags, and targeted lifecycle diagnostics. Those experiments reproduced abandoned TLS sockets becoming collectible after queued writes, but did not reliably reproduce the exact production race where a TLSWrap is collected while current_write_ is still pending. In normal public JS cleanup flows, _destroySSL() is usually scheduled while the socket is still strongly referenced, so the destructor path does not typically win that race.

This change therefore makes the destructor path safe by restricting it to native resource cleanup and dropping pending request references. Explicit JS cleanup continues to invoke queued callbacks as before.

@nodejs-github-bot
Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/crypto

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run. labels Apr 26, 2026
TLSWrap destructors can run from V8 weak callbacks. Avoid invoking
queued write callbacks from that path because StreamReq::Done mutates
JS-visible objects and may allocate on the V8 heap during weak callback
processing.

Refs: nodejs#62393
Made-with: Cursor
@alexkozy alexkozy force-pushed the fix-tlswrap-gc-destroy branch from 97995a0 to c43ebc8 Compare April 26, 2026 01:49
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.65%. Comparing base (42a154b) to head (c43ebc8).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #62965      +/-   ##
==========================================
+ Coverage   89.64%   89.65%   +0.01%     
==========================================
  Files         706      706              
  Lines      219394   219399       +5     
  Branches    42066    42065       -1     
==========================================
+ Hits       196674   196710      +36     
+ Misses      14629    14600      -29     
+ Partials     8091     8089       -2     
Files with missing lines Coverage Δ
src/crypto/crypto_tls.cc 77.93% <100.00%> (+0.07%) ⬆️
src/crypto/crypto_tls.h 86.66% <ø> (ø)

... and 50 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. crypto Issues and PRs related to the crypto subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants