Skip to content

Conversation

@SimonSiefke
Copy link
Contributor

Fixes a memory leak in linkDetector.ts by replacing HTMLElement.onclick with dom.addDisposableListener('click').

Because of that, now the disposable store also needs to be passed from one function to another and another. But the main change is replacing HTMLElement.onclick with dom.addDisposableListener('click').

Test Results

Before

A keydown, click, mouseleave and mousemove event listener leak related to linkDetector are found:

{
  "eventListenersWithStackTrace": [
    {
      "type": "keydown",
      "description": "l=>{const c=new Li(l);(c.keyCode===3||c.keyCode===10)&&(c.preventDefault(),c.stopPropagation(),r(c.keyCode===10))}",
      "objectId": "-6136671504294265107.1.22263",
      "count": 133,
      "originalStack": ["src/vs/workbench/contrib/debug/browser/linkDetector.ts:338:19"],
      "originalName": "e"
    },
    {
      "type": "click",
      "description": "l=>{const c=Te(e).getSelection();!c||c.type===\"Range\"||(Ye?l.metaKey:l.ctrlKey)&&(l.preventDefault(),l.stopImmediatePropagation(),r(!1))}",
      "objectId": "-6136671504294265107.1.22261",
      "count": 133,
      "originalStack": ["src/vs/workbench/contrib/debug/browser/linkDetector.ts:325:18"],
      "originalName": "event"
    },
    {
      "type": "mouseleave",
      "description": "()=>e.classList.remove(\"pointer\")",
      "objectId": "-6136671504294265107.1.22259",
      "count": 133,
      "originalStack": ["src/vs/workbench/contrib/debug/browser/linkDetector.ts:324:22"],
      "originalName": null
    },
    {
      "type": "mousemove",
      "description": "l=>{e.classList.toggle(\"pointer\",Ye?l.metaKey:l.ctrlKey)}",
      "objectId": "-6136671504294265107.1.22257",
      "count": 133,
      "originalStack": ["src/vs/workbench/contrib/debug/browser/linkDetector.ts:323:22"],
      "originalName": "event"
    }
  ],
  "isLeak": true
}

After

No more leak is detected.

connor4312
connor4312 previously approved these changes Dec 15, 2025
Copy link
Member

@connor4312 connor4312 left a comment

Choose a reason for hiding this comment

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

thanks!

@vs-code-engineering vs-code-engineering bot added this to the December / January 2026 milestone Dec 15, 2025
@connor4312 connor4312 enabled auto-merge (squash) December 15, 2025 22:58
rzhao271
rzhao271 previously approved these changes Dec 15, 2025
@roblourens
Copy link
Member

Build error: Error: [define-class-fields-check] src/vs/workbench/contrib/debug/browser/exceptionWidget.ts(103,89): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'DebugLinkHoverBehaviorTypeData'.

auto-merge was automatically disabled December 16, 2025 15:33

Head branch was pushed to by a user without write access

@SimonSiefke SimonSiefke dismissed stale reviews from connor4312 and rzhao271 via 38fda63 December 16, 2025 15:33
@SimonSiefke SimonSiefke marked this pull request as draft December 16, 2025 15:34
@SimonSiefke SimonSiefke marked this pull request as ready for review December 16, 2025 16:22
@SimonSiefke
Copy link
Contributor Author

Thanks!

  • Fixed the typescript error
  • Fixed disposable warnings in tests

It should be good to go now!

@connor4312
Copy link
Member

thanks!

@connor4312 connor4312 enabled auto-merge (squash) December 16, 2025 16:44
connor4312
connor4312 previously approved these changes Dec 16, 2025
@connor4312
Copy link
Member

Looks like something in the tests might be missing a disposable check 😬

  Debug - Link Detector
    ✔ noLinks
    ✔ trailingNewline
    ✔ trailingNewlineSplit
    ✔ singleLineLink
[10314:1216/164627.144861:INFO:CONSOLE:230] "Error: Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!
    at _DisposableStore.add (file:///mnt/vss/_work/vscode/vscode/out/vs/base/common/lifecycle.js:323:22)
    at LinkDetector.decorateLink (file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:253:25)
    at file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:234:12", source: file:///mnt/vss/_work/vscode/vscode/test/unit/electron/renderer.js (230)
[10314:1216/164627.144934:INFO:CONSOLE:230] "Error: Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!
    at _DisposableStore.add (file:///mnt/vss/_work/vscode/vscode/out/vs/base/common/lifecycle.js:323:22)
    at LinkDetector.decorateLink (file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:256:25)
    at file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:234:12", source: file:///mnt/vss/_work/vscode/vscode/test/unit/electron/renderer.js (230)
[10314:1216/164627.144972:INFO:CONSOLE:230] "Error: Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!
    at _DisposableStore.add (file:///mnt/vss/_work/vscode/vscode/out/vs/base/common/lifecycle.js:323:22)
    at LinkDetector.decorateLink (file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:259:25)
    at file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:234:12", source: file:///mnt/vss/_work/vscode/vscode/test/unit/electron/renderer.js (230)
[10314:1216/164627.144991:INFO:CONSOLE:230] "Error: Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!
    at _DisposableStore.add (file:///mnt/vss/_work/vscode/vscode/out/vs/base/common/lifecycle.js:323:22)
    at LinkDetector.decorateLink (file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:271:25)
    at file:///mnt/vss/_work/vscode/vscode/out/vs/workbench/contrib/debug/browser/linkDetector.js:234:12", source: file:///mnt/vss/_work/vscode/vscode/test/unit/electron/renderer.js (230)
    1) "after each" hook for "singleLineLink"


  8628 passing (25s)
  161 pending
  1 failing

  1) "after each" hook for "singleLineLink":

      
      + expected - actual

      -false
      +true
      
  AssertionError [ERR_ASSERTION]: Error: Unexpected console output in test run. Please ensure no console.[log|error|info|warn] usage in tests or runtime errors.
      at Context.<anonymous> (renderer.js:298:11)

joaomoreno
joaomoreno previously approved these changes Dec 16, 2025
auto-merge was automatically disabled December 16, 2025 16:57

Head branch was pushed to by a user without write access

@SimonSiefke SimonSiefke dismissed stale reviews from joaomoreno and connor4312 via c766088 December 16, 2025 16:57
@SimonSiefke
Copy link
Contributor Author

Thanks!

  • Fixed another issue where a adding a decoration after fileSystem stat call, could add elements to a disposed store
/* Since this is async. when the promise resolves, the store might be disposed */
this.fileService.stat(uri).then(stat => {
	if (stat.isDirectory) {
		return;
	}
	this.decorateLink(link, uri, fulltext, hoverBehavior, (preserveFocus: boolean) => this.editorService.openEditor({ resource: uri, options: { ...options, preserveFocus } }));
}

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.

6 participants