electron: [Bug]: segfault on startup at gpu_init.cc under native Wayland

Preflight Checklist

Electron Version

16.0.7

What operating system are you using?

Other Linux

Operating System Version

Arch

What arch are you using?

x64

Last Known Working Electron version

15.3.5

Expected Behavior

Electron to start successfully.

Actual Behavior

Electron crashes immediately upon startup. ERROR:gpu_init.cc(457) Passthrough is not supported, GL is egl, ANGLE is zsh: segmentation fault (core dumped) electron

Testcase Gist URL

No response

Additional Information

This is confirmed to be happening on a number of other distros on this Signal issue report. asciinema recording. I will happily provide more information if need be.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 29
  • Comments: 15 (4 by maintainers)

Commits related to this issue

Most upvoted comments

https://gist.github.com/brandonweeks/28f3ef35515e7cdd487a4df98bed5cff

Here is the backtrace from Electron 17.0.0 on NixOS, after resolving the libGLESv2.so.2 issue.

Thanks. The problem is that electron still calls to X11 objects despite them being null.

frame #0: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] base::internal::UncheckedObserverAdapter::IsEqual(this=0x00001cb0002db000, rhs=0x00001cb000e66350) const at observer_list_internal.h:37:53
    frame #1: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] auto base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(o=0x00001cb0002db000) const::'lambda'(auto const&)::operator()<base::internal::UncheckedObserverAdapter>(auto const&) const at observer_list.h:305:23
    frame #2: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] decltype(args=0x00001cb0002db000) base::internal::InvokeImpl<base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&)&, base::internal::UncheckedObserverAdapter const&>(auto&&, base::internal::UncheckedObserverAdapter const&) at invoke.h:132:10
    frame #3: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] decltype(args=0x00001cb0002db000) base::invoke<base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&)&, base::internal::UncheckedObserverAdapter const&>(auto&&, base::internal::UncheckedObserverAdapter const&) at invoke.h:147:10
    frame #4: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] bool auto base::internal::ProjectedUnaryPredicate<base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&), base::identity>(arg=0x00001cb0002db000)::'lambda'(auto&&)::operator()<base::internal::UncheckedObserverAdapter const&>(auto&&) const at algorithm.h:32:12
    frame #5: 0x00005562dcf5e552 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] auto std::__1::find_if<std::__1::__wrap_iter<base::internal::UncheckedObserverAdapter const*>, auto base::internal::ProjectedUnaryPredicate<base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&), base::identity>(auto&, base::identity&)::'lambda'(auto&&)>(__first=<unavailable>, __last=__wrap_iter<const base::internal::UncheckedObserverAdapter *> @ scalar) at algorithm:943:13
    frame #6: 0x00005562dcf5e54d electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] auto base::ranges::find_if<std::__1::__wrap_iter<base::internal::UncheckedObserverAdapter const*>, base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&), base::identity, std::__1::random_access_iterator_tag>(first=<unavailable>, last=__wrap_iter<const base::internal::UncheckedObserverAdapter *> @ scalar, pred=(obs = 0x00001cb000e66350)) const::'lambda'(auto const&), base::identity) at algorithm.h:465:10
    frame #7: 0x00005562dcf5e54d electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] auto base::ranges::find_if<std::__1::vector<base::internal::UncheckedObserverAdapter, std::__1::allocator<base::internal::UncheckedObserverAdapter> > const&, base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(x11::EventObserver const*) const::'lambda'(auto const&), base::identity, std::__1::random_access_iterator_tag>(pred=(obs = 0x00001cb000e66350)) const::'lambda'(auto const&), base::identity) at algorithm.h:483:10
    frame #8: 0x00005562dcf5e53d electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::HasObserver(obs=0x00001cb000e66350) const at observer_list.h:304:12
    frame #9: 0x00005562dcf5e534 electron`x11::Connection::AddEventObserver(x11::EventObserver*) [inlined] base::ObserverList<x11::EventObserver, false, true, base::internal::UncheckedObserverAdapter>::AddObserver(this=<unavailable>, obs=0x00001cb000e66350) at observer_list.h:271:9
    frame #10: 0x00005562dcf5e534 electron`x11::Connection::AddEventObserver(this=0x00001cb0002bd408, observer=0x00001cb000e66350) at connection.cc:486:20
    frame #11: 0x00005562dc78eb3e electron`electron::WindowStateWatcher::WindowStateWatcher(this=0x00001cb000e66350, window=<unavailable>) at window_state_watcher.cc:27:52

