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

Memory leaks in unpackaged C++-Desktop-App #9534

Open
Woopsalla opened this issue Apr 9, 2024 · 3 comments
Open

Memory leaks in unpackaged C++-Desktop-App #9534

Woopsalla opened this issue Apr 9, 2024 · 3 comments
Labels
team-Reach Issue for the Reach team

Comments

@Woopsalla
Copy link

Describe the bug

I created an unpackaged desktop app with the VS template "Blank App, Packaged (WinUI 3 in Desktop)" and only added some code (_CrtSetDbgFlag etc.) to detect memory leaks. When the app is started and stopped again with VS, memory leaks are shown.
Then I added some code that draws something in a canvas again and again to demonstrate rapidly growing storage requirements when an app has to update drawn content periodically.

Steps to reproduce the bug

  1. Download the following app and build the debug version:
    UnpackagedDesktopApp_MemLeak_SDK1_5_1.zip
  2. Start and stop the app in the Visual Studio without clicking the demo button.
  3. Check the memory leaks in the output window of the VS.
  4. Open the task manager to check memory requirements of the app.
  5. Start the app again and click the button.
  6. Monitor the growing memory requirements in the task manager.
    ...

Expected behavior

No memory leaks.
No growing memory requirements due to updated drawings.

Screenshots

No response

NuGet package version

Windows App SDK 1.5.1: 1.5.240311000

Packaging type

Unpackaged

Windows version

Windows 10 version 22H2 (19045, 2022 Update)

IDE

Visual Studio 2022

Additional context

No response

@DarranRowe
Copy link

DarranRowe commented Apr 11, 2024

For the first leak you mention here, it is a harmless leak.
When you create an instance of Application, via App, the runtime stashes an extra reference to Application somewhere. This is never released when the process exits. You can verify this by defining a destructor in App and placing a breakpoint in it, the breakpoint is never hit.
If you do some nasty things and release that final reference to App, the leaks almost completely go away. For example, if I override the Xaml defined entry point function and use the following:

#include "pch.h"
#include "App.xaml.h"

void nasty_stuff_that_frees_the_application(const winrt::Microsoft::UI::Xaml::Application &app);
void check_process_requirements();

int APIENTRY wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPWSTR, _In_ int)
{
	check_process_requirements();

	auto flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
	flags = (flags & 0x0000ffff) | _CRTDBG_LEAK_CHECK_DF;
	_CrtSetDbgFlag(flags);

	winrt::Microsoft::UI::Xaml::Application app = nullptr;

	winrt::Microsoft::UI::Xaml::Application::Start(
		[&app](auto &&)
		{
			app = winrt::make<winrt::Meh::implementation::App>();
		});

	nasty_stuff_that_frees_the_application(app);
	app = nullptr;

	return 0;
}

The following is the left over detected blocks of memory left allocated:

Detected memory leaks!
Dumping objects ->
{406} normal block at 0x000002D3241429D0, 32 bytes long.
 Data: <0 E       E     > 30 86 45 00 F6 7F 00 00 00 86 45 00 F6 7F 00 00 
{272} normal block at 0x000002D324142E50, 24 bytes long.
 Data: < -              > 18 2D 07 17 FF 7F 00 00 01 00 00 00 00 00 00 00 
Object dump complete.
The program '[15928] Meh.exe' has exited with code 0 (0x0).

I'm not going into how I released that last reference to Application because it is guaranteed to leave a dangling pointer somewhere in the Xaml runtime. While it doesn't cause problems now for short periods after it is deleted, there is no guarantee that there will never be a use after free in the future. If you want to work it out yourself, it is basically obtaining the ABI interface and releasing it without an AddRef or QI. But this is certainly not something that you should do, I'm only doing it here to illustrate a point.

The remaining two blocks could be related to the dispatcher queue, which I don't believe gets shut down either. But these are harmless because the amount of blocks does not grow and Windows will reclaim the memory when the process' heap gets destroyed when the process exits. However, I understand that these leaks can get in the way of debugging.

@Woopsalla
Copy link
Author

Thank you, Darran, for clarifying the facts. That at least explains that part. And yes, of course this makes troubleshooting more difficult and should definitely be fixed.
However, the second problem pointed out by the application is much more problematic (see points 5 and 6). The constantly growing memory requirements of the application will paralyse the system in a relatively short time. For our actual application, the memory problem is even worse, as it has to update an extensive GUI at very short intervals. This is currently preventing us from delivering the product and is absolutely critical.
It may not be a memory leak in the classic sense, but only in the sense that the memory is apparently still being released correctly before the app is exited. But not as long as the app is running. So it's just a question of timing.
Of course, it is important that this problem is fixed, because it is serious. For the moment, however, an explanation would help me, and above all a workaround.

@bpulliam bpulliam transferred this issue from microsoft/WindowsAppSDK Apr 11, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the needs-triage Issue needs to be triaged by the area owners label Apr 11, 2024
@bpulliam bpulliam added team-Reach Issue for the Reach team and removed needs-triage Issue needs to be triaged by the area owners labels Apr 11, 2024
@Woopsalla
Copy link
Author

In my opinion, an application that generates its own graphical elements and updates their display regularly is a standard use case. If such applications cause the user systems to crash, this is highly critical. Accordingly, this problem should also be classified here!
Is there anyone in the Microsoft team who can help with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Reach Issue for the Reach team
Projects
None yet
Development

No branches or pull requests

3 participants