winget-cli icon indicating copy to clipboard operation
winget-cli copied to clipboard

Access violation during process exit due to ComStaticStorageStatics

Open Fulgen301 opened this issue 1 month ago • 1 comments

Relevant area(s)

WinGet CLI, COM API

Relevant command(s)

No response

Brief description of your issue

It seems WinGet has regressed from 1.10.320 and is once again executing COM code during DLL uninitialization, when COM has already been unloaded.

Steps to reproduce

I tried this code (complete project attached):

int main()
{
	winrt::check_hresult(CoInitializeEx(nullptr, COINIT_MULTITHREADED));
	const struct Cleanup { ~Cleanup() { CoUninitialize();  } } cleanup;

	const auto packageManager{ CreateWinGetInstance<winget::PackageManager>(CLSID_PackageManager) };

	auto catalog = packageManager.GetPackageCatalogByName(L"winget");
	winrt::check_hresult(catalog.Connect().ExtendedErrorCode());
	return 0;
}

WinGetBug-COM-AccessViolation.zip

Expected behavior

It works.

Actual behavior

I get an access violation during process cleanup.

0:000> k
 # ChildEBP RetAddr      
00 (Inline) --------     WindowsPackageManager!winrt::impl::consume_Windows_ApplicationModel_Core_ICoreApplication<winrt::Windows::ApplicationModel::Core::ICoreApplication>::Properties+0xe [C:\__w\1\b\x86\Release\AppInstallerSharedLib\Generated Files\winrt\Windows.ApplicationModel.Core.h @ 86] 
01 (Inline) --------     WindowsPackageManager!winrt::Windows::ApplicationModel::Core::CoreApplication::Properties::__l2::<lambda_1>::operator()+0xe [C:\__w\1\b\x86\Release\AppInstallerSharedLib\Generated Files\winrt\Windows.ApplicationModel.Core.h @ 1082] 
02 (Inline) --------     WindowsPackageManager!winrt::impl::call_factory_cast+0x2a [C:\__w\1\b\x86\Release\AppInstallerSharedLib\Generated Files\winrt\base.h @ 6511] 
03 (Inline) --------     WindowsPackageManager!winrt::Windows::ApplicationModel::Core::CoreApplication::Properties+0x2a [C:\__w\1\b\x86\Release\AppInstallerSharedLib\Generated Files\winrt\Windows.ApplicationModel.Core.h @ 1082] 
04 00b3f590 621f40a3     WindowsPackageManager!AppInstaller::WinRT::COMStaticStorageStatics::ResetAll+0xd7 [C:\__w\1\s\external\pkg\src\AppInstallerSharedLib\COMStaticStorage.cpp @ 34] 
05 00b3f5b8 672d29c9     WindowsPackageManager!WindowsPackageManagerInProcModuleTerminate+0x63 [C:\__w\1\s\external\pkg\src\WindowsPackageManager\main.cpp @ 113] 
06 00b3f5c0 672d12b7     Microsoft_Management_Deployment_InProc!DllMain+0x29 [C:\__w\1\s\external\pkg\src\Microsoft.Management.Deployment.InProc\dllmain.cpp @ 32] 
07 00b3f600 672d139c     Microsoft_Management_Deployment_InProc!dllmain_dispatch+0x73 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 281] 
08 00b3f614 77168ff6     Microsoft_Management_Deployment_InProc!_DllMainCRTStartup+0x1c [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\dll_dllmain.cpp @ 334] 
09 00b3f634 771a0df3     ntdll!LdrxCallInitRoutine+0x16
0a 00b3f658 7712b11c     ntdll!LdrpCallInitRoutineInternal+0x22
0b 00b3f6a0 77127259     ntdll!LdrpCallInitRoutine+0xae
0c 00b3f740 771240fc     ntdll!LdrShutdownProcess+0x199
0d 00b3f810 7698b113     ntdll!RtlExitUserProcess+0x17c
WARNING: Stack unwind information not available. Following frames may be wrong.
0e 00b3f824 62caa464     KERNEL32!ExitProcess+0x13
0f 00b3f830 62caa40e     ucrtbased!wassert+0x534
10 00b3f868 62caa6d2     ucrtbased!wassert+0x4de
11 00b3f87c 007aa232     ucrtbased!exit+0x12
12 00b3f8dc 007aa0ad     WinGetBugTest!__scrt_common_main_seh+0x172 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 295] 
13 00b3f8e4 007aa458     WinGetBugTest!__scrt_common_main+0xd [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 331] 
14 00b3f8ec 76975d49     WinGetBugTest!mainCRTStartup+0x8 [D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp @ 17] 
15 00b3f8fc 7715d6db     KERNEL32!BaseThreadInitThunk+0x19
16 00b3f954 7715d661     ntdll!__RtlUserThreadStart+0x2b
17 00b3f964 00000000     ntdll!_RtlUserThreadStart+0x1b

Environment

WinGet 1.12.350 from NuGet

Fulgen301 avatar Nov 12 '25 10:11 Fulgen301

I'm going to be creating test infrastructure so that we get proper coverage on this and mid-process unload.

I suspect that for this issue we need to not attempt the COM teardown (WindowsPackageManagerInProcModuleTerminate) during DllMain exit. Or better detect the current COM state before doing so.

For the other one, I need to rethink the lifetime mechanics, probably through a more direct invocation rather than reusing the registration system.

JohnMcPMS avatar Nov 14 '25 21:11 JohnMcPMS