基础freeglut程序出现内存泄漏问题求助
关于FreeGLUT程序关闭后Address Sanitizer检测到内存泄漏的问题
我正在编写一个简单的freeglut应用程序,代码如下:
#include "GL/freeglut.h" #include "glm/glm.hpp" // global and state variables namespace globals { const int screen_width = 720; const int screen_height = 720; const int window_position_x = 100; const int window_position_y = 100; const glm::vec4 clear_color (0.2f, 0.2f, 0.2f, 1.0f); } void display (); int main (int argc, char** argv) { glutInit(&argc, argv); // initialize GLUT window size, position, display mode glutInitWindowSize(globals::screen_width, globals::screen_height); glutInitWindowPosition(globals::window_position_x, globals::window_position_y); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); // continue execution after window is closed by user glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); // create a window glutCreateWindow("Simple GLUT Template"); // setup a display callback that GLUT calls for every render glutDisplayFunc(display); // start main loop glutMainLoop(); return 0; } void display () { using namespace globals; glClearColor(clear_color.r, clear_color.g, clear_color.b, clear_color.a); glClear(GL_COLOR_BUFFER_BIT); glutSwapBuffers(); }
编译命令为:
g++ -Wall -Wextra -pedantic -g -DDEBUG_MODE -D_GLIBCXX_DEBUG -fsanitize=address,undefined -lGL -lGLU -lglut simple-glut-template.cpp -o simple-glut-template
当我运行程序并关闭窗口时,Address Sanitizer检测到大量无法修复的内存泄漏(泄漏日志如下),希望能得到帮助理解问题原因,谢谢!
Memory leak found by Address Sanitizer:
================================================================= ==24070==ERROR: LeakSanitizer: detected memory leaks Indirect leak of 1264 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f2998557701 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd57701) #2 0x7f299855a86c (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd5a86c) Indirect leak of 632 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f2998557701 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd57701) #2 0x7f299855a1d7 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd5a1d7) Indirect leak of 520 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f29978b2317 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xb2317) Indirect leak of 416 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299ba65b04 (/lib/x86_64-linux-gnu/libGLX_mesa.so.0+0x42b04) Indirect leak of 416 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299854729e (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4729e) #2 0x7f2998549caf (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd49caf) #3 0x7f299855a8eb (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd5a8eb) Indirect leak of 120 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299ba7187f (/lib/x86_64-linux-gnu/libGLX_mesa.so.0+0x4e87f) Indirect leak of 96 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299854e18c (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4e18c) Indirect leak of 96 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b78d5 in __interceptor_realloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:85 #1 0x7f299855df80 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd5df80) #2 0x7f299854cf16 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4cf16) Indirect leak of 88 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f29978ad39d (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xad39d) Indirect leak of 88 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299c3009ce in xcb_register_for_special_xge (/lib/x86_64-linux-gnu/libxcb.so.1+0xe9ce) Indirect leak of 80 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7f299c301872 (/lib/x86_64-linux-gnu/libxcb.so.1+0xf872) Indirect leak of 56 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7f29978b55fc (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xb55fc) Indirect leak of 40 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b83b7 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:77 #1 0x7f299854cd45 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4cd45) Indirect leak of 32 byte(s) in 2 object(s) allocated from: #0 0x7f299c8b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7f299c301ab5 (/lib/x86_64-linux-gnu/libxcb.so.1+0xfab5) Indirect leak of 8 byte(s) in 1 object(s) allocated from: #0 0x7f299c8b89cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x7f299854d7aa (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4d7aa) #2 0x7f299855d270 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd5d270) #3 0x7f299854ca7f (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0xd4ca7f) #4 0x7f2997985729 (/usr/lib/x86_64-linux-gnu/dri/iris_dri.so+0x185729) SUMMARY: AddressSanitizer: 3952 byte(s) leaked in 21 allocation(s).
问题原因分析
从泄漏日志能明显看出,所有泄漏的内存都来自系统底层的图形驱动库(比如iris_dri.so、libGLX_mesa.so.0、libxcb.so.1),和你自己写的代码完全无关。主要原因有两个:
- 驱动或GLUT的资源清理不彻底:FreeGLUT在窗口关闭后,可能没触发底层图形资源的完整释放流程;或者Mesa这类开源驱动本身存在一些未修复的内存泄漏问题,属于驱动层面的遗留bug。
- 窗口退出行为的影响:你设置了
GLUT_ACTION_CONTINUE_EXECUTION,让程序在窗口关闭后继续执行glutMainLoop()之后的代码,但GLUT的部分内部资源可能没在这个时机完成清理,导致Sanitizer检测到泄漏。即便改成默认的退出行为,驱动层面的泄漏依然可能存在。
解决方案与建议
- 不用改你的代码:这些泄漏不会影响程序正常运行,属于工具误报或者驱动层面的问题,完全不需要修改业务代码。
- 如果想消除检测报告:
- 用Address Sanitizer的抑制文件忽略驱动泄漏:创建
asan_suppressions.txt文件,添加以下规则:
运行程序时加上参数:leak:*iris_dri.so* leak:*libGLX_mesa.so* leak:*libxcb.so*ASAN_OPTIONS=suppressions=asan_suppressions.txt ./simple-glut-template - 尝试升级Mesa图形驱动,新版本可能修复了部分已知的内存泄漏。
- 用Address Sanitizer的抑制文件忽略驱动泄漏:创建
- 调整GLUT退出行为:把
GLUT_ACTION_CONTINUE_EXECUTION改成GLUT_ACTION_GLUTMAINLOOP_RETURNS,让GLUT在窗口关闭后做更多内部资源清理,但无法完全消除驱动层面的泄漏。
内容的提问来源于stack exchange,提问作者Arrow
相关产品推荐
相关产品推荐

