I'm going CRAZY!!! Random crashes without reason

Moderator
Posts: 1,140
Joined: 2005.07
Post: #1
This has got to be the weirdest thing EVER! I'm trying to make a game with a full screen graphics context. After getting that out, and trying to display a menu, it worked fine for a little while. Then, suddenly, it started crashing. Without changing anything major. It keeps on saying that I was accessing freed memory and the crash reporter usually gives me the line where I call glGenTextures, the debugger stopps where I free a C string. The problem is, I don't have anything else where I free it! Here's a walkthrough of what I did trying to track down the problem:

This C string is one that I'm constructing to open a texture. I malloc it, copy the bundle string, then concatenate the rest of the path. After that, I feed the string into my open TGA method, and free the string. The string is accessed twice: once to check to make sure it's not NULL, and once to open the file. That can't be a problem, but I comment it out anyway. Next, it crashes citing where I delete the TGA file after loading the texture (using glTexImage2D), saying where I set the pointer to NULL. Ok, I take that out. It then crashes pointing to the end of the function. I say WTF??? and comment out where I actually free the data, and it works. It also works when I just comment out my deleteTGA function. Neither of those should have done anything. The this class also contains Font classes which instantiate before hand it actually gets to the crash. It has a nearly identical method of opening my font texture, and if I comment out the string free and texture delete there, it usually works as well. At one point, I commented out all of my texture loading function calls, and it says I accessed freed memory when assigning an integer! (by the line number it gave me)

It gets even weirder. I commented out my capture display function calls, and ran through the debugger. It went through the instanciation of the menu class this is crashing in, it starts instanciating the fonts, goes to the malloc of the C string for accessing the font texture, then completely dies. When I look at the function calls, it suddenly jumped past all not only that font instanciation, but all the rest of them as well to where I freed the C string for opening the texture for the texture after all that is done.

When I comment out all the frees and deletes, it runs, but doesn't load one of the textures.

As a final test, I went into main.m, took out NSApplicationMainLoop, instanciated my controller, slept for 20 seconds, then quit. Lo and behold, it worked perfectly! Loaded all the textures and displayed the graphics perfectly, no malloc errors, NOTHING! I take it back out, and it crashes.

Edit: almost forgot to mention: at one point, I put in a print call, and it didn't crash! One of the textures didn't load, but it didn't crash. I took out the print statement, and it crashed again... Talk about weird. Not even accessing anything, just "cerr << "here\n";"

Here is all relevent code. I'm at a complete loss. I've been at this all day without avail. Hopefully somebody here with more cocoa experience can help me.

(mainWindow and eventView were added after trying most of this stuff, but made no difference)

AppController init (called first)
Code:
- (id)init
{
    self = [super init];
    if (self != nil)
    {
        [mainWindow makeKeyAndOrderFront:self];
        appController = self;
        gameView = [[GameView alloc] init];
        [eventView lockFocus];
        mainList = new DrawList;
        Drawable *menu = new MainMenu;
        mainList->insert(menu);
        [gameView draw];
    }
    return self;
}

GameView init
Code:
- (id)init
{
    self = [super init];
    previousDisplay = CGDisplayCurrentMode(kCGDirectMainDisplay);
    CGDisplayCapture(kCGDirectMainDisplay);
    [self setFullScreen];
    NSOpenGLPixelFormatAttribute attributes[] =
    {
        NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32,
        NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
        NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)32,
        NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
        NSOpenGLPFASampleBuffers, (antiAliasing) ? (NSOpenGLPixelFormatAttribute)1 : (NSOpenGLPixelFormatAttribute)0,
        NSOpenGLPFASamples, (NSOpenGLPixelFormatAttribute)antiAliasing,
        NSOpenGLPFAScreenMask, (NSOpenGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDispla​y),
        NSOpenGLPFAFullScreen,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFAAccelerated,
        NSOpenGLPFAAllRenderers,
        (NSOpenGLPixelFormatAttribute)0
    };
    NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
    sharedContext = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil];
    context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:sharedContext];
    [format release];
    clearColor[0] = clearColor[1] = clearColor[2] = 0;
    clearColor[3] = 1;
    location = LOC_MAIN_MENU;
    [self reshape];
    [self prepare];
    return self;
}

setFullScreen
Code:
- (void)setFullScreen
{
    CFDictionaryRef fullScreen = CGDisplayBestModeForParameters(kCGDirectMainDisplay, 32, width, height, NULL );
    CGDisplaySwitchToMode(kCGDirectMainDisplay, fullScreen);
    NSRect rect = NSMakeRect(0, 0, width, height);
    [[[AppController appController] mainWindow] setFrame:rect display:false];
    [[[AppController appController] eventView] setFrame:rect];
}

