Skip to content

Access Violation caused by static cache destructor accessing weak references after their module has been unloaded due to COM having been uninitialized #5363

@Fulgen301

Description

@Fulgen301

Brief description of your issue

When connecting to a composite catalog consisting of a package catalog reference and CompositeSearchBehavior::RemotePackagesFromAllCatalogs, GetCachedInstalledIndex() is eventually called as the source is opened, leading to a CachedInstalledIndex static object being created. However, CachedInstalledIndex contains an event revoker, which contains a weak reference to a Windows::ApplicationModel::PackageCatalog object, which does not live in WindowsPackageManager.dll, but Windows.ApplicationModel.dll, a system DLL.

If the application calls CoUninitialize for the last time, COM unloads Windows.ApplicationModel.dll, leaving the weak reference pointing to a destroyed object in an unloaded DLL. The static variable eventually gets destroyed on process exit, causing the event revoker to attempt to resolve the weak reference, causing an access violation.

(Essentially, this is what Raymond Chen warned against - the object the weak reference refers to is not implemented n the same DLL as the weak reference.)

Steps to reproduce

  1. Create a PackageManager object.
  2. Create a composite package catalog with a package catalog reference and CompositeSearchBehavior::RemotePackagesFromAllCatalogs.
  3. Connect to the catalog. The static variable has now been initialized.
  4. Call CoUninitialize. Windows.ApplicationModel.dll will be unloaded, which can be verified by sxe ud:Windows_ApplicationModel in WinDbg.
  5. Exit the process. An access violation will occur in winrt::weak_ref<winrt::Windows::ApplicationModel::IPackageCatalog::get:

ZIP file containing a reproducer

Expected behavior

The application will cleanly shut down with no access violation.

Actual behavior

An access violation occurs on process exit:

00 WindowsPackageManager!winrt::weak_ref<winrt::Windows::ApplicationModel::IPackageCatalog>::get
01 WindowsPackageManager!winrt::impl::event_revoker<winrt::Windows::ApplicationModel::IPackageCatalog,&winrt::impl::abi<winrt::Windows::ApplicationModel::IPackageCatalog,void>::type::`vcall'{60}'>::{dtor}
02 WindowsPackageManager!`AppInstaller::Repository::Microsoft::`anonymous namespace'::PredefinedInstalledSourceReference::GetCachedInstalledIndex'::`2'::`dynamic atexit destructor for 's_installedIndex''
03 ucrtbase!<lambda_f03950bc5685219e0bcd2087efbe011e>::operator()
04 ucrtbase!__crt_seh_guarded_call<int>::operator()<<lambda_69a2805e680e0e292e8ba93315fe43a8>,<lambda_f03950bc5685219e0bcd2087efbe011e> &,<lambda_03fcd07e894ec930e3f35da366ca99d6> >
05 ucrtbase!_execute_onexit_table
06 WindowsPackageManager!__scrt_dllmain_uninitialize_c
07 WindowsPackageManager!dllmain_crt_process_detach
08 WindowsPackageManager!dllmain_crt_dispatch
09 WindowsPackageManager!dllmain_dispatch
0a WindowsPackageManager!_DllMainCRTStartup
0b ntdll!LdrxCallInitRoutine
0c ntdll!LdrpCallInitRoutine
0d ntdll!LdrShutdownProcess
0e ntdll!RtlExitUserProcess
0f KERNEL32!ExitProcessImplementation

Environment

Microsoft.WindowsPackageManager.InProcCom.1.10.340 from NuGet

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-COM-APIIssue related to COM APIIssue-BugIt either shouldn't be doing this or needs an investigation.

    Type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions