[BUG] Exit code 139 (segmentation fault) when calling `GRGlInterface.Create` on Ubuntu and Linux Mint
Description
I have a project utilizing GLFW and SkiaSharp that is working great on Windows. In trying to suss out Linux support, I have found that I am unable to create a GRGlInterface on Ubuntu and Linux Mint. Specifically, exit code 139 (segmentation fault) is generated when I call:
// Line 29 in Windowtest/Program.fs
let grGlInterface = GRGlInterface.Create(getProcAddress)
The definition of getProcAddress comes from wrapping GLFW:
// Line 201 in GLFW/Wrappers.fs
let getProcAddress name =
printfn "Name passed into `getProcAddress`: %s" name
glfwGetProcAddress(name)
// Line 38 in GLFW/Context.fs
/// Returns the address of the specified function for the current context.
[<DllImport(glfwDLLPath, CallingConvention = CallingConvention.Cdecl)>]
extern IntPtr glfwGetProcAddress(string procname)
Note: It is possible that this is a dependency issue. But as seen in WindowTest.fsproj, it is unclear how SkiaSharp.NativeAssets.Linux or SkiaSharp.NativeAssets.Linux.NoDependencies should be used. I do note that I on the same Linux Mint machine, I am able to run a Polyglot Notebook with SkiaSharp to draw some pictures with no more than:
#r "nuget: SkiaSharp"
#r "nuget: SkiaSharp.NativeAssets.Linux"
open SkiaSharp
So the issue seems to revolve around GRGlInterface.Create and possibly the interaction with GLFW and/or OpenGL.
There is some additional information on a prior Stack Overflow question I posted: https://stackoverflow.com/questions/74882243/how-do-i-properly-build-a-net-7-application-using-skiasharp-on-linux-getting-a
Code
See the above general description, and see the attached code. To reproduce:
-
Install
libglfw3-
Ensure that the
glfwDLLPathon line 9 inGLFW/Common.fsand the path on line 42 inGLFW/Utilities.fspoint to the correct location oflibglfw.so.3.3. -
On my machine, the path is
@"/usr/lib/x86_64-linux-gnu/libglfw.so.3.3"
-
-
Run
dotnet run --project WindowTestin the directory containing theWindowing.slnsolution.
Expected Behavior
No exit code 139 (segmentation fault). If there is a dependency issue, which there may be, I would expect a DLL not found error or some other error notifying me of the dependency issue.
Actual Behavior
The program crashes and exit code 139 (segmentation fault) is returned.
Basic Information
- Version with issue: SkiaSharp 2.88.3
- Last known good version: unknown
- IDE: Visual Studio Code
- Platform Target Frameworks:
- Linux: Linux Mint 21.1 Vera, Ubuntu on WSL2 with WSLg (can follow up with version if needed)
- macOS: Untested as of now
- Windows Classic: Windows 11 works as expected
- Target Devices: desktop PCs
Detailed IDE/OS information (click to expand)
PASTE ANY DETAILED VERSION INFO HERE
Screenshots
Sample run of the program. I am printing out the string passed to getProcAddress.
$ dotnet run --project WindowTest
Initialized?: true
Starting to create window...
Window: 94505711911120n
Ending creating window...
Name passed into `getProcAddress`: test
Name passed into `getProcAddress`: glGetString
Name passed into `getProcAddress`: glGetString
Name passed into `getProcAddress`: glGetStringi
Name passed into `getProcAddress`: glGetIntegerv
Name passed into `getProcAddress`: eglQueryString
Name passed into `getProcAddress`: eglGetCurrentDisplay
$ echo $?
139
Reproduction Link
Please see the attached zip file for a self-contained reproduction. The only external dependency, aside from SkiaSharp is GLFW, but see above for instructions. This code is unlicensed at the moment, so please only use for debugging purposes.
I experienced this as well in Linux on WSL2. I figured out that the crash occurs in GrGLExtensions::init. eglDisplay seems to be a garbage value (0xfffffffffffffec0) and queryString(eglDisplay, GR_EGL_EXTENSIONS) seems to return that same garbage value, leading to a segfault when attempting to call eat_space_sep_strings on it.
I was able to fix this locally by intercepting calls to eglQueryString and, on GR_EGL_EXTENSIONS, returning an empty string, which led to a successful run of my barebones sample application.
I'm not sure what the correct solution is here unfortunately but hopefully this helps point folks in the right direction. I guess you could validate eglDisplay (what is this 0xfffffffffffffec0 value? Some sort of error constant that can be checked?) and not queryString if it's invalid.
I found https://github.com/rust-skia/rust-skia/issues/511 which pointed to https://github.com/flutter/engine/pull/16924.
An F# equivalent of glfwWindowHint(GLFW_CONTEXT_CREATION_API, GLFW_EGL_CONTEXT_API) when the OS is Linux should resolve this issue :)
Thus I don't believe this is a mono/skia or SkiaSharp bug but rather a rough edge that documentation should pave over.
Hope this helps!