microsoft / microsoft/vscode-js-debug

Extension host OOM serializing breakpoint predictor cache

Open
#2,407 0 comments 0 reactions 1 assignee View on GitHub

@connor4312 is already working on this.

Since Sep 4, 2026.

bug
Dominant language
TypeScript
Stars
2k
Forks
373
Avg merge
1d 9m
Merged PRs (30d)
6

Description

Summary

A VS Code Insiders extension host crashed with a native V8 OOM while attaching/debugging from a large workspace. Symbolication points to JSON.stringify() of the breakpoint predictor cache as the final allocation.

Possibly related to #2173, but this dump identifies a specific allocation and call site.

Environment

  • VS Code Insiders: 1.137.0-insider (1f625adb84abf41cdff31f40f66e58a222f033f6)
  • Electron: 42.10.0
  • macOS arm64
  • Process: local extension host (node.mojom.NodeService)
  • Process uptime: 5,853 seconds

Symbolicated crashing thread

partition_alloc::internal::OnNoMemoryInternal
partition_alloc::TerminateBecauseOutOfMemory
(anonymous namespace)::V8OOMErrorCallback
v8::internal::V8::FatalProcessOutOfMemory
v8::internal::HeapAllocator::AllocateRawSlowPath
v8::internal::Factory::NewStringFromTwoByte
v8::internal::JsonStringify
<JavaScript frames>
node::fs::FSReqPromise<...>::Resolve
node::fs::AfterMkdirp

The NewStringFromTwoByte length argument was 0x55b8eb, or 5,617,899 characters.

The same workspace's ms-vscode.js-debug/bp-predict.json is 5,617,904 bytes, effectively matching the failed allocation. Its top-level key describes the default workspace scan rooted at <workspace>/out/**/*.js.

This matches BreakpointPredictorCachedState.store():

await fs.mkdir(path.dirname(this.path), { recursive: true });
await fs.writeFile(this.path, JSON.stringify(value));

V8 OOM annotations

heap.limit             4,294,967,296
heap.used              3,585,540,660 (83.5%)
heap.total             3,747,840,000
heap.total_available     552,433,816
old_space.size         2,636,120,064
old_space.used         2,506,918,964 (95.1%)
external_memory           95,189,642
location               CALL_AND_RETRY_LAST

The extension host had already grown close to the old-space limit while processing the workspace. Serializing the roughly 5.6 MB cache required one additional complete two-byte V8 string and became the fatal allocation.

Additional context

  • Only one matching crash dump was present in the 24-hour window, so I cannot compare signatures across multiple dumps.
  • The extension-host trace contained heavy activity immediately before the crash, including large bursts of setContext/_setContext, but the failed allocation size and native stack point directly to breakpoint-cache serialization.
  • I have not attached the dump or full logs because they contain local paths. I can provide the dump privately if useful.

Could you determine the appropriate fix in js-debug? The underlying memory growth may be broader than the final cache serialization.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.