eglSwapBuffers never returns

Viewed 403

I'm developing a simple game on Raspberry Pi 3. As an operating system I use official Raspbian Stretch Lite. The game is run without X server and developed in C++ using SFML PI library.

The problem is that game freezes from time to time. It can happen after a few seconds or a few hours of running the game but sooner or later it always happens. The stacktrace of freeze indicates that eglSwapBuffers never returns. What's more killing the game and running it again doesn't help - it freezes during startup on eglCreatePbufferSurface call. It starts again after reboot. What can be the reason of such freeze? Can I debug it somehow? I'm quite afraid that it may be caused by a bug in SFML PI or EGL implementation.

Stacktrace of main thread during main thread freeze:

Thread 1 (Thread 0x76293000 (LWP 802)):
#0  0x76f3c014 in futex_abstimed_wait_cancelable (private=0, abstime=0x0, expected=1, 
    futex_word=0x76459b84 <pool_mem+1444>) at ../sysdeps/unix/sysv/linux/futex-internal.h:205
#1  do_futex_wait (sem=sem@entry=0x76459b84 <pool_mem+1444>, abstime=0x0) at sem_waitcommon.c:115
#2  0x76f3c158 in __new_sem_wait_slow (sem=0x76459b84 <pool_mem+1444>, abstime=0x0) at sem_waitcommon.c:282
#3  0x76804548 in eglSwapBuffers () from /opt/vc/lib/libbrcmEGL.so
#4  0x76ed14b8 in sf::Window::display() () from /usr/lib/libsfml-window.so.2.4
#5  0x000a8038 in Game::run() ()
#6  0x0013d9ec in main ()

Stacktrace of freeze during startup after killing the game:

Thread 1 (Thread 0x76223000 (LWP 1001)):
#0  0x76ecc014 in futex_abstimed_wait_cancelable (private=0, abstime=0x0, expected=1, 
---Type <return> to continue, or q <return> to quit---
    futex_word=0x767c1a58 <khrn_queue+76>) at ../sysdeps/unix/sysv/linux/futex-internal.h:205
#1  do_futex_wait (sem=sem@entry=0x767c1a58 <khrn_queue+76>, abstime=0x0) at sem_waitcommon.c:115
#2  0x76ecc158 in __new_sem_wait_slow (sem=0x767c1a58 <khrn_queue+76>, abstime=0x0) at sem_waitcommon.c:282
#3  0x763eeb60 in vchiu_queue_pop () from /opt/vc/lib/libvchiq_arm.so
#4  0x7679b014 in rpc_recv () from /opt/vc/lib/libbrcmEGL.so
#5  0x76795b54 in egl_surface_create () from /opt/vc/lib/libbrcmEGL.so
#6  0x767923b8 in eglCreatePbufferSurface () from /opt/vc/lib/libbrcmEGL.so
#7  0x76e635f4 in sf::priv::EglContext::EglContext(sf::priv::EglContext*) () from /usr/lib/libsfml-window.so.2.4
#8  0x76e5f2b0 in sf::priv::GlContext::initResource() () from /usr/lib/libsfml-window.so.2.4
#9  0x76e5f95c in sf::GlResource::GlResource() () from /usr/lib/libsfml-window.so.2.4
#10 0x76e60f54 in sf::Window::Window() () from /usr/lib/libsfml-window.so.2.4
#11 0x76ea2d7c in sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) () from /usr/lib/libsfml-graphics.so.2.4
#12 0x000a8642 in Game::Game() ()
#13 0x0013d9e6 in main ()
1 Answers

Disclaimer: This is not a solution, but some step that may help you identify or solve the issue.

What's more killing the game and running it again doesn't help

This means that you most likely are facing a driver level issue. Any application problem would be fixed by restarting it (assuming your application runs the same). And the fact that it freezes, plus references to sem_waitcommon and the look at the stack means, of course, that you are hitting a deadlock, originating from libbrcmEGL.so, the video driver. The bad news is, bugs in the video driver happen, can be pretty complex to solve, and because the driver is closed source, you won't be able to fix it yourself, or have it fixed by the community...

I wasn't able to find an issue matching yours exactly, which may point toward a bug yet unidentified, due to the specific combination of software and version you are using:

  • Your current distribution: kernel, glibc, cbrm firmware version
  • Your engine: SFML, SFML PI
  • And the fact that you are using EGL and not X11

Below are some steps, starting with the easiest

Peek at dmesg

That is a very easy first step that might yield valuable information. When the issue occurs, after the first and second freeze, see if anything shows up. Any important issue will be raised there, and shine some light onto your problem.

Report a bug

The first step is probably to report the problem in raspberrypi/linux, with an MVE. This may take some time, but maybe your best bet to fix that exact issue, as the firmware of the GPU (Videocore IV, as libbrcmEGL.so) is closed source.

SFML / SFML PI

Your bug is probably due to a specific set of operations on the driver that ends up triggering the bug you are seeing. I would recommend reducing your code to the minimum, to try to identify what triggers the problem. The fact that it happens randomly won't help, unfortunately. Even though this probably won't solve the core issue, you might be able to circumvent it.

Try a different version of SFML

Either upgrade or downgrade the version of SFML and SFML PI you are using. Again, this won't solve the core issue but might avoid it.

Flash an older Raspbian distribution

If this is a regression in the video driver, you might be able to fix it by flashing an older version of the distribution, from here

To minimize the effort, you can try to manually checkout a different version of libEGL* and libbrcmEGL.so from raspberry/firmware, but you might run into compatibility issues with their dependencies.

Switch to X11

I know... EGL will definitely give you better performances, and you probably don't need that desktop and composition. But given the larger community and use, chances are you will run into a lot fewer troubles. And because it uses libbrcmGLESv2.so, you are guaranteed the same (maybe bugged) code won't be executed.

Related