eglSwapBuffers никогда не возвращается

Разрабатываю простенькую игру на Raspberry Pi 3. В качестве операционной системы использую официальную Raspbian Stretch Lite. Игра запускается без X-сервера и разработана на C++ с использованием библиотеки SFML PI.

Проблема в том, что игра время от времени зависает. Это может произойти через несколько секунд или через несколько часов после запуска игры, но рано или поздно это всегда происходит. Трассировка стека указывает на то, что eglSwapBuffers никогда не возвращается. Более того, убийство игры и повторный запуск не помогают - она ​​зависает при запуске на вызове eglCreatePbufferSurface. Он снова запускается после перезагрузки. В чем может быть причина такого зависания? Можно как-то отладить? Я очень боюсь, что это может быть вызвано ошибкой в ​​реализации SFML PI или EGL.

Stacktrace основного потока во время зависания основного потока:

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 зависаний при запуске после закрытия игры:

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 ()

person Rames    schedule 21.10.2018    source источник
comment
Не могли бы вы предоставить больше информации? Все ли ваши драйверы обновлены? Игра многопоточная? Есть ли что-нибудь, что вы можете сделать, чтобы это произошло (хотя бы быстрее)?   -  person gabe870    schedule 24.03.2019
comment
За исключением того, что если вы делаете что-то странное, для меня это похоже на проблему с драйвером. Есть ли у вас какие-либо связанные ошибки в вашем журнале dmesg, когда это происходит? Также важно знать, какая именно у вас плата, версия ядра и версия драйвера.   -  person Adrien Leravat    schedule 24.03.2019
comment
@ gabe870 Не знаю, можешь что-нибудь предложить? Позвонить sf::Window::display как можно быстрее? Да, игра, к сожалению, многопоточная, но я не вызываю никаких SFML или EGL/OpenGL API из потоков, отличных от основного. @AdrienLeravat Я не проверял dmesg журнал. Это происходит как на Raspberry Pi 3 B, так и на Raspberry Pi 3 B+. Версия ядра: 4.14.87-v7+ Прошивка: 4 декабря 2018 г., 16:50:03, версия 1f3414729f43ef3b977a910a0d811a759562e1cf (чистая) (релиз)   -  person Rames    schedule 25.03.2019


Ответы (1)


Отказ от ответственности. Это не решение, а некий шаг, который может помочь вам определить или решить проблему.

Более того, убить игру и запустить ее снова не помогает.

Это означает, что вы, скорее всего, столкнулись с проблемой на уровне драйвера. Любая проблема с приложением будет устранена путем его перезапуска (при условии, что ваше приложение работает так же). И тот факт, что он зависает, плюс ссылки на sem_waitcommon и просмотр стека означает, конечно, что вы попали в тупик, исходящий от libbrcmEGL.so, видеодрайвера. Плохая новость заключается в том, что ошибки в видеодрайвере случаются, их довольно сложно решить, а поскольку исходный код драйвера закрыт, вы не сможете исправить его самостоятельно или доверить его исправлению сообщества...

Мне не удалось найти проблему, точно соответствующую вашей, что может указывать на еще не идентифицированную ошибку из-за конкретной комбинации программного обеспечения и версии, которую вы используете:

  • Ваш текущий дистрибутив: ядро, glibc, версия прошивки cbrm
  • Ваш движок: SFML, SFML PI
  • И тот факт, что вы используете EGL, а не X11

Ниже приведены некоторые шаги, начиная с самого простого

Посмотрите на dmesg

Это очень простой первый шаг, который может дать ценную информацию. Когда проблема возникает, после первого и второго зависания, посмотрите, не появится ли что-нибудь. Любой важный вопрос будет поднят там и прольет свет на вашу проблему.

Сообщить об ошибке

Первым шагом, вероятно, будет сообщение о проблеме в raspberrypi/linux с помощью MVE. Это может занять некоторое время, но, возможно, лучше всего решить именно эту проблему, поскольку прошивка графического процессора (Videocore IV, как libbrcmEGL.so) имеет закрытый исходный код.

SFML / SFML PI

Ваша ошибка, вероятно, связана с определенным набором операций в драйвере, которые в конечном итоге вызывают ошибку, которую вы видите. Я бы рекомендовал сократить ваш код до минимума, чтобы попытаться определить, что вызывает проблему. Тот факт, что это происходит случайно, к сожалению, не поможет. Хотя это, вероятно, не решит основную проблему, вы можете обойти ее.

Попробуйте другую версию SFML

Обновите или понизьте версию SFML и SFML PI, которую вы используете. Опять же, это не решит основную проблему, но может ее избежать.

Прошить более старый дистрибутив Raspbian

Если это регресс в видеодрайвере, вы можете исправить это, установив более старую версию дистрибутива из здесь

Чтобы свести к минимуму усилия, вы можете попробовать вручную проверить другую версию libEGL* и libbrcmEGL.so с raspberry/firmware, но вы можете столкнуться с проблемами совместимости с их зависимостями.

Переключиться на X11

Я знаю... EGL определенно даст вам лучшую производительность, и вам, вероятно, не нужен этот рабочий стол и композиция. Но, учитывая более широкое сообщество и использование, скорее всего, у вас будет гораздо меньше проблем. И поскольку он использует libbrcmGLESv2.so, вам гарантировано, что тот же код (возможно, с ошибками) не будет выполнен.

person Adrien Leravat    schedule 26.03.2019
comment
dmesg не показывает ничего, связанного с графическим процессором. Ваши идеи вполне логичны, но из-за недетерминированности этой ошибки их очень трудно проверить. Как узнать, исправили ли изменения ошибку или мне просто повезло и зависания не произошло? Несколько раз до этого я думал, что проблема решилась сама собой, потому что игра работала без каких-либо проблем в течение 24 часов, но я всегда ошибался. - person Rames; 26.03.2019
comment
Что касается любой случайно возникающей проблемы, единственный способ узнать, исправлена ​​ли она, - это, к сожалению, запустить ее в течение длительного (достаточно) периода времени. Это проще, если вы найдете способ воспроизвести его более надежно/часто, возможно, за счет большей нагрузки на драйвер. Условия гонки самые ужасные! По этой же причине я считаю, что гораздо проще оформить тикет, и надеюсь, что они смогут исправить это в разумные для вас сроки. Без возможности отладки или инструментирования драйвера brcm это просто предположение. Сообщите мне о том, что происходит! - person Adrien Leravat; 26.03.2019