microsoft / microsoft-ui-xaml

WinUI: a modern UI framework with a rich set of controls and styles to build dynamic and high-performing Windows applications.
MIT License
6.38k stars 683 forks source link

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'ObjectReference'. #9963

Open jamers99 opened 2 months ago

jamers99 commented 2 months ago

Describe the bug

We're getting verified crashes from our logging system Sentry, but we're unable to replicate the issue. The app just dies, and we get a report with an exception message like this:

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'ObjectReference'.
  ?, in void IObjectReference.ThrowIfDisposed()
  ?, in T IObjectReference.AsType<T>()
  ?, in int ExceptionHelpers.GetHRForException(Exception ex)
  ?, in int EventHandler<T>.Do_Abi_Invoke<TAbi>(Void* thisPtr, IntPtr sender, TAbi args)

This happens pretty frequently, probably 1-2 times per user hour. We have "breadcrumbs" of what happened in the UI, but so far, that hasn't really shown us any correlation of specific steps to take to replicate the problem.

Steps to reproduce the bug

See description, no indications of how to reproduce the problem.

Expected behavior

A better exception. Details about what triggered this via a helpful stack trace. We have no idea what caused this crash and it's not anywhere in our code. We only need to know what's wrong so we can fix/avoid whatever we're doing now.

Screenshots

None, it's happening to production users that haven't been able to capture the problem with screen recording (yet)

NuGet package version

We're on 1.6.240923002

Windows version

Windows 11 (22631)

kmgallahan commented 2 months ago

If I recall correctly, this started popping up a few minor releases ago due to using LINQ's Cast<T> or OfType<T> on a generic collection of objects.

I can't remember my exact exception message though, yours just looks familiar.

jamers99 commented 1 month ago

We found the problem. It's an exception in the exception handling; while handling the original exception another exception is thrown. We finally had a scenario to reproduce it, although we won't be able to share the repro project (it also requires very specific setup). The original exception is a LayoutCycleException that we're now looking into fixing.

The issue is a bug in https://github.com/microsoft/CsWinRT and we've made a very hacky and risky workaround in order to get the original exception: Image

Essentially, in WinRT.Runtime's ExceptionHelper.cs line 364 an object is read from the Exception.Data collection and is used in a using, which disposes it. The same object is read again later and since it was disposed, it throws the ObjectDisposedException.

I believe the using statement in ExceptionHelper.cs at line 364 should be removed. While I don't know why it would be needed, it definitely should not be disposing this object, as it doesn't own it, and something may later read it (as proved by this bug).

It also may be wise to look into preventing the exception handling from throwing another exception.

jamers99 commented 4 weeks ago

@codendone how do we update CsWinRT (WinRT.Runtime.dll) once this gets fixed in the CsWinRT repo? Do we need to wait on a WinAppSDK nuget update? Or can we manually specify a version of CsWinRT?

manodasanW commented 4 weeks ago

Given the fix is in WinRT.Runtime, you can get the fix by referencing an updated CsWinRT package or the updated Windows SDK projection package (via WindowsSdkPackageVersion property until the .NET SDK is updated to reference the new version).