微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 Docker 容器内的 Wayland 上使用 EGL 的应用程序崩溃

如何解决在 Docker 容器内的 Wayland 上使用 EGL 的应用程序崩溃

我使用的是 Toradex 的 Apalis i.MX8QM 模块。我安装了 Torizo​​n,这是制造商提供的 Linux 操作系统。它旨在与基于 debian 的 Docker 容器一起使用。他们提供了一个运行 Weston (Wayland + XWayland) 的容器来渲染图形。 在另一个容器中,我使用以下 Dockerfile 编译了 ogre3d 图形引擎(源代码www.github.com/OGRECave/ogre):

FROM --platform=linux/arm64 torizon/wayland-base-vivante:2 AS base
RUN apt-get -y update && apt-get install -y --no-install-recommends \
    apt-utils \
    && apt-mark hold dash && apt-get -y upgrade && apt-mark unhold dash \
    && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*
ARG ACCEPT_FSL_EULA=1
RUN apt-get -y update && apt-get install -y --no-install-recommends \
    libwayland-client0 \
    libwayland-server0 \
    libgal-vivante1 \
    libvsc-vivante1 \
    libgbm-vivante1 \
    libegl-vivante1 \
    libgl-vivante1 \
    libglesv2-vivante1 \
    libglesv1-cm-vivante1 \
    libglslc-vivante1 \
    && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*
# Make sure the user can access DRM and video devices
RUN usermod -a -G video,render torizon
# UP TO HERE ITS CODE PROVIDED BY TORADEX 
RUN apt-get -y update && apt-get install -y git cmake gcc g++ make libxrandr-dev libglu1-mesa-dev libzip-dev libfreeimage-dev libpoco-dev libois-dev libzzip-0-13 libzzip-dev doxygen libcgal-dev libcppunit-dev libxt-dev libxaw7-dev pkg-config gdb x11-apps nano libsdl2-2.0 libegl-vivante1-dev
USER torizon
RUN cd /home/torizon/ && git clone https://github.com/OGRECave/ogre
RUN mkdir -p /home/torizon/ogre/bld && cd /home/torizon/ogre/bld && cmake -DCMAKE_BUILD_TYPE=Debug -DOGRE_GLSUPPORT_USE_EGL=1 -DOGRE_BUILD_RENDERSYstem_GLES2=1 -DOGRE_BUILD_SAMPLES=1 -DOGRE_CONfig_THREADS=0 -DOGRE_INSTALL_DOCS=0 -DOGRE_BUILD_PLUGIN_CG=0 -DOGRE_INSTALL_MEDIA=1 -DOGRE_BUILD_TOOLS=0 -DOGRE_BUILD_TESTS=0 -DOGRE_INSTALL_SAMPLES=1 ../
RUN cd /home/torizon/ogre/bld && make
USER root
RUN cd /home/torizon/ogre/bld && make install

上面的容器使用以下命令运行(可能不需要一些环境变量来真正完成这项工作):

docker run -e ACCEPT_FSL_EULA=1 -e X11_UNIX_SOCKET=/tmp/.X11-unix -e WAYLAND_disPLAY=wayland-0 -e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR -e disPLAY=:0 -it --rm --name=wayland-app --user=torizon -v /dev/dri:/dev/dri -v /dev/galcore:/dev/galcore -v /tmp:/tmp -v /run/:/run/ --device-cgroup-rule='c 199:* rmw' --device-cgroup-rule='c 226:* rmw' --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ogre-way-base-egl-j1

当我尝试运行 ogre3d 编译后编译的第一个示例时,出现一些错误。我用 gdb 运行它来帮助调试。输出如下所示:

torizon@0c2f3e5ed77f:~/ogre/bld/bin$ gdb Samplebrowser
GNU gdb (Debian 9.2-1) 9.2
copyright (C) 2020 Free Software Foundation,Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY,to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "aarch64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions,please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help,type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from Samplebrowser...
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) r
Starting program: /home/torizon/ogre/bld/bin/Samplebrowser
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/aarch64-linux-gnu/libthread_db.so.1".
Creating resource group General
Creating resource group OgreInternal
Creating resource group OgreAutodetect
SceneManagerFactory for type 'DefaultSceneManager' registered.
Registering ResourceManager for type Material
Registering ResourceManager for type Mesh
Registering ResourceManager for type Skeleton
MovableObjectFactory for type 'ParticleSystem' registered.
ArchiveFactory for archive type FileSystem registered.
ArchiveFactory for archive type Zip registered.
ArchiveFactory for archive type EmbeddedZip registered.
DDS codec registering
ETC codec registering
ASTC codec registering
Registering ResourceManager for type HighLevelGpuProgram
Registering ResourceManager for type Compositor
MovableObjectFactory for type 'Entity' registered.
MovableObjectFactory for type 'Light' registered.
MovableObjectFactory for type 'BillboardSet' registered.
MovableObjectFactory for type 'ManualObject' registered.
MovableObjectFactory for type 'BillboardChain' registered.
MovableObjectFactory for type 'RibbonTrail' registered.
Loading library /home/torizon/ogre/bld/lib/RenderSystem_GLES2.so.1.12.12
Installing plugin: OpenGL ES 2.0 RenderSystem
OpenGL ES 2.x Rendering Subsystem created.
[New Thread 0xffffe5601170 (LWP 22)]
[New Thread 0xffffe4e00170 (LWP 23)]