reshape
Code:
- (void)reshape
{
    [context setFullScreen];
    [context makeCurrentContext];
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    ratio = (float)width/(float)height;
    if (location == LOC_MAIN_MENU || location == LOC_OPTIONS_MENU || location == LOC_LEVEL_SELECT)
        glOrtho(-200*ratio, 200*ratio, 0, 400, -200, 200);
    else
        gluPerspective(90.0, ratio, 0.1, 1000);
}

prepare
Code:
- (void)prepare
{
    glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_CULL_FACE);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

font's constructor (texture loading part)
Code:
char *texturePath;
        if (textureQuality == LOW_QUALITY)
            texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier low.tga";
        else if (textureQuality == HIGH_QUALITY)
            texturePath = "/Space Chase.app/Contents/Resources/Textures/Courier.tga";
        char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
        strcpy(completePath, appPath);
        mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
        free(completePath);
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
                     0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
        mnkyDeleteTGA(&tex);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        currentQuality = textureQuality;

menu's constructor
Code:
MainMenu::MainMenu() : title("Space Chase", large, zero, zero, titleColor), start("Start Game", small, zero, zero, itemColor),
startSelected("Start Game", selected, zero, zero, itemColor), level("Select Level", small, zero, zero, itemColor),
levelSelected("Select Level", selected, zero, zero, itemColor), options("Options", small, zero, zero, itemColor),
optionsSelected("Options", selected, zero, zero, itemColor), highScores("High Scores", small, zero, zero, itemColor),
highScoresSelected("High Scores", selected, zero, zero, itemColor), credits("Credits", small, zero, zero, itemColor),
creditsSelected("Credits", selected, zero, zero, itemColor), quit("Quit", small, zero, zero, itemColor),
quitSelected("Quit", selected, zero, zero, itemColor), startIsSelected(0), levelIsSelected(0), optionsIsSelected(0), creditsIsSelected(0),
highScoresIsSelected(0), quitIsSelected(0), background(0), currentQuality(0)
{
    char *texturePath;
    if (textureQuality == LOW_QUALITY)
        texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars low.tga";
    else if (textureQuality == HIGH_QUALITY)
        texturePath = "/Space Chase.app/Contents/Resources/Textures/Stars.tga";
    char *completePath = (char *)malloc(strlen(appPath) + strlen(texturePath) + 1);
    strcpy(completePath, appPath);
    mnkyTGAInfo *tex = mnkyOpenTGA(strcat(completePath, texturePath));
    free(completePath);
    glGenTextures(1, &background);
    glBindTexture(GL_TEXTURE_2D, background);
    glTexImage2D(GL_TEXTURE_2D, 0, tex->components, tex->width, tex->height,
                 0, tex->format, GL_UNSIGNED_BYTE, tex->imageData);
    mnkyDeleteTGA(&tex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    currentQuality = textureQuality;
}

A final note: is it possibly NSApplication not being too C++ friendly? Since this did work when commenting out its main loop....

Edit x2: before anybody asks, I did "Clean all targets" and rebuilt about 3000x already.

Edit x3: I ran it through Malloc debug, and it ran perfectly. (loaded all textures and everything) Strange...................
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #2
Wow. I just found it. And it was not where I suspected. In my open TGA function, I accidentally put in the wrong thing for the size for my call to malloc (the pointer instead of the type, which have similar names). It worked all other times, purely by luck, so I didn't think that would be it. Malloc debug actually caught that for me: It printed out that I was freeing past the malloc, then I put in print statements, and then it led me to there. Wow. The symptoms certainly were weird, though...
Quote this message in a reply
Member
Posts: 161
Joined: 2005.07
Post: #3
Whenever you have random crashes, odds are its a memory problem, whether by trying to follow an uninitialized pointer, trying to access an item in an array that doesn't exist (out of bounds), having two pointers that point to the same thing then trying to delete both of them, etc.

The reason it's random is because the OS chooses a slice of RAM each time for your program to use (I think it's called the stack space?), so your faulty code was using a different section of RAM each time.
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #4
This was malloced onto the heap. I confess I don't have much experience (I just started learning how to program last year), so I didn't know that it was a sign of memory problems. Made since once I found out that was the problem. At least the laws of math and physics weren't breaking... Sneaky
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Crazy AI stuffs Coin 4 3,173 Oct 16, 2005 06:16 PM
Last Post: frozendevil
  pathfinding crashes Iceman 5 4,163 Jul 28, 2005 05:48 PM
Last Post: unknown
  My game crashes on quit... hangt5 17 8,238 Jan 30, 2005 09:38 PM
Last Post: hangt5
  My application crashes MACnus 2 2,426 Dec 31, 2004 01:35 AM
Last Post: MACnus