SkiaSharp icon indicating copy to clipboard operation
SkiaSharp copied to clipboard

[BUG] NullReferenceException: Object reference not set to an instance of an object in SKGLTextureViewRenderer.OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl)

Open thisisthekap opened this issue 3 years ago • 13 comments

Description

Heavily reported by our production monitoring, not able to reproduce locally.

System.NullReferenceException: Object reference not set to an instance of an object
  at SkiaSharp.Views.Android.SKGLTextureViewRenderer.OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl) [0x0008a] in <2240341f42164adf9675613a7d38e6a2>:0
  at SkiaSharp.Views.Android.GLTextureView+GLThread.GuardedRun () [0x003bd] in <2240341f42164adf9675613a7d38e6a2>:0
  at SkiaSharp.Views.Android.GLTextureView+GLThread.Run () [0x00028] in <2240341f42164adf9675613a7d38e6a2>:0
  at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00014] in <49badae49cda4201a817f1b87a55a469>:0
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <49badae49cda4201a817f1b87a55a469>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <49badae49cda4201a817f1b87a55a469>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x0002b] in <49badae49cda4201a817f1b87a55a469>:0
  at System.Threading.ThreadHelper.ThreadStart () [0x00008] in <49badae49cda4201a817f1b87a55a469>:0

Code

Using SKGLView as a drawing canvas.

Basic Information

  • Version with issue: 2.80.2
  • Last known good version: none
  • IDE: CI
  • Platform Target Frameworks:
    • Android: v11.0
    • iOS:
    • Linux:
    • macOS:
    • Tizen:
    • tvOS:
    • UWP:
    • watchOS:
    • Windows Classic:
  • Target Devices:
    • Y7 Prime 2019 Android 8.1.0
    • HUAWEI Y7s Android 8.1.0
    • 荣耀畅玩8C Android 8.1.0
Detailed IDE/OS information (click to expand)

PASTE ANY DETAILED VERSION INFO HERE

thisisthekap avatar Jun 22 '21 06:06 thisisthekap

I think it may be related to the drawing happening but for some reason the surface is not there.

This could be if the view is rendering, but then is removed from the hierarchy or disposed mid-render. As a result, we have a context, but the context does not have any surface. In the end, the null surface is trying to create a canvas, which blows up.

Maybe see if there is a way to cancel rendering when the view is no longer used? Not sure exactly your app flow, but see if it helps is there is some way to disconnect the render and/or set the render mode to not looping.

That is the only reason I can see that it was told there is a surface, but it was gone by the time skia wanted to start working.

mattleibow avatar Jul 09 '21 01:07 mattleibow

@mattleibow Thanks for the suggestions, I will definitely give them a try.

What exactly do you mean by "disconnect the render loop"?

thisisthekap avatar Jul 09 '21 07:07 thisisthekap

@mattleibow Could you please clarify?

thisisthekap avatar Aug 12 '21 10:08 thisisthekap

Hi, sorry. I see I typed the reply on my phone, but it never actually went through.

I meant you can try do a HasRenderLoop=false when the page is disappearing. This should shut down the render loop thread. If that resolves it, then I can investigate some more. The issue could be that the frame draw has started but actually is killed mid-way through.

If this fixes it then I can see if I can add more guards.

mattleibow avatar Aug 12 '21 10:08 mattleibow

@mattleibow we have the same problem. In the last 30 days it caused about 1k crashes for 300 different users. It is also the most common reason for crashes on Android for us.

Most effected devices: Y7 Prime 2019 HUAWEI Y7s Honor 8X Max

Setting HasRenderLoop=false on disappearing/sleep did not change anything. Unfortunately, we can't reproduce the problem ourselves, so I don't know if abandoning HasRenderLoop would fix it.

Xamarin Exception Stack:
System.NullReferenceException: Object reference not set to an instance of an object
  at SkiaSharp.Views.Android.SKGLTextureViewRenderer.OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl) [0x0008a] in <2240341f42164adf9675613a7d38e6a2>:0
  at SkiaSharp.Views.Android.GLTextureView+GLThread.GuardedRun () [0x003bd] in <2240341f42164adf9675613a7d38e6a2>:0
  at SkiaSharp.Views.Android.GLTextureView+GLThread.Run () [0x00028] in <2240341f42164adf9675613a7d38e6a2>:0
  at System.Threading.ThreadHelper.ThreadStart_Context (System.Object state) [0x00014] in <90373b3274ec474892629de4358854a7>:0
  at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00071] in <90373b3274ec474892629de4358854a7>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <90373b3274ec474892629de4358854a7>:0
  at System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state) [0x0002b] in <90373b3274ec474892629de4358854a7>:0
  at System.Threading.ThreadHelper.ThreadStart () [0x00008] in <90373b3274ec474892629de4358854a7>:0

