microsoft / vscode

Visual Studio Code
https://code.visualstudio.com
MIT License
164.82k stars 29.49k forks source link

TreeView: Maximum call stack size exceeded error - Siblings #230361

Closed RedCMD closed 1 month ago

RedCMD commented 1 month ago

Max call stack error when there's too many nodes in a TreeView

Steps to Reproduce:

  1. Install JSON TextMate extension
  2. Load a file that causes a TextMate grammar to match many many rules typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<int>::type>::type>::type>::type>::type>::type>::type>::type>::type ptr{nullptr}; works well in a CPP file
  3. right click => Show TextMate Calling Stack
  4. wait for file to be parsed
  5. wait even longer for VSCode to attempt to render the tree (notice memory usage going up)
  6. Max Call Stack error
  ERR Maximum call stack size exceeded: RangeError: Maximum call stack size exceeded
    at E.U (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:191:12436)
    at E.splice (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:191:11388)
    at vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:4:9067
    at Array.forEach (<anonymous>)
    at t.splice (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:4:9054)
    at vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:234:8098
    at A.bufferEvents (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:100:3899)
    at te.splice (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:234:8074)
    at te.splice (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:628:64439)
    at f.t (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:187:27391)
    at f.splice (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:187:25598)
    at L.l (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:187:34140)
    at L.setChildren (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:187:33684)
    at C.setChildren (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:629:6619)
    at Re.J (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:629:23716)
    at Re.C (vscode-file://vscode-app/e:/VSCode-win32-x64/resources/app/out/vs/workbench/workbench.desktop.main.js:629:20783)

Seems TreeView cant expand more than 170k nesting nodes all at once

related: #61524

alexr00 commented 1 month ago

I get an exception in the extension when I try to use it.

workbench.web.main.internal.js:3109  Error: No grammar provided for <undefined>
    at collectReferencesOfReference (/home/node/.vscode-remote/extensions/redcmd.tmlanguage-syntax-highlighter-2.5.0/out/textmate/grammar/grammarDependencies.js:102:19)
    at ScopeDependencyProcessor.processQueue (/home/node/.vscode-remote/extensions/redcmd.tmlanguage-syntax-highlighter-2.5.0/out/textmate/grammar/grammarDependencies.js:71:13)
    at Registry._loadGrammar (/home/node/.vscode-remote/extensions/redcmd.tmlanguage-syntax-highlighter-2.5.0/out/textmate/main.js:81:33)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at tokenizeFile (/home/node/.vscode-remote/extensions/redcmd.tmlanguage-syntax-highlighter-2.5.0/out/TextMate.js:204:21)
    at Object.getChildren (/home/node/.vscode-remote/extensions/redcmd.tmlanguage-syntax-highlighter-2.5.0/out/Providers/TreeDataProvider.js:34:23)
    at vy.Y (file:///vscode/bin/linux-x64/d78a74bcdfad14d5d3b1b782f87255d802b57511-insider/out/vs/workbench/api/node/extensionHostProcess.js:156:13744)
    at vy.getChildren (file:///vscode/bin/linux-x64/d78a74bcdfad14d5d3b1b782f87255d802b57511-insider/out/vs/workbench/api/node/extensionHostProcess.js:156:10258)

Do you have a minimal repro I could use?

RedCMD commented 1 month ago

there was no language assigned to the file? I should prob handle that and show a friendly error

assign language CPP and use example text:

typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<typename::std::add_pointer<int>::type>::type>::type>::type>::type>::type>::type>::type>::type ptr{nullptr};

image

I'll look into making a repo

alexr00 commented 1 month ago

The language assigned to the file was C++, and syntax highlighting reflecdted that. I even saved it as a C++ file.

RedCMD commented 1 month ago

repo: https://github.com/RedCMD/TreeViewMaxCallStackError

13000 sibling nodes: ```rust ERR RangeError: Maximum call stack size exceeded at UJi.K (asyncDataTree.ts:1447:17) at UJi.H (asyncDataTree.ts:1308:16) at async UJi.G (asyncDataTree.ts:1274:30) at async UJi.E (asyncDataTree.ts:1229:3) at async UJi.C (asyncDataTree.ts:971:3) at async UJi.updateChildren (asyncDataTree.ts:957:3) at async Promise.all (index 0) at async J5e.Sb (treeView.ts:1058:5) ```

notice if you lower the sibling nodes down to 125000, it doesn't error but VSCode takes a very very long time to display them even tho the extension returns every single node in less than a 100ms

4000 nested nodes: ```rust ERR RangeError: Maximum call stack size exceeded at Object.g [as map] (iterator.ts:79:19) at UJi.M (asyncDataTree.ts:1500:42) at asyncDataTree.ts:1500:75 at Object.g [as map] (iterator.ts:82:10) at g.next () at Object.g [as map] (iterator.ts:81:14) at g.next () at URi.x (indexTreeModel.ts:519:14) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) at URi.x (indexTreeModel.ts:520:23) ```

notice if you lower the nested nodes to 3000 and after the tree has been displayed, scrolling down too far causes VSCode to freeze

RedCMD commented 1 month ago

@alexr00 once a MaxCallStackError occurs it permanently breaks the TreeView and requires VSCode to be restarted

alexr00 commented 1 month ago

Thank you for the repo! I can easily fix the call stack issue. The slowness is coming from many cross process calls. I'm tracking that here: https://github.com/microsoft/vscode/issues/232263