Skip to content

src: free placeholder nodes for cppgc wrappers in MemoryTracker - #65793

Open
codebytere wants to merge 1 commit into
nodejs:mainfrom
codebytere:fix/embedder-heap-snapshot-cppgc-node-leak
Open

src: free placeholder nodes for cppgc wrappers in MemoryTracker#65793
codebytere wants to merge 1 commit into
nodejs:mainfrom
codebytere:fix/embedder-heap-snapshot-cppgc-node-leak

Conversation

@codebytere

Copy link
Copy Markdown
Member

MemoryTracker::AddNode(const CppgcMixin*) allocates a MemoryRetainerNode that only stands in for the wrapper's JS node on the tracker's stack while MemoryInfo() runs (the comment in Track() calls it a dummy). The other AddNode() overloads hand their node to the v8::EmbedderGraph, which owns it; this one does not, and nothing else freed it. Every heap snapshot, --heapsnapshot-near-heap-limit trigger or inspector HeapProfiler.takeHeapSnapshot leaked 56 bytes per live vm.Script / vm context: node -e "globalThis.s = new vm.Script('1'); v8.getHeapSnapshot()" under LSAN shows it.

The tracker now owns these placeholders and frees them when it is destroyed; its constructor and destructor move to memory_tracker-inl.h because the member needs the complete MemoryRetainerNode type. The already-seen branch of Track(const CppgcMixin*) adds its edge to the wrapper's JS node like the first visit does, so nothing in the graph ever points at a placeholder.

Tests: EnvironmentTest.HeapSnapshotWithCppgcWrappersDoesNotLeak takes a heap snapshot from C++ with a vm.Script and a context alive; LeakSanitizer reports the nodes before and is clean after (it asserts nothing without LSAN). test-heapsnapshot*, test-v8-*heap*, test-heapdump* and pummel/test-heapdump-vm-script pass.

Refs: #56534


Disclosure: the code, test and this description were written by Claude Code, directed and reviewed by @codebytere.

`MemoryTracker::AddNode(const CppgcMixin*)` allocates a
`MemoryRetainerNode` that only stands in for the wrapper's JS node while
its `MemoryInfo()` runs; unlike the other node kinds it is not handed
to the `EmbedderGraph`, and nothing freed it. Every heap snapshot (or
other `BuildEmbedderGraph` call) leaked one node per live `vm.Script`
or `vm` context.

Keep the placeholders in the tracker and free them with it, and make
the already-seen path in `Track(const CppgcMixin*)` add its edge to the
wrapper's JS node like the first visit does, so the graph never refers
to a placeholder.

Refs: nodejs#56534
Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
@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 Sep 4, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@codecov

codecov Bot commented Sep 4, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 90.14%. Comparing base (2befec5) to head (191eee3).
⚠️ Report is 60 commits behind head on main.

Files with missing lines Patch % Lines
src/memory_tracker-inl.h 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #65793      +/-   ##
==========================================
+ Coverage   89.99%   90.14%   +0.14%     
==========================================
  Files         757      769      +12     
  Lines      257739   261450    +3711     
  Branches    48881    49644     +763     
==========================================
+ Hits       231961   235685    +3724     
+ Misses      16861    16786      -75     
- Partials     8917     8979      +62     
Files with missing lines Coverage Δ
src/memory_tracker.h 100.00% <ø> (ø)
src/memory_tracker-inl.h 74.40% <83.33%> (+0.41%) ⬆️

... and 94 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++. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants