与 OpenGL、SDL 和图形驱动程序相关的内存泄漏和错误

发布于 2024-12-13 19:09:41 字数 6467 浏览 0 评论 0原文

系统与库规格:
操作系统 - Ubuntu 11.10
显卡 - ATI Mobility Radeon HD 5430
显卡驱动程序版本 - fglrx-updates/fglrx-updates-dev (2:8.881-0ubuntu6.1)
SDL 版本 - libsdl1.2debian-all (SDL 1.2.14-6.1)
OpenGL 版本 - libgl1-mesa (7.7.1-5)
----4.1.11005 兼容性配置文件上下文
编译命令:gcc -Wall -Wextra -g -O3 -o $@ $^ -lSDL -lGLU -lGLEW -std=gnu99
包含的库“stdlib.h”“stdio.h”“stdarg.h”“string.h”“math.h”“SDL/SDL.h”“GL/glew.h”

问题描述 我正在尝试将 OpenGL/GLUT 应用程序移动到 OpenGL/SDL 应用程序中。 GLUT 应用程序运行无错误。

在 GDB 下,我收到以下分段错误:

Program received signal SIGSEGV, Segmentation fault.
__GI_getenv (name=0xb7f8af92 "L_MOUSE_RELATIVE") at getenv.c:90
90  getenv.c: No such file or directory.
    in getenv.c
(gdb) where
#0  __GI_getenv (name=0xb7f8af92 "L_MOUSE_RELATIVE") at getenv.c:90
#1  0xb7f69922 in ?? () from /usr/lib/libSDL-1.2.so.0
#2  0xb7f69922 in ?? () from /usr/lib/libSDL-1.2.so.0
#3  0xb7f30fa5 in SDL_PumpEvents () from /usr/lib/libSDL-1.2.so.0
#4  0xb7f30fe4 in SDL_PollEvent () from /usr/lib/libSDL-1.2.so.0
#5  0x080499df in mainloop (head=0x845f248) at mainloop.c:34

在整个程序中,我不断地检查 NULL 和其他失败的返回,因此我决定运行 Valgrind 来查看代码中内存处理不当的位置。以下链接到 valgrind --log-file=memerrors.txt ./main 的结果文件 http://www.2shared.com/document/1dnbZQPS/memerrors-simple.html

我通常不会关心 SDL、OpenGL 或图形驱动程序 (fglrx) 库中的内存错误,但几乎毫无疑问,不存在内存泄漏或错误。我自己的代码,所以我很好奇是否有人对此有任何想法。

int mainloop(void* head){
//Declare Standard Variables
MORB_Header* header = (MORB_Header*) head;
MORB_Renderer* render = header->render;
MORB_Light* light = render->light;

//Initialize Shader
GLShader* shader = glCreateShaders(header,"shader.vert","shader.frag");

//Load Textures for Use
texture[0] = glLoadTexture("rock.bmp");
texture[1] = glLoadTexture("rock_n.bmp");

//First Run Setup
header->scrUpd = 1;
glViewport(0,0, render->width,render->height);
//Check for Errors
GLenum errb = glGetError();
glProject(render->fov,render->aspect,render->zNear,render->zFar);   
errCheck("First Run Setup");

int morbexit = 0;
while(!morbexit)
{
    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
                //Do Nothing
    }
    if(header->scrUpd){
            /* Working Display Function */
        }
    else SDL_Delay(5);
    morbexit = header->quit;
}
free(shader);
return 0;
}

如果我删除事件循环,我不会收到分段错误,这让我认为内存问题主要出在 SDL 中。

我的准备功能如下:

    int width=800, height=600;
    SDL_Surface* initSDL()
{
const SDL_VideoInfo* video;
SDL_Surface* surface;

//Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) fatal("Video Init failed: %s\n",SDL_GetError());

video = SDL_GetVideoInfo( );
if (video == NULL) fatal("Video query failed: %s\n",SDL_GetError());

int flags = SDL_OPENGL | SDL_DOUBLEBUF | SDL_HWPALETTE;
if (video->hw_available) flags |= SDL_HWSURFACE;
else flags |= SDL_SWSURFACE;
if (video->blit_hw) flags |= SDL_HWACCEL;

/* Sets up OpenGL Attributes */
if(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) < 0) fatal("Double Buffering Init failed: %s\n", SDL_GetError());

/* Create the surface */
surface = SDL_SetVideoMode(width,height,32,flags);
if (surface==NULL) fatal("Video Mode Set failed: %s\n",SDL_GetError());
SDL_WM_SetCaption("Morbular","Morbular");

return surface;
}
void initGL()
{
GLenum err = glewInit();
if(!err == GLEW_OK) fatal("Glew Init failed: %s\n",glewGetErrorString(err));
glClearColor(0.0,0.0,0.0,1.0);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
errCheck("initGL()");
}
int main(int argc, char* argv[])
{
//Process command line arguments
for(int i=1; i<argc; i++) {
    if(!strcmp(argv[i],"-window")) {
        width = atoi(argv[++i]);
        height = atoi(argv[++i]);
        if(!(width && height)) {
            fatal("'-window' should be in the form '-window WIDTH HEIGHT'");
        }
    } else {
        printf("Argument %s is invalid...  ignored...", argv[i]);
    }
}

SDL_Surface* surface;
Header* header;

surface = initSDL();
initGL();

//Start Morbular
header = headerInit(surface);
mainloop(header);

//Cleanup on exit
SDL_Quit();

//Return
return EXIT_SUCCESS;
}