Thread 1 "Samplebrowser" received signal SIGSEGV,Segmentation fault.
0x0000fffff6e6dbd0 in pthread_mutex_lock () from /lib/aarch64-linux-gnu/libpthread.so.0
(gdb) bt
#0  0x0000fffff6e6dbd0 in pthread_mutex_lock () from /lib/aarch64-linux-gnu/libpthread.so.0
#1  0x0000fffff69432f0 in wl_proxy_create_wrapper () from /usr/lib/aarch64-linux-gnu/libwayland-client.so.0
#2  0x0000fffff6ba1b50 in ?? () from /usr/lib/aarch64-linux-gnu/libEGL.so.1
#3  0x0000fffff6b94534 in eglInitialize () from /usr/lib/aarch64-linux-gnu/libEGL.so.1
#4  0x0000fffff6c7d694 in Ogre::EGLSupport::getGLdisplay (this=0xaaaaaab17b90) at /home/torizon/ogre/RenderSystems/GLSupport/src/EGL/OgreEGLSupport.cpp:65
#5  0x0000fffff6c618c4 in Ogre::X11EGLSupport::getGLdisplay (this=0xaaaaaab17b90) at /home/torizon/ogre/RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLSupport.cpp:280
#6  0x0000fffff6c60ba4 in Ogre::X11EGLSupport::X11EGLSupport (this=0xaaaaaab17b90,profile=4) at /home/torizon/ogre/RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLSupport.cpp:51
#7  0x0000fffff6c60b44 in Ogre::getGLSupport (profile=4) at /home/torizon/ogre/RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLSupport.cpp:45
#8  0x0000fffff6c3d1c4 in Ogre::GLES2RenderSystem::GLES2RenderSystem (this=0xaaaaaab17180) at /home/torizon/ogre/RenderSystems/GLES2/src/OgreGLES2RenderSystem.cpp:178
#9  0x0000fffff6c3cb18 in Ogre::GLES2Plugin::install (this=0xaaaaaab17100) at /home/torizon/ogre/RenderSystems/GLES2/src/OgreGLES2Plugin.cpp:48
#10 0x0000fffff79c026c in Ogre::Root::installPlugin (this=0xaaaaaab00b20,plugin=0xaaaaaab17100) at /home/torizon/ogre/OgreMain/src/OgreRoot.cpp:1188
#11 0x0000fffff6c28bc4 in Ogre::dllStartPlugin () at /home/torizon/ogre/RenderSystems/GLES2/src/OgreGLES2EngineDll.cpp:41
#12 0x0000fffff79c064c in Ogre::Root::loadplugin (this=0xaaaaaab00b20,pluginName="/home/torizon/ogre/bld/lib/RenderSystem_GLES2") at /home/torizon/ogre/OgreMain/src/OgreRoot.cpp:1237
#13 0x0000fffff79bf2c4 in Ogre::Root::loadplugins (this=0xaaaaaab00b20,pluginsfile="./plugins.cfg") at /home/torizon/ogre/OgreMain/src/OgreRoot.cpp:973
#14 0x0000fffff79bc9ac in Ogre::Root::Root (this=0xaaaaaab00b20,pluginFileName="./plugins.cfg",configFileName="./ogre.cfg",logFileName="./ogre.log")
    at /home/torizon/ogre/OgreMain/src/OgreRoot.cpp:227
#15 0x0000fffff7f76d3c in OgreBites::ApplicationContextBase::createRoot (this=0xfffffffff238) at /home/torizon/ogre/Components/Bites/src/OgreApplicationContextBase.cpp:191
#16 0x0000fffff7f7663c in OgreBites::ApplicationContextBase::initApp (this=0xfffffffff238) at /home/torizon/ogre/Components/Bites/src/OgreApplicationContextBase.cpp:55
#17 0x0000aaaaaaab6b28 in OgreBites::SampleContext::go (this=0xfffffffff238,initialSample=0x0) at /home/torizon/ogre/Samples/Common/include/SampleContext.h:143
#18 0x0000aaaaaaab44e4 in main (argc=1,argv=0xfffffffff648) at /home/torizon/ogre/Samples/browser/src/main.cpp:89

正如我们所见,它在从 libwayland-client 调用的 pthread_mutex_lock() 处崩溃。

就在调用 eglInitialize() 之前(正好在 this代码中),参数值是:

(gdb) step
65              if (eglInitialize(mGLdisplay,&mEGLMajor,&mEGLMinor) == EGL_FALSE)
(gdb) print mGLdisplay
$3 = (EGLdisplay) 0xaaaaaab16180
(gdb) print *mEGLMajor
Cannot access memory at address 0x0
(gdb) print mEGLMajor
$4 = 0
(gdb) print mEGLMinor
$5 = 0

