I'm trying to write a simple bgfx application in C# with .NET Core. It works fine on Windows, but it fails at runtime on Linux with the following error:
/usr/bin/dotnet: symbol lookup error: /home/user/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0/libbgfx-shared-libDebug.so: undefined symbol: XLockDisplay
I'm very ignorant about C++ (especially on Linux) and I already tried all I could think about. I'm looking for hints to fix this problem. Thank you very much for your help.
This is the constructor of the class I use to create a new X11 window. It works and the window is opened correctly.
public GameWindow()
{
// (snip)
XInitThreads();
dpy = XOpenDisplay(IntPtr.Zero);
if (dpy == IntPtr.Zero)
throw new ApplicationException("XOpenDisplay failed");
var s = XDefaultScreen(dpy);
win = XCreateSimpleWindow(dpy, XRootWindow(dpy, s), 10, 10, Width, Height, 1, XBlackPixel(dpy, s), XWhitePixel(dpy, s));
XSelectInput(dpy, win, XEventMask.ExposureMask | XEventMask.KeyPressMask);
XMapWindow(dpy, win);
// (snip)
WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", false);
XSetWMProtocols(dpy, win, new[] { WM_DELETE_WINDOW }, 1);
}
This is where I create the window and assign it to bgfx.
using (var window = new GameWindow())
{
Bgfx.SetWindowHandle(window.Handle);
var inited = Bgfx.Init(); // <- this line causes the crash
// (snip)
}
This is the Bgfx.Init()
function.
public static bool Init (InitSettings settings = null) {
InitSettings.Native native;
NativeMethods.bgfx_init_ctor(&native);
// (snip)
return NativeMethods.bgfx_init(&native); // <- this line causes the crash
}
The included C++ examples run fine, I'm only encountering this problem from C# (though the library is statically linked in the C++ examples; I'm linking dynamically with PInvoke from C#).
I identified the crash to be triggered from glcontext_glx.cpp:66. All the code before this line does indeed run (I checked the tracelogs and they are actually printed until the crash, and I do successfully interact from C# with the library in other ways before that function call is made).
Oddly, the libbgfx-shared-libDebug.so (3.6MB) weighs less than the libbgfx-shared-libRelease.so (5.4MB). The opposite is true for the Windows build by Michael Popoloski (bgfx.dll 728KB and bgfx_debug.dll 3.5MB).
I do XCreateSimpleWindow()
from C# before initializing bgfx, and the window does appear, therefore the X11 library is actually linked correctly.
readelf -d libbgfx-shared-libDebug.so
to see if X11 marked as a static dependency - it is not/proc/1234/maps
that the shared X11 library is loaded - the same library is loaded in my C# test and in the included C++ exampleLD_PRELOAD
and LD_LIBRARY_PATH
- no changeundefined symbol: XLockDisplay
to undefined symbol: glXQueryVersion
, which is called in the next line-lm -lpthread -lX11
flags to the compiler (as suggested by jdweng) - that error line is not printed anymore, but the program still crashes when XLockDisplay
is calledStatic dependencies of libbgfx-shared-libDebug.so:
user@ASUS-MINT ~/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0 $ readelf -d libbgfx-shared-libDebug.so
Dynamic section at offset 0x1571d0 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [librt.so.1]
0x0000000000000001 (NEEDED) Shared library: [libdl.so.2]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]
(snip)
Maps for dotnet while running my code:
user@ASUS-MINT ~ $ cat /proc/32502/maps
00400000-00418000 r-xp 00000000 08:06 185073 /usr/share/dotnet/dotnet
(snip)
7fe844bed000-7fe844d42000 r-xp 00000000 08:06 1616067 /home/user/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0/libbgfx-shared-libDebug.so
7fe844d42000-7fe844f42000 ---p 00155000 08:06 1616067 /home/user/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0/libbgfx-shared-libDebug.so
7fe844f42000-7fe844f45000 r--p 00155000 08:06 1616067 /home/user/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0/libbgfx-shared-libDebug.so
7fe844f45000-7fe844f4d000 rw-p 00158000 08:06 1616067 /home/user/Documents/Projects/GameEngine/GameEngine/bin/Debug/netcoreapp2.0/libbgfx-shared-libDebug.so
(snip)
7fe8455aa000-7fe8456df000 r-xp 00000000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7fe8456df000-7fe8458df000 ---p 00135000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7fe8458df000-7fe8458e0000 r--p 00135000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7fe8458e0000-7fe8458e4000 rw-p 00136000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
(snip)
Maps for the included C++ example (no reference to libbgfx-shared-libDebug.so):
user@ASUS-MINT ~ $ cat /proc/351/maps
00400000-007fe000 r-xp 00000000 08:06 1607279 /home/user/bgfx/bgfx/.build/linux64_gcc/bin/examplesDebug
(snip)
7f6ad126c000-7f6ad13a1000 r-xp 00000000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f6ad13a1000-7f6ad15a1000 ---p 00135000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f6ad15a1000-7f6ad15a2000 r--p 00135000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
7f6ad15a2000-7f6ad15a6000 rw-p 00136000 08:06 2370342 /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0
(snip)
I feel guilty answering my own question without a real solution, but here I go...
I kept investigating how to solve this problem with no avail. After two years of inactivity, I decided to try again.
Since 2018 I have formatted my computer and installed various operating system updates, probably even some X11 updates; I updated all project dependencies, including bgfx, to the latest version; and I upgraded from .NET Core App 2.0 to 3.0.
Maybe there was something wrong with the version of bgfx that I was using? Maybe there was a bug in the dynamic linking in that version of the .NET runtime? Maybe there was a problem with my version of Xlib.so?
I guess I will never really know, but now it works. Magic.