libhybris: eglplatform_wayland.so unresolved symbol issue
The problem
Attempt to start plasma mobile session using kwin_hwcomposer backend results in kwin_wayland running, but plasmashell not present, and logs:
klte:~$ cat /tmp/plasmashell_logs
Error: could not determine $DISPLAY.
org.kde.kwindowsystem: Loaded plugin "/usr/lib/qt5/plugins/kf5/org.kde.kwindowsystem.platforms/KF5WindowSystemKWaylandPlugin.so" for platform "wayland"
Using Wayland-EGL
ERROR: /usr/lib/libhybris/eglplatform_wayland.so
Error relocating /usr/lib/libhybris/eglplatform_wayland.so: hybris_egl_display_get_mapping: symbol not found
Assertion failed: 0 (ws.c: _init_ws: 49)
KCrash: Attempting to start /usr/bin/plasmashell from kdeinit
Warning: connect() failed: : Connection refused
KCrash: Attempting to start /usr/bin/plasmashell directly
KCrash: Application 'plasmashell' crashing...
org.kde.kwindowsystem: Loaded plugin "/usr/lib/qt5/plugins/kf5/org.kde.kwindowsystem.platforms/KF5WindowSystemKWaylandPlugin.so" for platform "wayland"
Using Wayland-EGL
ERROR: /usr/lib/libhybris/eglplatform_wayland.so
Error relocating /usr/lib/libhybris/eglplatform_wayland.so: hybris_egl_display_get_mapping: symbol not found
Assertion failed: 0 (ws.c: _init_ws: 49)
"Famous issue"
Jan 23 17:01:21 <NotKit> Using Wayland-EGL … ERROR: /usr/lib/libhybris/eglplatform_wayland.so …
Error relocating /usr/lib/libhybris/eglplatform_wayland.so: hybris_egl_display_get_mapping: symbol not found
Jan 23 17:01:25 <NotKit> oh, that famous issue
Jan 23 17:01:53 <bhushanshah> huh?
Jan 23 17:02:18 <NotKit> I think that also happened on Arch
Jan 23 17:02:34 <bhushanshah> do you know solution?
Jan 23 17:04:52 <NotKit> I remember that it required linker arguments change during libhybris build
Jan 23 17:05:24 <NotKit> used export LD_PRELOAD=/usr/lib/libEGL.so.1.0.0 as quick hack
Turns out that issue is known. Since 2017!
krnlyng bshah, try adding -lEGL to LDFLAGS of hybris/egl/platforms/wayland/Makefile.am
relevant chat logs link: http://www.merproject.org/logs/%23sailfishos-porters/%23sailfishos-porters.2017-10-01.log.html
Workaround:
Edit plaMo startup script /usr/bin/plasma-phone
like that, by adding a line with LD_PRELOAD
definition before the line that starts plsamashell:
...
export LD_PRELOAD=/usr/lib/libhybris-egl/libEGL.so.1.0.0
exec /usr/bin/plasmashell -p org.kde.plasma.phone 2>/tmp/plasmashell_logs
Explanation
The issue is that hybris's eglplatform_wayland.so
plugin is using a function hybris_egl_display_get_mapping()
that is implemented inside a hybris's own libEGL.so
(probably some kind of private hybris API). And eglplatform_wayland.so
is not linked to libEGL.so
, because, I assume: in libhybris's buildsystem plugins are built first, then libEGL.so is built after plugins. (libhybris provides its own libEGL to be used instead of mesa's).
No platform plugin in libhybris tree has -lEGL
link flag and the package itself of course cannot depend on mesa (as provider of libEGL). Probably platform plugin shouldn't link to libEGL at all (because it loads android libs at runtime) and this is some bug in libhybris, or misconfiguration/misplacement of hybris_egl_display_get_mapping()
function. Hard to tell.
The reason this bug is unknown for other distros is probably because something else loads libEGL (provided by libhybris) in process before eglplatform_wayland is loaded, as proved by LD_PRELOAD hack working.
Links
- function definition is here: https://github.com/libhybris/libhybris/blob/master/hybris/egl/egl.c#L171
- usage is here: https://github.com/libhybris/libhybris/blob/master/hybris/egl/platforms/wayland/eglplatform_wayland.cpp#L214
Possible solutions:
-
LD_PRELOAD
hack mentioned above is only good as temporary solution, or to prove the issue -
We can force
eglplatform_wayland
to link tolibEGL
, by just adding-lEGL
to linker flags. But because libEGL does not exist at the time ofeglplatform_wayland
linking we would have to addmesa-dev
to deps to have libEGL available and avoid linking error. Another problem is that--as-needed
is passed to linker flags, and libraries are linked only if they are really used. So we have to actually use some public libEGL API. I tried this option in https://gitlab.com/minlexx/pmaports/commit/26c5346bcf45fb51368a343b222d0ff6c65b1247 (I usedeglQueryString()
as harmless call) but decided that this it too much hacks already and wrong overall. -
Apparently platform plugin is not supposed to link to to libEGL. So, the correct approach would be to just load libEGL at runtime using
dlopen()
and resolvehybris_egl_display_get_mapping()
withdlsym()
.
I'm going to fix that.