See https://github.com/electron/electron/blob/main/shell/browser/native_window_views.cc#L279. <— That’s fundamentally incorrect. Chromium has migrated from non-Ozone builds, which used non-Ozone/X11 by default, to Ozone builds[1], which uses Ozone/X11 by default with Wayland chosen if --ozone-platform flag is passed. Thus, there is no point to pass the --enable-features=UseOzonePlatform flag since M95 [2]. The flag was left until M98[3] just for the gardening purposes and it’s no longer in Chromium. Last, the USE_X11 ifdef and the use_x11 gn arg have also been removed after all the gardening was completed in M98[4][5].

That’s the reason it segfaults.

[1] https://source.chromium.org/chromium/chromium/src/+/cecaf7e62fa3daddc51120e06a52e1777e36f05e [2] https://chromiumdash.appspot.com/commit/cecaf7e62fa3daddc51120e06a52e1777e36f05e [3] https://chromiumdash.appspot.com/commit/5d0f7a98e295248609dc2bad9209d7f387374e03 [4] https://chromiumdash.appspot.com/commit/cd3d129061f1ee453fb06af7b998f948c3582874 [5] https://chromiumdash.appspot.com/commit/6d244dbb18098e85b019248a6d207f5735dd8558

It also seems to be a race condition. If I start slack several times in a row (with ozone on wayland), it will eventually not crash.

I’m seeing the same issue with --enable-features=UseOzonePlatform --ozone-platform=wayland on various Electron versions installed from NPM, including:

  • 17.0.0
  • 19.0.0-nightly.20220204

Output:

[451760:0205/112309.380364:ERROR:cursor_loader.cc(116)] Failed to load a platform cursor of type kNull
[451795:0100/000000.421096:ERROR:gpu_init.cc(454)] Passthrough is not supported, GL is egl, ANGLE is 
/home/neoraider/.config/yarn/global/node_modules/electron-nightly/dist/electron exited with signal SIGSEGV
[451795:0100/000000.900648:ERROR:sandbox_linux.cc(377)] InitializeSandbox() called with multiple threads in process gpu-process.

All older versions up to 16.0.8 instead run into #32487, so they fail to start before this crash… Arch Linux backported the patches proposed in that PR, so they already get the new crash behavior of Electron 17+ with Electron 16 and the latest Sway.

@msisov oops, sorry I’ve pasted the wrong example, that was indeed an unrelated error (although it shouldn’t cause a segfault either).

It’s probably best to look at the outputs in this thread (there are many): https://github.com/signalapp/Signal-Desktop/issues/5719 E.g. from the original/first post (without the Signal-Desktop output):

[6603:0105/154522.895686:ERROR:gpu_init.cc(457)] Passthrough is not supported, GL is egl, ANGLE is 
[6603:0105/154522.898629:ERROR:sandbox_linux.cc(376)] InitializeSandbox() called with multiple threads in process gpu-process.
[6540:0105/154522.915875:ERROR:cursor_loader.cc(114)] Failed to load a platform cursor of type kNull
Segmentation fault (core dumped)

Here’s the output on my system when libGLESv2.so.2 can be found but https://github.com/electron/electron/pull/32603#issuecomment-1022908675 is likely a better example for that case:

$ result/bin/electron --ozone-platform=wayland

Electron 17.0.0 - Build cross platform desktop apps with JavaScript, HTML, and CSS
Usage: electron [options] [path]

A path to an Electron app may be specified. It must be one of the following:
  - index.js file.
  - Folder containing a package.json file.
  - Folder containing an index.js file.
  - .html/.htm file.
  - http://, https://, or file:// URL.

Options:
  -i, --interactive     Open a REPL to the main process.
  -r, --require         Module to preload (option can be repeated).
  -v, --version         Print the version.
  -a, --abi             Print the Node ABI version.
[3647:0207/202632.954888:ERROR:cursor_loader.cc(116)] Failed to load a platform cursor of type kNull
[3683:0207/202633.017704:ERROR:gpu_init.cc(454)] Passthrough is not supported, GL is egl, ANGLE is
[3683:0207/202633.035746:ERROR:sandbox_linux.cc(377)] InitializeSandbox() called with multiple threads in process gpu-process.
[3647:0207/202633.111607:ERROR:object_proxy.cc(623)] Failed to call method: org.freedesktop.DBus.Properties.Get: object_path= /org/freedesktop/portal/desktop: org.freede
sktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.FileChooser”
[3647:0207/202633.111645:ERROR:select_file_dialog_impl_portal.cc(243)] Failed to read portal version property
Segmentation fault (core dumped)

