SDL3调用SDL_CreateWindowAndRenderer出现128字节内存泄漏求助
关于SDL3.4.x在Fedora 43上128字节内存泄漏的可能来源分析
核心场景回顾
运行最小复现代码时,AddressSanitizer检测到128字节直接内存泄漏,栈追踪指向SDL_EGL_LoadLibrary、Wayland_GLES_LoadLibrary等SDL内部调用:
#include <SDL3/SDL.h> int main() { SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; SDL_CreateWindowAndRenderer("Leak Test", 640, 480, 0, &window, &renderer); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; }
项目配置:CMake引入SDL3源码,开启-fsanitize=address编译选项,编译时添加-DSDL_X11_XSCRNSAVER=OFF参数。
可能的泄漏来源
1. SDL EGL/Wayland后端的清理逻辑遗漏
SDL加载Wayland平台的EGL库时,会分配存储库句柄、函数指针表的内部结构体(如SDL_EGLContextData类结构),若SDL_Quit流程中对应的清理函数(如SDL_EGL_Quit、Wayland_GLES_Quit)未完全释放这些结构,会产生固定大小的内存泄漏,128字节刚好匹配部分平台特定结构体的尺寸。
另外,编译时关闭SDL_X11_XSCRNSAVER可能触发非标准初始化分支,导致部分清理代码未执行。
2. 外部EGL/Wayland库自身的泄漏
正如SDL官方提及的外部库泄漏情况,这128字节可能来自系统EGL实现(如Fedora 43自带的Mesa EGL库)或Wayland客户端库:
- EGL库加载时可能分配全局配置缓存、设备信息等内存,这类内存通常不会在库卸载时自动释放;
- Wayland后端的某些全局状态初始化后,对应的销毁逻辑未被SDL正确触发,或外部库本身存在未修复的泄漏。
3. 动态加载函数的残留内存
SDL通过dlopen/dlsym加载EGL和Wayland相关函数时,可能保留部分动态加载的元数据内存,这类内存会被进程退出时系统回收,但会被AddressSanitizer标记为泄漏。
验证方法
- 切换视频后端测试:设置环境变量
SDL_VIDEODRIVER=x11运行程序,若泄漏消失,说明问题出在Wayland后端相关逻辑; - 单独测试EGL库:编写不依赖SDL的小程序,直接调用EGL初始化/终止接口,用ASAN检测是否存在泄漏,确认是否为外部库问题;
- 检查SDL源码清理逻辑:查看SDL3.4.x版本中
src/video/egl/SDL_egl.c和src/video/wayland/SDL_waylandopengles.c的退出函数,确认是否有未释放的128字节结构。
内容的提问来源于stack exchange,提问作者luke sim
相关产品推荐
相关产品推荐