我在互联网上搜索,但找不到任何适合我的情况的解决方案,我不知道如何继续尝试解决此问题。

感谢您提供任何信息。

解决方法

我尝试使用我们的 Visual Studio 代码扩展重现构建 ogre 的问题,所以事情可能有点不同(我使用了交叉复杂化,并有一个容器来构建和一个容器来运行应用程序)。 首先,我更改了构建配置以移除一些渲染器,这有助于简化依赖关系。 这些是我在 cmake 中的定义:

    "OGRE_GLSUPPORT_USE_EGL":1,"OGRE_BUILD_RENDERSYSTEM_GL":0,"OGRE_BUILD_RENDERSYSTEM_GL3PLUS":0,"OGRE_BUILD_RENDERSYSTEM_TINY":0,"OGRE_BUILD_RENDERSYSTEM_GLES2":1,"OGRE_BUILD_SAMPLES":1,"OGRE_CONFIG_THREADS": 0,"OGRE_INSTALL_DOCS":0,"OGRE_BUILD_PLUGIN_CG":0,"OGRE_INSTALL_MEDIA":1,"OGRE_BUILD_TOOLS":0,"OGRE_BUILD_TESTS":0,"OGRE_INSTALL_SAMPLES":1

我还添加了一个安装后命令来修复从我的本地文件夹到我在设备上使用的文件夹 (/ogre) 的安装路径。 在 CMakeList.txt 的末尾我添加了:

install (SCRIPT "${CMAKE_SOURCE_DIR}/PostInstall.cmake")

这是 PostInstall.cmake:

message("Post install script")

execute_process(COMMAND bash "-c" "sed -i s+/workspaces/ogre/appconfig_0/work/ogre+/ogre+g ${CMAKE_INSTALL_PREFIX}/share/OGRE/*.cfg"
    )

对于构建,我使用这个 dockerfile:

FROM torizon/debian-cross-toolchain-arm64:2-bullseye

RUN HOLD_PKGS='libdrm-common libdrm-amdgpu1:arm64 libdrm2:arm64' \
    && apt-get -y update \
    && apt-get -y upgrade \
    && for P in $HOLD_PKGS ; do \
    echo ${P}=$(apt-cache show $P | sed -r -e '/^Version:/!d' -e 's/.* //' -e '/toradex/d' -e 'q') ; \
    done | xargs -r apt-get install -y --no-install-recommends \
    && apt-mark hold $HOLD_PKGS \
    && apt-get clean && apt-get autoremove && rm -rf /var/lib/apt/lists/*

# commands that should be run before installing packages (ex: to add a feed or keys)


# your regular RUN statements here
# Install required packages
RUN apt-get -q -y update \
    && apt-get -q -y install gdb-multiarch procps rsync openssh-client\
    libwayland-dev:arm64 \
    libgbm-vivante1-dev:arm64 libegl-vivante1-dev:arm64 libglesv2-vivante1-dev:arm64 libxrandr-dev:arm64  libzip-dev:arm64 libfreeimage-dev:arm64 libpoco-dev:arm64 libois-dev:arm64 libzzip-dev:arm64 doxygen libcgal-dev:arm64 libcppunit-dev:arm64 libxt-dev:arm64 libxaw7-dev:arm64\
    \
    && rm -rf /var/lib/apt/lists/*

(您可以添加命令来克隆代码、应用更改并构建它)

这是我用来运行应用程序的 dockerfile:

FROM --platform=linux/arm64 torizon/wayland-base:2
          
# Make sure we don't get notifications we can't answer during building.
ENV DEBIAN_FRONTEND="noninteractive"

ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/ogre/lib OGRE_PLUGIN_DIR=/ogre/lib/OGRE

# commands that should be run before installing packages (ex: to add a feed or keys)


# your regular RUN statements here
# Install required packages
RUN if [ ! -z "libxt6 libxaw7 libzzip-0-13 libxrandr2" ]; then \
    apt-get -q -y update \
    && apt-get -q -y install libxt6 libxaw7 libzzip-0-13 libxrandr2 \
    && rm -rf /var/lib/apt/lists/* ; \
    fi

# commands that should be run after all packages have been installed (RUN/COPY/ADD)



COPY work/ogre /ogre


USER torizon

WORKDIR /ogre

# commands that will run on the target (ENTRYPOINT or CMD)
CMD /ogre/bin/SampleBrowser 

通过这种方式,我能够在不崩溃的情况下运行应用程序。 鼠标光标在 openGL 表面上不可见时存在问题。 我使用 Verdin iMX8MM 是因为我没有可用的 Apalis IMX8 ATM,但平台应该相似(用于 GPU 的 imx8 和 vivante 驱动程序)。

如果您想尝试使用我们的 IDE 扩展来构建它,我可以将我的更改分享到 ogre master 分支,但是在调试此问题时,我发现我们自己的扩展中存在问题,我们需要几周时间才能发布更新。 很抱歉出现这个问题。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。