SkiaSharp icon indicating copy to clipboard operation
SkiaSharp copied to clipboard

[BUG] Exit code 139 (segmentation fault) when calling `GRGlInterface.Create` on Ubuntu and Linux Mint

Open bmitc opened this issue 3 years ago • 2 comments

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 glfwDLLPath on line 9 in GLFW/Common.fs and the path on line 42 in GLFW/Utilities.fs point to the correct location of libglfw.so.3.3.

    • On my machine, the path is @"/usr/lib/x86_64-linux-gnu/libglfw.so.3.3"

  • Run dotnet run --project WindowTest in the directory containing the Windowing.sln solution.

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.

dotnet-windowing.zip

bmitc avatar Dec 30 '22 00:12 bmitc

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.

SuperAuguste avatar Nov 23 '25 21:11 SuperAuguste

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!

SuperAuguste avatar Nov 24 '25 21:11 SuperAuguste