AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
26.06k stars 2.25k forks source link

Access Violation in Avalonia.Skia.SurfaceRenderTarget.Blit #17456

Open jangernert opened 2 weeks ago

jangernert commented 2 weeks ago

Describe the bug

A few Systems running a 24/7 Kiosk UI crashing randomly with the following Exception:

Application: MetriX2.UI.Kiosk.exe
CoreCLR Version: 8.0.23.53103
.NET Version: 8.0.0
Description: The process was terminated due to an unhandled exception.
Exception Info: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Stack:
   at SkiaSharp.SkiaApi.sk_canvas_flush(IntPtr)
   at SkiaSharp.SkiaApi.sk_canvas_flush(IntPtr)
   at Avalonia.Skia.SurfaceRenderTarget.Blit(Avalonia.Platform.IDrawingContextImpl)
   at Avalonia.Rendering.Composition.Server.ServerCompositionTarget.Render()
   at Avalonia.Rendering.Composition.Server.ServerCompositor.RenderCore()
   at Avalonia.Rendering.Composition.Server.ServerCompositor.RenderReentrancySafe()
   at Avalonia.Rendering.Composition.Server.ServerCompositor.Render()
   at Avalonia.Rendering.RenderLoop.TimerTick(System.TimeSpan)
   at Avalonia.Win32.WinRT.Composition.WinUiCompositorConnection+RunLoopHandler.Invoke(Avalonia.Win32.WinRT.IAsyncAction, Avalonia.Win32.WinRT.AsyncStatus)
   at Avalonia.Win32.WinRT.Impl.__MicroComIAsyncActionCompletedHandlerVTable.Invoke(Void*, Void*, Avalonia.Win32.WinRT.AsyncStatus)
   at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG ByRef)
   at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG ByRef)
   at Avalonia.Win32.WinRT.Composition.WinUiCompositorConnection.RunLoop()
   at Avalonia.Win32.WinRT.Composition.WinUiCompositorConnection+<>c__DisplayClass7_0.<TryCreateAndRegisterCore>b__0()

To Reproduce

I've been looking at crash statistics and trying to reproduce the issue for quite some time. But I have found no clear pattern so far. I haven't even managed to reproduce the crash once on my development machine (which runs Linux).

Some users seem to be affected quite heavily. While others encounter the crash rarely or not at all. All while on very similar hardware.

"Affected heavily" in this case means once or twice a day. So not often enough to do some iterative testing with debug builds.

Expected behavior

Not crashing

Avalonia version

11.1.4

OS

Windows

Additional context

A relevant issue from the SkiaSharp tracker: https://github.com/mono/SkiaSharp/issues/2125

It suggests the crash could be caused by not disposing the SKSurface on time after drawing. The avalonia rendering code with all its abstractions is not straight forward to follow. So I'm not sure if this is actually the issue here.

The issue started to appear after a big refactor and visual redesign of the UI code. So maybe how avalonia is used is part of the equation. But without being able to consistently trigger the crash this also just a guess.

I haven't had the time to update to avalonia 11.2, yet. But once I did and the update is deployed for a while I can provide an update if 11.2 fixed the issue.

kekekeks commented 2 weeks ago

If you suspect that some SKSurface is being finalized, you can try collecting GC and finalization events using dotnet-trace https://github.com/dotnet/diagnostics/blob/main/documentation/dotnet-trace-instructions.md#commonly-used-keywords-for-the-microsoft-windows-dotnetruntime-provider

vadimart92 commented 1 week ago

My guess is that you are using some skia primitives to render UI (like SkPaint or SkShader), and forget to dispose some instances. If there is a lot of code you can collect memory dump during this crash (with procdump for example) and you will probably see one more thread that calls Dispose on this instance (from destructor), so you will be able to inspect this object and guess where it was created.