以及处理内存/OpenGL/SDL 的代码的其他部分

    //---- Code segement
int size = sizeof(Header)+sizeof(Renderer)+sizeof(Light);
void* addr = malloc(size);
if (addr == NULL) fatal("Cannot allocate %d bytes of memory for Header file %s\n",size,stderr);
Header* header = (Header*) addr;
    //---- Code segement (following sets all attributes of header,render,etc)

    //---- Code segement
int size = sizeof(GLShader);
GLShader* shader = malloc(size);
if (shader == NULL) fatal("Cannot allocate %d bytes of memory for Shader Program %s\n",size,stderr);
    //---- Code segement

    //---- Code segement
glValidateProgramARB(shader->ID)

    //---- Code segement
    char* textFileRead(char *filename)   
    {
FILE *file;
char *text = NULL;

int f,count;
f = open(filename, O_RDONLY);
if (f < 0) fatal("Cannot open file %s\n",filename);

count = lseek(f, 0, SEEK_END);
if(count<0) fatal("Error reading data from file %s\n",filename);

close(f);

if (filename != NULL) {
    file = fopen(filename,"rt");
    if (file != NULL) {
        if (count > 0) {
            int size = sizeof(char)*(count+1);
            text = (char *)malloc(size);
            if(text==NULL) fatal("Cannot allocate %d bytes of memory for file read %s\n",size,filename);
            count = fread(text,sizeof(char),count,file);
            text[count] = '\0';
        }
        fclose(file);
    } else fatal("Error reading data from file %s\n",filename); 
}
return text;
}

printInfoLog(shader->ID);

glUseProgramObjectARB(shader->ID);
    //Set uniforms         

free(vertexString);
free(fragmentString);
    //---- Code segement

如果您需要其他任何内容,请询问。请帮助我理解为什么会发生这种情况。

System & Library Specications:
Operating System - Ubuntu 11.10
Graphics Card - ATI Mobility Radeon HD 5430
Graphics Driver Version - fglrx-updates/fglrx-updates-dev (2:8.881-0ubuntu6.1)
SDL Version - libsdl1.2debian-all (SDL 1.2.14-6.1)
OpenGL Version - libgl1-mesa (7.7.1-5)
----4.1.11005 Compatibility Profile Context
Compile Commands: gcc -Wall -Wextra -g -O3 -o $@ $^ -lSDL -lGLU -lGLEW -std=gnu99
Included libraries "stdlib.h" "stdio.h" "stdarg.h" "string.h" "math.h" "SDL/SDL.h" "GL/glew.h"

Problem Description
I'm trying to move a OpenGL/GLUT application into an OpenGL/SDL application.
The GLUT applications works error free.

Under GDB I recieve the following segmentation fault:

Program received signal SIGSEGV, Segmentation fault.
__GI_getenv (name=0xb7f8af92 "L_MOUSE_RELATIVE") at getenv.c:90
90  getenv.c: No such file or directory.
    in getenv.c
(gdb) where
#0  __GI_getenv (name=0xb7f8af92 "L_MOUSE_RELATIVE") at getenv.c:90
#1  0xb7f69922 in ?? () from /usr/lib/libSDL-1.2.so.0
#2  0xb7f69922 in ?? () from /usr/lib/libSDL-1.2.so.0
#3  0xb7f30fa5 in SDL_PumpEvents () from /usr/lib/libSDL-1.2.so.0
#4  0xb7f30fe4 in SDL_PollEvent () from /usr/lib/libSDL-1.2.so.0
#5  0x080499df in mainloop (head=0x845f248) at mainloop.c:34

Throughout my entire program I consistently check for NULL and other failed returns, so I decided to run Valgrind to see where memory was being mishandled in my code. The following links to the resulting file of valgrind --log-file=memerrors.txt ./main
http://www.2shared.com/document/1dnbZQPS/memerrors-simple.html

I typically wouldn't care about the memory errors in the libraries for SDL, OpenGL, or the Graphics Driver(fglrx), but there are almost undoubtedly no memory leaks or errors in my own code, so I am curious if anyone has any thoughts on it.

int mainloop(void* head){
//Declare Standard Variables
MORB_Header* header = (MORB_Header*) head;
MORB_Renderer* render = header->render;
MORB_Light* light = render->light;

//Initialize Shader
GLShader* shader = glCreateShaders(header,"shader.vert","shader.frag");

//Load Textures for Use
texture[0] = glLoadTexture("rock.bmp");
texture[1] = glLoadTexture("rock_n.bmp");

//First Run Setup
header->scrUpd = 1;
glViewport(0,0, render->width,render->height);
//Check for Errors
GLenum errb = glGetError();
glProject(render->fov,render->aspect,render->zNear,render->zFar);   
errCheck("First Run Setup");

int morbexit = 0;
while(!morbexit)
{
    SDL_Event event;
    while(SDL_PollEvent(&event))
    {
                //Do Nothing
    }
    if(header->scrUpd){
            /* Working Display Function */
        }
    else SDL_Delay(5);
    morbexit = header->quit;
}
free(shader);
return 0;
}