That D-Bus error should also be unrelated and fixable at the packaging / Linux distribution’s side (or my setup):

[3647:0207/202633.111607:ERROR:object_proxy.cc(623)] Failed to call method: org.freedesktop.DBus.Properties.Get: object_path= /org/freedesktop/portal/desktop: org.freede
sktop.DBus.Error.InvalidArgs: No such interface “org.freedesktop.portal.FileChooser”
[3647:0207/202633.111645:ERROR:select_file_dialog_impl_portal.cc(243)] Failed to read portal version property

But IMO that should normally be optional and it definitely shouldn’t cause a segfault.

Based on this issue and the linked issues, many users on different distributions are affected. However, it also seems to work on some distributions (e.g., Arch Linux, I think - but apparently not for all users).

Anyway, I had no luck to get it to work on my distribution (even when trying to use different GPU related flags, e.g., for SwiftShader). E.g. (not sure which of them are currently supposed to work and which not - they’re changing faster than I can keep up with and may of the old flags result in [13322:0207/211626.899668:ERROR:gl_factory.cc(148)] Requested GL implementation (gl=none,angle=none) not found in allowed implementations: [(gl=egl-gles2,angle=none),(gl =egl-angle,angle=swiftshader),(gl=swiftshader-gl,angle=none)]. - looks like only very few combinations are left):

  • --use-gl=egl (etc.)
  • --use-angle=swiftshader (etc.)
  • --disable-gpu-sandbox
  • --disable-gpu

@msisov does Electron 17.0.0 work on your Linux setup?

It should definitely try to open a system libGLESv2

That’s also good to know. I was actually wondering about that since at least Chromium and Google Chrome seem to ship a libGLESv2.so as well. It is a wrapper from ANGLE, IIRC.

https://gist.github.com/brandonweeks/28f3ef35515e7cdd487a4df98bed5cff

Here is the backtrace from Electron 17.0.0 on NixOS, after resolving the libGLESv2.so.2 issue.

ERROR:gpu_init.cc(457) Passthrough is not supported, GL is egl, ANGLE is

I think this particular error message is a red herring. I always see this error when launching both Chromium and Electron on Wayland even though the apps run just fine afterwards.

FWIW I can also reproduce the startup crash when launching Electron 16 on Wayland but only when using the official electron package from Arch Linux.

When installing the same electron version from npm/yarn (e.g.: yarn global add electron@16.0.7), it no longer crashes at startup and the Electron window is displayed properly.

This seems to suggest it might be an Arch Linux packaging issue that may be caused by some of the distribution specific patches.

However, while looking into this, I did find out that all Electron versions based on Chromium version 98+ (e.g.: electron@17.0.0-alpha.4+) fail to start on Wayland. The last Electron version that I can still run on Wayland seems to be electron@17.0.0-alpha.3 which is based on Chromium 96.

@mitchchn suggested that it might be related to WindowStateWatcher but I haven’t looked into it to see if it’s the same issue.

I suspect @msisov’s a62362f and Electron’s outstanding work to integrate it in #31382 are at least tangentially related to this crash due to the electron::WindowStateWatcher connection.

/cc @deepak1556

Failed to load GLES library: libGLESv2.so.2

Check the strace output when you start electron with Ozone/Wayland. Here is the example of my machine -

chromium.log.7774:openat(AT_FDCWD, "/home/msisov/code/chromium/src/out/debug2/libGLESv2.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
chromium.log.7774:openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libGLESv2.so.2", O_RDONLY|O_CLOEXEC) = 469

It should definitely try to open a system libGLESv2 unless it fails to initialize GL and uses swiftshader/swangle

Here is an example if run Chromium with SwAngle (angle + swiftshader, which is a successor of swiftshader. the legacy swiftshader support has been dropped in the upstream recently).

chromium.log.8186:openat(AT_FDCWD, "/home/msisov/code/chromium/src/out/debug2/libGLESv2.so", O_RDONLY|O_CLOEXEC) = 469
chromium.log.8278:openat(AT_FDCWD, "/home/msisov/code/chromium/src/out/debug2/libGLESv2.so", O_RDONLY|O_CLOEXEC) = 469