Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Latest VS 2019 update causes VS to hang and results in OOM #186

Closed
mackie89 opened this issue Jan 24, 2025 · 15 comments
Closed

Latest VS 2019 update causes VS to hang and results in OOM #186

mackie89 opened this issue Jan 24, 2025 · 15 comments

Comments

@mackie89
Copy link

Hey

The latest update from 01/24/25 seem to cause my VS2019 to hang on loading the project, and seems to result in an out of memory exception.

<entry>
    <record>8369</record>
    <time>2025/01/24 20:06:50.658</time>
    <type>Error</type>
    <source>VisualStudio</source>
    <description>SetSite failed for package [CmdArgsPackage]Source: &apos;System&apos; Description: 
	Exception of type &apos;System.OutOfMemoryException&apos; was thrown.&#x000D;&#x000A;System.OutOfMemoryException: 
	Exception of type &apos;System.OutOfMemoryException&apos; was thrown.&#x000D;&#x000A;   
	at System.Dynamic.ComRuntimeHelpers.CheckThrowException(Int32 hresult, ExcepInfo&amp; excepInfo, UInt32 argErr, String message)&#x000D;&#x000A;   
	at CallSite.Target(Closure , CallSite , ComObject )&#x000D;&#x000A;   
	at CallSite.Target(Closure , CallSite , Object )&#x000D;&#x000A;   
	at SmartCmdArgs.Services.ProjectConfigService.GetItemsFromVCProjEngineConfig(Project project, List`1 allArgs, Boolean includeArgs, Boolean includeEnvVars, Boolean includeWorkDir, Boolean includeLaunchApp)&#x000D;&#x000A;   
	at SmartCmdArgs.Services.ProjectConfigService.GetItemsFromProjectConfig(IVsHierarchyWrapper project)&#x000D;&#x000A;   
	at SmartCmdArgs.Services.ViewModelUpdateService.UpdateCommandsForProject(IVsHierarchyWrapper project)&#x000D;&#x000A;   
	at SmartCmdArgs.Services.LifeCycleService.InitializeDataForSolution()&#x000D;&#x000A;   
	at SmartCmdArgs.Services.LifeCycleService.IsEnabledChanged()&#x000D;&#x000A;   
	at SmartCmdArgs.Services.LifeCycleService.set_IsEnabledSaved(Nullable`1 value)&#x000D;&#x000A;   
	at SmartCmdArgs.Services.LifeCycleService.InitializeConfigForSolution()&#x000D;&#x000A;   
	at SmartCmdArgs.CmdArgsPackage.&lt;InitializeAsync&gt;d__23.MoveNext()&#x000D;&#x000A;
	--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   
	at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)&#x000D;&#x000A;   
	at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Shell.AsyncPackage.&lt;&gt;c__DisplayClass20_0.&lt;&lt;Microsoft-VisualStudio-Shell-Interop-IAsyncLoadablePackageInitialize-Initialize&gt;b__1&gt;d.MoveNext()&#x000D;&#x000A;
	--- End of stack trace from previous location where exception was thrown ---&#x000D;&#x000A;   
	at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)&#x000D;&#x000A;   
	at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Shell.UIThreadReentrancyScope.WaitOnTaskCompleteInternal(Task task, CancellationToken cancel, Int32 ms)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.&lt;&gt;c__DisplayClass100_1.&lt;InternalGetResult&gt;b__1()&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.IgnoreObjectDisposedException(Action action)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.&lt;&gt;c__DisplayClass100_0.&lt;InternalGetResult&gt;b__0()&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.&lt;&gt;c__DisplayClass108_0.&lt;InvokeWithWaitDialog&gt;b__0()&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.InvokeWithWaitDialog[T](Func`1 function)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.InvokeWithWaitDialog(Action action)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.InternalGetResult(Boolean ignoreUIThreadCheck)&#x000D;&#x000A;   
	at Microsoft.VisualStudio.Services.VsTask.GetResult()</description>
    <guid>{131B0C0A-5DD0-4680-B261-86AB5387B86E}</guid>
    <hr>8007000e - E_OUTOFMEMORY</hr>
    <errorinfo></errorinfo>
  </entry>
@mackie89
Copy link
Author

Hmmm that's weird even rolling back to a previous version doesn't seem to stop the hang. I even wiped my vcxproj.user file that contained my cmd args, it still hangs. This is a Unreal Engine project, I wonder if there has been something else that change that isn't playing well with this extension now.

@skyleryork
Copy link

Same issue here for multiple developers, using VS2022 on non-UE projects/solutions. There's ~5 minute hang on launch and devenv.exe uses ~15GB of RAM before becoming responsive again. Delay seems to vary depending on the size/complexity of the solution.

@Irame
Copy link
Collaborator

Irame commented Jan 26, 2025

Hi, sorry for the late response, I will investigate the issue.

The code path in the call stack should only be executed if the project does not have any data available (.suo or .json file) for the extension. The extension then tries to gather all the used arguments from the VS configuration. But this is done on a per project basis and if you opened the solution before there should be a configuration for each project for the extension to look at.
Are there any other log entries that come from the extension that you can share with me?

This does not explain the Issue but I am wondering if @skyleryork does trigger the same code path. Do you have any log files (or log entries) for me to look at? Could you also give me the kind of solution you have (C++, C#, ...).

@amuTBKT
Copy link

amuTBKT commented Jan 26, 2025

I am facing a similar issue with my UE5 project (both at work and home).
Visual Studio: 17.11.5
Windows 10 Build 19045.5371
SmartCommandLineargs v3.2.0

I don't remember updating my Visual Studio, the issue just seem to happen overnight (one day was working fine next day started taking 5mins to load the project)
I think the only thing that changed for me was probably windows update, not sure how that could break the plugin ^^'

Issue:
From what I can tell we only save the *.args.json file for a project upon modification. Unreal project usually has the game project as startup while the main UE5 engine project is usually just added to the solution (not active by default). So the UE5.args.json file is never saved.
As a result every time the solution is opened, it takes a very long time to process UE5 project inside GetItemsFromVCProjEngineConfig function.

Workaround:

  • Manually create UE5.args.json under $(ProjectDir) directory.
  • Set UE5 to startup, add a dummy arg and ensure the file is created.

@Irame
Copy link
Collaborator

Irame commented Jan 26, 2025

Thanks for the detailed comment.

The issue comes from accessing the config of each C++ project to collect the command line args. This is done because there aren't any ".args.json" files for these projects and therefore they are "new" to the extension. To avoid ignoring already set arguments we scan those projects and add the arguments to the extension.
For other projects types the cost of accessing the config isn't that high so it usually does not matter. As I fixed the collection of command line arguments for C++ projects with the last release the issue arose.

I am a bit confused as in how creating a .args.json file for a single project solves the issue as the extension should still scan the rest of the solution.

I implemented a solution for you to test. It basically asks you if you want to ignore C++ projects from the command args collection process when it finds more than 15 C++ projects.

SmartCmdArgs-vs2017-v3.2.0.1.vsix.zip
SmartCmdArgs-vs2019-v3.2.0.1.vsix.zip
SmartCmdArgs-vs2022-v3.2.0.1.vsix.zip
(I had to zip them, because GitHub does not allow .vsix files)

It would be nice if you could test the solution and share you feedback, thanks!

@skyleryork
Copy link

Hi, sorry for the late response, I will investigate the issue.

The code path in the call stack should only be executed if the project does not have any data available (.suo or .json file) for the extension. The extension then tries to gather all the used arguments from the VS configuration. But this is done on a per project basis and if you opened the solution before there should be a configuration for each project for the extension to look at. Are there any other log entries that come from the extension that you can share with me?

This does not explain the Issue but I am wondering if @skyleryork does trigger the same code path. Do you have any log files (or log entries) for me to look at? Could you also give me the kind of solution you have (C++, C#, ...).

I'm not sure about the callstack, but this is a solution with hundreds of C++ projects, so it makes sense that scanning would be the bottleneck. But only a single project builds an executable target, and it already has an .args.json that I've been using for a long time. Is it supposed to scan library projects, and/or generate argument files once it does? As far as I can tell, it doesn't create any new files so there's nothing to stop it from repeating the scan every time.

@amuTBKT
Copy link

amuTBKT commented Jan 27, 2025

@Irame Thanks for the patch, I'll check if those changes fixes the issue for me.

I am a bit confused as in how creating a .args.json file for a single project solves the issue as the extension should still scan the rest of the solution.
UE5 project has more than 50 configurations 😅 (as reported inside GetItemsFromVCProjEngineConfig function), remaining projects in the soluton are C# Programs so doesn't take too long for them.
Image

Not sure about the issue @skyleryork is facing. Since their project is non UE5 maybe something changed internally on how VS extensions handle project loading? (I don't have much experience in this area 😞)

@BleuBleu
Copy link

BleuBleu commented Jan 27, 2025

Hi.

Had the same issue as everyone here. This morning VS2022 completely stalled opening a pretty big UE solution.
I tested the 3.2.0.1 version and it asked me if I wanted to ignore C++ project and I said yes and now things seem to work.

Now do we know why we were previously able to scan everything and that it suddenly stopped working? That's a bit worrying.

-Mat

@Irame
Copy link
Collaborator

Irame commented Jan 27, 2025

@amuTBKT:

UE5 project has more than 50 configurations 😅 (as reported inside GetItemsFromVCProjEngineConfig function), remaining projects in the solution are C# Programs so doesn't take too long for them. Image

Interesting, how long does it hang on startup? The change I have made only applies to solutions with more than 15 C++ projects. If it can already be the case that the load time is unbearable with one project I should disable scanning for C++ projects all together (like it was before the fix).


@BleuBleu:

Now do we know why we were previously able to scan everything and that it suddenly stopped working? That's a bit worrying.

Previously C++ projects weren't scanned properly because it wasn't correctly implemented.

@amuTBKT
Copy link

amuTBKT commented Jan 27, 2025

I do remember the issue you are referring to, earlier it used to clear the commandline for Unreal (C++) projects xD
It was a nice QoL update, but I guess makes sense to allow disabling it for cases like this :(

For me the single UE5 project takes ~4-5 minutes to load. My project is on a HDD too, so that probably doesn't help :p
Image

I am just not sure why I am seeing the issue now?

  • I've not updated the plugin
  • Using the same VS version for the past few months
  • I have been using that project for years (not a new project, so I never had the UE5.args.json file in my project)

@Irame
Copy link
Collaborator

Irame commented Jan 27, 2025

The extension updates itself unfortunately. Even if I mark it as preview...

@mundifex
Copy link

It would be great to have a configuration option to opt-out of the new behavior and revert to old behavior which has served well for years. Scanning just the project marked as Startup would be ideal in my case, as it's the only project for which I will ever configure command-line arguments.

@mackie89
Copy link
Author

Yeah the patch seems to work for me, I can now open my UE4 project at regular speed again :)
Small side note, I was not able to see the entire message when the popup appeared.

Image

Agree with @mundifex that if it only scanned the Startup project that would be great, I only ever change args for that one.
Also wonder why accessing the config of each C++ project is so bad?

@Irame
Copy link
Collaborator

Irame commented Feb 2, 2025

I implemented a different way to deal with the problem. It allows for a better default handling.
This version gathers existing arguments from C++ projects only for startup projects per default.

This behavior is configurable in the options (I think I'll also put it in the solutions settings dialog):

  • Ignore C++ projects
  • Gather args only from startup projects (default)
  • Gather args from all projects

SmartCmdArgs-vs2017-v3.2.0.2.vsix.zip
SmartCmdArgs-vs2019-v3.2.0.2.vsix.zip
SmartCmdArgs-vs2022-v3.2.0.2.vsix.zip
(I had to zip them, because GitHub does not allow .vsix files)

@mundifex
Copy link

mundifex commented Feb 2, 2025

Tested using 3.2.0.2 and performance is back to expected in Visual Studio. Thank you for implementing a fix!

@Irame Irame closed this as completed Feb 5, 2025
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

No branches or pull requests

6 participants