-
Notifications
You must be signed in to change notification settings - Fork 550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] System.AccessViolationException
thrown when flushing canvas or swapping buffers
#2125
Comments
System.AccessViolationException
thrown when flushing canvas or swapping buffers
Another error reported to the console is:
This is using some higher-level wrappers, but it is basically doing the same thing as the above code snippet. It shows that in this case, the error occurs at |
I have tried debugging this a million ways, and I have not been able to solve this or workaround the issue. There are several seemingly related issues in this repository that mention the If I do not recreate the Attached is a very simple reproduction of this unexpected exception using only Silk.NET.GLFW, which is just using Silk.NET's GLFW binding and not their windowing abstraction, and SkiaSharp. The project was done in Visual Studio Community 2022 with the latest versions and only requires the NuGet dependencies. The crash can take a few minutes, but it happens every time. It seems to happen much faster in other slightly more complicated scenarios, but the error is the same |
I'm no F# expert, but should some of those "let" statements be "use"? |
I was playing around with As far as my understanding goes, using |
Pretty sure this is just a bug in the example, though arguably it should be possible to notice some error and throw an exception earlier. The dispose pattern deals with resources - that may or may not be memory. It works for me if the unmanaged resources are properly disposed (i.e. GRBackendRenderTarget and SKSurface). |
Thanks for mentioning At first I was confused, but the issue is because Using I'll leave this issue open for now, as I think the "bug" is now at least a documentation issue. Since |
Again, I'm no F# expert, but I read that warning as the "new" operator should be used when directly invoking a constructor, not that the named constructor idiom should be avoided. It's fairly common to use that pattern any time additional context is needed to distinguish constructors that otherwise would have the same signatures. Probably here to distinguish between creating a new backend render target vs. wrapping an existing one. Edit: looks like most of the other named constructors are obsolete, so maybe regular constructors could be added. Trouble is, the existing ones would still be needed for compatibility. |
Yes, I know. I didn't say named constructors should be avoided. In F#, the https://fsharpforfunandprofit.com/posts/classes/#constructing-and-using-a-class My point was that |
A named constructor is a public static method used to instantiate an object... i.e. SKSurface.Create is a named constructor. Upstream Skia surfaces themselves use named constructors too. I don't think it's wrong to use them where it's appropriate, and I don't necessarily think that F# rule implies that there's any issue here either. As an aside, you might not even always care about disposing types that implement IDisposable (e.g. Tasks). Though probably most of the time you will want to explicitly dispose, it's up to the caller to be aware and make an appropriate judgement. Looks like the error handling pattern here is that the named constructor returns null if the allocation failed (a regular constructor would only be able to throw an exception for errors), but it looks to me like the binding at least already does the right thing: |
Apologies for equating named constructors with object constructors. I wasn't aware that "named constructors" were a specific thing. In my opinion, it's a poor name to mean something different than constructing an object by name. 🙃 I don't really know C#, only enough to use .NET libraries from F#, and defining constructors in F# is handled a bit differently. @mattleibow Can you please confirm the correct way to handle |
generally a surface should be created, and then disposed when done using it i dont know F# so this is C# SKSurface surface;
if (width == 0 || height == 0 || graphicsContext == null)
{
return null;
}
SKSurface s = SKSurface.Create(graphicsContext, false, new SKImageInfo(width, height));
if (s == null)
{
return null;
}
// draw with s.Canvas
s.Dispose(); // s.Canvas is disposed with surface |
Conclusion: Surface must be disposed of. |
keep in mind anything that automatically disposes the surface will also work, for example, a so long as the surface is disposed at the appropriate time |
Description
I am using GLFW for creating a window and SkiaSharp to draw to that window's OpenGL context. SkiaSharp suddenly throws
System.AccessViolationException
exceptions, often without an indication of where it occurred, but it seems to occur either atSKCanvas.flush()
or when instructing GLFW to swap buffers.The exception is thrown every run, but it is indeterminate how long it takes for the exception to be thrown.
The exception message in the Visual Studio "Exception Unhandled" window that pops up:
Details after selecting "Copy Details" in this window:
Error message printed to console:
Code
I have written my own GLFW bindings in F#, which are used below, but the wrappers below are almost one-to-one with the GLFW functions invoked.
Expected Behavior
No exception.
Actual Behavior
A
System.AccessViolationException
exception is thrown, often with no stack trace.Basic Information
Screenshots
This is a screenshot of the window and image that's being drawn:
Reproduction Link
Unavailable at the moment since the code is in a private repository.A reproduction is linked here.The text was updated successfully, but these errors were encountered: