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.52k stars 540 forks source link

Attempted to read or write protected memory. This is often an indication that other memory is corrupt #3018

Closed Joost-Jens-Luminis closed 1 month ago

Joost-Jens-Luminis commented 1 month ago

Description

Some of our users are running into the following error: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. We have unfortunately been unable to reproduce it on our systems.

The stacktrace from the even log brings us to the following line of code causing the issue:

   at SkiaSharp.SkiaApi.sk_canvas_draw_path(IntPtr, IntPtr, IntPtr)
   at SkiaSharp.SkiaApi.sk_canvas_draw_path(IntPtr, IntPtr, IntPtr)

The following snippet is the method in which the DrawCanvas method is called. We are certain this is done on the main thread and we don't have a threading issue here:

Code

        canvas.Save();
        var path = new SKPath();

        // clipping so lines are not drawn outside the graph area, but adding 1 px bottom to show lines that are at exactly min scale.
        path.AddRect(new SKRectI(this._snapshotXGraphLeft, this._snapshotYGraphTop, this._snapshotXGraphRight, (int)(this._snapshotYGraphBottom + this.ScaleUp(1))));
        canvas.ClipPath(path);

        foreach (ChartSignal signal in this.Signals)
        {
            if (!signal.IsEnabled)
            {
                continue;
            }

            foreach (List<LinePoint>? line in signal.GetLines(this.ChartRange.ChartMin, this.ChartRange.ChartMax))
            {
                SKColor.TryParse(signal.Color?.Value, out SKColor color);

                this._linePaint.Color = color;

                var linePath = new SKPath();
                linePath.MoveTo(this.CreateSKPoint(line[0]));
                for (var i = 1; i < line.Count; i++)
                {
                    linePath.LineTo(this.CreateSKPoint(line[i]));
                }

                canvas.DrawPath(linePath, this._linePaint);
            }
        }

        canvas.Restore();

Expected Behavior

No response

Actual Behavior

No response

Version of SkiaSharp

2.88.3 (Current)

Last Known Good Version of SkiaSharp

2.88.2 (Previous)

IDE / Editor

Visual Studio (Windows)

Platform / Operating System

Windows

Platform / Operating System Version

It's a WinUI 3 application running on Windows 10 Pro 22H2 (OS Build: 19045.4651). We are also using version 2.88.8 of the Skiasharp.Views.Winui.

Devices

No response

Relevant Screenshots

No response

Relevant Log Output

Application: Bronkhorst FlowSuite 2.exe CoreCLR Version: 8.0.824.36612 .NET Version: 8.0.8 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_draw_path(IntPtr, IntPtr, IntPtr) at SkiaSharp.SkiaApi.sk_canvas_draw_path(IntPtr, IntPtr, IntPtr) at Bronkhorst.FlowControl.Windows.Views.Controls.ChartControl.DrawSignalLines(SkiaSharp.SKCanvas) at Bronkhorst.FlowControl.Windows.Views.Controls.ChartControl.OnPaintSurface(System.Object, SkiaSharp.Views.Windows.SKPaintSurfaceEventArgs) at SkiaSharp.Views.Windows.SKXamlCanvas.DoInvalidate() at ABI.Microsoft.UI.Dispatching.DispatcherQueueHandler.Do_Abi_Invoke(IntPtr) at ABI.Microsoft.UI.Xaml.IApplicationStaticsMethods.Start(WinRT.IObjectReference, Microsoft.UI.Xaml.ApplicationInitializationCallback) at Bronkhorst.FlowControl.Windows.Program.Main(System.String[])

Code of Conduct

ojb500 commented 1 month ago

Is something else interfering with this._linePaint (maybe disposing of it)?

Joost-Jens-Luminis commented 1 month ago

this._linePaint is a property that is created on startup of the class and never disposed of during the runtime of the class. There is also only one draw action running at the same time ever, so nothing is changed on linePaint while canvas.DrawPath is doing it's thing..

Joost-Jens-Luminis commented 1 month ago

It turns out it was a driver issue. The client had out-of-date drivers.