mono / SkiaSharp

SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on Google's Skia Graphics Library. It provides a comprehensive 2D API that can be used across mobile, server and desktop models to render images.
MIT License
4.14k stars 522 forks source link

[BUG] Porting from 2.88.6 to 3.0.0-preview2.1 - "Access Violation on Finalizer/Dispose"- SKPaint object #2794

Open najak3d opened 2 months ago

najak3d commented 2 months ago

Description

Thank you for SkiaSharp! We love love love it.

Tonight I started our efforts to port our application from using SkiaSharp 2.88.6 (which is working like a champ, making full use of custom shaders on GLSurfaces), to the latest 3.0.0-preview2.1.

We had to change over about a dozen API's to the new API's -- very smooth, no issue.

But now when we run our previously very-stable application (in production), it now (with SkiaSharp v3.0) instantly crashes with an "Access Violation" error where the stack trace shows a Native SKObject Dispose() method being called by it's finalizer.

Here's what I see in Visual Studio 2022:

image

The object type Disposed is of type "SKPaint".

Code

Because I don't know which SKObject is being Finalized, I don't know which code triggers it. But somewhere, I've got an SKPaint object that is being disposed via the Finalizer, which is supposed to be fine (right?).

Expected Behavior

I'm expecting SkiaSharp Object Finalizers to NOT cause Access Violation exceptions, but instead to operated normally.

Actual Behavior

Finalizer calls Dispose() which throws a fatal "Access Violoation" exception, and our app crashes.

Version of SkiaSharp

3.x (Alpha)

Last Known Good Version of SkiaSharp

2.88.2 (Previous)

IDE / Editor

Visual Studio (Windows)

Platform / Operating System

Windows

Platform / Operating System Version

Windows 11 Home

Devices

CyberPowerPC with intel i9-14900K, running Windows 11 Home

Relevant Screenshots

image

Relevant Log Output

No response

Code of Conduct

najak3d commented 2 months ago

NOTE: ONCE, as I re-ran this many times, it crashed on the GLControl Paint event thread, while running this line of code:

int charsMeasured = (int)Paint.BreakText(textSpan.Span, maxWidth, out float measuredWidth);

Same error, "Access Violation Exception".

najak3d commented 2 months ago

And so, I wrote specialized Property Getter/Setter for my "Font" class which ensures that no SKPaint objects ever get Finalized (which is something I'm hoping to avoid worrying about).

And so now the "Access Violation" now only happens on my call to "Paint.BreakText(...)":

int charsMeasured = (int)Paint.BreakText(textSpan.Span, maxWidth, out float measuredWidth);

So I set a watch on 'Paint' property, and the watch gets 3 "AccessVioloationExceptions" inside of it, as shown here:

image

najak3d commented 2 months ago

NOTE - if I set a BreakPoint, to change the "timing" - the line of code that throws this Access Violation exception can be changed, such as this last time it crashed on this line of code:

    canvas.DrawText(txtLine, lineX, drawY + 0.4f, OutlinePaint);

(where OutlinePaint itself is throwing AccessViolations on some properties).

NOTE - that it successfully uses these Paint objects many many times just fine (and rapidly) - and then it randomly breaks (as though something were disposed by a finalizer, is what it could be).

AmitParmar2005 commented 1 month ago

Hi,

Could you please tell me how did you make code working? Did you just install SkiaSharp 3.0.0-preview2.1 nuget package? I have installed it but I get Access Violation exception. Did you also build and install latest Angle library?

If possible, could you please list down the steps you followed for code migration?

Thanks in advance, Amit

najak3d commented 1 month ago

I just changed my NUGET references to the various SkiaSharp libraries over to the preview 3.0, for 3 packages as shown here:

image

And then it compiled great (after a few code fixes)... but crashes on the 'Finalizers' it seems.

I do NOT have (nor ever had) Angle nuget referenced by my project. But I do have OpenTK 3.3.3 packages as follows:

image

Other than those, I have System.XXXX libraries, and Xamarain.Essentials 1.8, and NetonSoft.Json 13.0.3 and EntityFramework 6.4.4.

That's it.. So the ONLY change I made in migration to NUGET was those THREE SkiaSharp packages shown above.

AmitParmar2005 commented 1 month ago

Thanks for quick reply.

I think, I misunderstood. Is your application developed in WPF?

My application is in WinUI 3.

najak3d commented 1 month ago

It runs on WPF for Windows, but Xamarin Forms for Android/iOS. Windows/WPF is the easiest place to get things working, so am starting here. Then will move on to Android/iOS w/Xamarin.Forms.