EGLDisplay句柄生命周期与静态对象生命周期相关问题咨询
问题解答
EGLDisplay句柄生命周期问题
这类EGL句柄确实存在固有生命周期,且长度远短于静态对象的生命周期,是你当前段错误的核心诱因。
Intel Mesa驱动的EGL实现会在进程退出的__libc_fini_array调用链前半段就销毁所有全局DRM连接、EGLDisplay内部关联资源,而C++静态对象的析构时机处于该调用链的最末尾,此时你持有的EGLDisplay已经被驱动隐式回收,调用eglDestroyContext()、eglTerminate()自然会返回EGL_BAD_DISPLAY,如果强行操作还会触发野指针访问导致段错误。
你引入OpenCV highgui模块后问题复现,是因为highgui内部也会初始化X11/EGL全局资源,它的退出清理逻辑同样在静态对象析构之前执行,会进一步提前释放DRM设备的全局引用,放大了生命周期不匹配的问题。
修复方案:
- 避免用静态对象持有EGLContext实例,改用显式的初始化、销毁接口,在
main函数返回前手动触发EGL资源清理 - 若必须保留静态持有逻辑,可新增EGLDisplay有效性校验逻辑,析构时如果检测到句柄已无效(可提前存一个有效标记,或调用
eglQueryDisplayAttribEXT判断返回值),直接跳过销毁操作即可
EGL_PLATFORM_DEVICE_EXT display句柄重复调用返回不同值问题
该异常不属于配置遗漏,通常有两个原因:
- 你每次调用
eglGetPlatformDisplayEXT()时传入的devicedrm是重新打开的/dev/dri/设备文件句柄,即使指向同一个物理设备,只要文件描述符数值不同,Mesa驱动会将其识别为不同的native_display实例,因此返回不同的EGLDisplay - 你使用的Ubuntu自带的Mesa驱动版本低于21.0,该版本之前的Mesa对
EGL_EXT_platform_base扩展的实现存在bug,没有做相同参数的句柄缓存,每次调用都会生成新的EGLDisplay实例
验证修复方式:
- 全局仅打开一次DRM设备文件,复用同一个文件描述符调用
eglGetPlatformDisplayEXT(),如果返回句柄仍不重复,可将Mesa驱动升级到22.0以上的稳定版即可解决缓存问题 - 部分驱动的句柄缓存逻辑仅在首次调用
eglInitialize()后生效,可在第一次获取并初始化EGLDisplay后再重复调用验证返回值是否一致
内容的提问来源于stack exchange,提问作者quasi
相关产品推荐
相关产品推荐