Huaba93 avatar Oct 15 '21 05:10 Huaba93

@mattleibow SKSurface.Create can return null on purpose.

Returns the new surface if it could be created and the configuration is supported, otherwise null.

Src: https://docs.microsoft.com/en-us/dotnet/api/skiasharp.sksurface.create?view=skiasharp-2.80.2#SkiaSharp_SKSurface_Create_SkiaSharp_GRContext_System_Boolean_SkiaSharp_SKImageInfo_System_Int32_

So this part could be causing the crash:

https://github.com/mono/SkiaSharp/blob/95c296bd9e8301205c7136de5670681fd1f24396/source/SkiaSharp.Views/SkiaSharp.Views.Android/SKGLTextureViewRenderer.cs#L88-L89

Huaba93 avatar Oct 18 '21 06:10 Huaba93

HasRenderLoop=false did not solve our issue as well. @mattleibow what do you think about the suggestion of @Huaba93 to add a null check?

thisisthekap avatar Nov 11 '21 07:11 thisisthekap

@mattleibow Would the null check for the result of SKSurface.Create be a viable option (as suggested by https://github.com/mono/SkiaSharp/issues/1723#issuecomment-945391399)?

thisisthekap avatar Jan 14 '22 07:01 thisisthekap

@mattleibow I tried to build skiasharp myself. Without success. When executing the target externals-download, keep getting a "method not found" error:

========================================
externals-download
========================================
Downloading '_nativeassets' version '0.0.0-branch.main.179'...
An error occurred when executing task 'externals-download'.
Error: One or more errors occurred. (Method not found: 'System.Threading.Tasks.Task`1<System.Collections.Generic.IEnumerable`1<System.String>> NuGet.Packaging.PackageReaderBase.CopyFilesAsync(System.String, System.Collections.Generic.IEnumerable`1<System.String>, NuGet.Packaging.Core.ExtractPackageFileDelegate, NuGet.Common.ILogger, System.Threading.CancellationToken)'.)
        Method not found: 'System.Threading.Tasks.Task`1<System.Collections.Generic.IEnumerable`1<System.String>> NuGet.Packaging.PackageReaderBase.CopyFilesAsync(System.String, System.Collections.Generic.IEnumerable`1<System.String>, NuGet.Packaging.Core.ExtractPackageFileDelegate, NuGet.Common.ILogger, System.Threading.CancellationToken)'.

thisisthekap avatar Jan 14 '22 07:01 thisisthekap

@mattleibow This issue keeps to be the top reason for crashes for all of our android apps. As I am unfortunately not able to do a custom build myself, your help is very much appreciated. I would be happy to do a PR as well, but without the ability to build the repository on my side, I do not want to propose a code change.

thisisthekap avatar Jan 31 '22 12:01 thisisthekap

I'm now seeing crashes with the same stack trace - exclusively on Y7 Prime 2019

Crashes all happen after "2seconds" (according to appcenter).

SKGLTextureViewRenderer.OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl)
GLTextureView+GLThread.GuardedRun ()
GLTextureView+GLThread.Run ()
ThreadHelper.ThreadStart_Context (System.Object state)
ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx)
ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx)
ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state)
ThreadHelper.ThreadStart ()

This code is running on Xamarin.Android (no Xamarin.Forms involved) - as far as I can tell, the Renderloop is a Xamarin Forms feature. I've tried to find a device farm with any of the mentioned devices, but no luck.

I've looked through my event logs, and I do see logs from Huawei devices, just none with a device type containing Y7. I'm thinking I'll exclude that device from being supported from the Play Store.

@mattleibow - what's the next step in the investigation here?

wouterst79 avatar May 12 '22 23:05 wouterst79

I have another set of these (also on Y7 Prime 2019), but now they appear sometimes after 5 seconds, and sometimes after 8.

SKGLTextureViewRenderer.OnDrawFrame (Javax.Microedition.Khronos.Opengles.IGL10 gl)
GLTextureView+GLThread.GuardedRun ()
GLTextureView+GLThread.Run ()
ThreadHelper.ThreadStart_Context (System.Object state)
ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx)
ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx)
ExecutionContext.Run (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state)
ThreadHelper.ThreadStart ()

wouterst79 avatar Jun 02 '22 20:06 wouterst79

Did anyone find any way to fix this? I've a tried a lot on mine Xamarin Forms, but looking at the stack trace it does not look like the issue is with my code, as the crash happens even before the OnPaintSurface method is called?

Picao84 avatar Oct 06 '23 10:10 Picao84