If I remove the event loop, I do not receive the segmentation fault which makes me think the memory problem is primarily in SDL.

My preparation functions follows:

    int width=800, height=600;
    SDL_Surface* initSDL()
{
const SDL_VideoInfo* video;
SDL_Surface* surface;

//Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) fatal("Video Init failed: %s\n",SDL_GetError());

video = SDL_GetVideoInfo( );
if (video == NULL) fatal("Video query failed: %s\n",SDL_GetError());

int flags = SDL_OPENGL | SDL_DOUBLEBUF | SDL_HWPALETTE;
if (video->hw_available) flags |= SDL_HWSURFACE;
else flags |= SDL_SWSURFACE;
if (video->blit_hw) flags |= SDL_HWACCEL;

/* Sets up OpenGL Attributes */
if(SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24) < 0) fatal("Video Attribute error: %s\n", SDL_GetError());
if(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1) < 0) fatal("Double Buffering Init failed: %s\n", SDL_GetError());

/* Create the surface */
surface = SDL_SetVideoMode(width,height,32,flags);
if (surface==NULL) fatal("Video Mode Set failed: %s\n",SDL_GetError());
SDL_WM_SetCaption("Morbular","Morbular");

return surface;
}
void initGL()
{
GLenum err = glewInit();
if(!err == GLEW_OK) fatal("Glew Init failed: %s\n",glewGetErrorString(err));
glClearColor(0.0,0.0,0.0,1.0);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
errCheck("initGL()");
}
int main(int argc, char* argv[])
{
//Process command line arguments
for(int i=1; i<argc; i++) {
    if(!strcmp(argv[i],"-window")) {
        width = atoi(argv[++i]);
        height = atoi(argv[++i]);
        if(!(width && height)) {
            fatal("'-window' should be in the form '-window WIDTH HEIGHT'");
        }
    } else {
        printf("Argument %s is invalid...  ignored...", argv[i]);
    }
}

SDL_Surface* surface;
Header* header;

surface = initSDL();
initGL();

//Start Morbular
header = headerInit(surface);
mainloop(header);

//Cleanup on exit
SDL_Quit();

//Return
return EXIT_SUCCESS;
}

and other parts of code that deal with memory/OpenGL/SDL

    //---- Code segement
int size = sizeof(Header)+sizeof(Renderer)+sizeof(Light);
void* addr = malloc(size);
if (addr == NULL) fatal("Cannot allocate %d bytes of memory for Header file %s\n",size,stderr);
Header* header = (Header*) addr;
    //---- Code segement (following sets all attributes of header,render,etc)

    //---- Code segement
int size = sizeof(GLShader);
GLShader* shader = malloc(size);
if (shader == NULL) fatal("Cannot allocate %d bytes of memory for Shader Program %s\n",size,stderr);
    //---- Code segement

    //---- Code segement
glValidateProgramARB(shader->ID)

    //---- Code segement
    char* textFileRead(char *filename)   
    {
FILE *file;
char *text = NULL;

int f,count;
f = open(filename, O_RDONLY);
if (f < 0) fatal("Cannot open file %s\n",filename);

count = lseek(f, 0, SEEK_END);
if(count<0) fatal("Error reading data from file %s\n",filename);

close(f);

if (filename != NULL) {
    file = fopen(filename,"rt");
    if (file != NULL) {
        if (count > 0) {
            int size = sizeof(char)*(count+1);
            text = (char *)malloc(size);
            if(text==NULL) fatal("Cannot allocate %d bytes of memory for file read %s\n",size,filename);
            count = fread(text,sizeof(char),count,file);
            text[count] = '\0';
        }
        fclose(file);
    } else fatal("Error reading data from file %s\n",filename); 
}
return text;
}

printInfoLog(shader->ID);

glUseProgramObjectARB(shader->ID);
    //Set uniforms         

free(vertexString);
free(fragmentString);
    //---- Code segement

If you need anything else just ask. Please help me understand why this happens.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绿萝 2024-12-20 19:09:41

当我

  • 不要调用库初始化函数。(在我的例子中经常调用glew_init())
  • 在运行时安装了错误的位数(x86 与 x64)库(不属于 apt 的内容的下载链接错误),但这通常会导致链接器错误
  • 在调试模式下编译时使用运行时而不是开发库。 (忘记了 apt-get install lib-awesome-dev 中的 -dev )
  • I usually see things like this when I

  • don't call library initialization functions.(glew_init() often in my case)
  • Have the wrong bitness (x86 vs x64) libraries at run time installed (wrong download link for something not in apt) though usually this causes linker errors
  • Have runtime instead of dev libraries when compiling in debug mode. (forgot -dev in apt-get install lib-awesome-dev)
  • ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文