You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基础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),和你自己写的代码完全无关。主要原因有两个:

  1. 驱动或GLUT的资源清理不彻底:FreeGLUT在窗口关闭后,可能没触发底层图形资源的完整释放流程;或者Mesa这类开源驱动本身存在一些未修复的内存泄漏问题,属于驱动层面的遗留bug。
  2. 窗口退出行为的影响:你设置了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图形驱动,新版本可能修复了部分已知的内存泄漏。
  • 调整GLUT退出行为:把GLUT_ACTION_CONTINUE_EXECUTION改成GLUT_ACTION_GLUTMAINLOOP_RETURNS,让GLUT在窗口关闭后做更多内部资源清理,但无法完全消除驱动层面的泄漏。

内容的提问来源于stack exchange,提问作者Arrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:05:17