We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 881

Summary: Segmentation fault with Autorelease Pool Release
Product: SDL Reporter: macite
Component: *don't know*Assignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: major    
Priority: P2 CC: icculus
Version: 1.2.14   
Hardware: x86_64   
OS: Mac OS X 10.6   
Attachments: Source code to reproduce issue

Description macite 2009-11-10 04:12:56 UTC
Created attachment 447 [details]
Source code to reproduce issue

I currently develop a game library using SDL as a back end and have found some
issues with the SDL changes from 1.2.13 -> 1.2.14 for MacOS related to
AutoReleasePools. The following code will work with SDL 1.2.13, but fails (most
of the time...) in 1.2.14. The issue appears to be with the object being freed
twice.

When I create a surface using SDL_CreateRGBSurface(...) and Blit it onto the
screen in code that uses a AutoReleasePool the program terminates abnormally on
release of the pool. The code and stack trace are as follows. In this format
the error occurs on "most" executions. This appears to indicate a race
condition with the resource being freed on another thread, though I have little
knowledge of the internal workings of SDL.

int SDL_main(int argc, char **argv)
{
    NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
    SDL_Surface *screen, *surface;

    screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

    surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
                                     800, 600, 32,
                                     screen->format->Rmask, 
                                     screen->format->Gmask, 
                                     screen->format->Bmask, 
                                     0xffffffff & ~screen->format->Rmask
                                                & ~screen->format->Gmask
                                                & ~screen->format->Bmask);

    Uint32 grey = SDL_MapRGBA(screen->format, 128, 128, 128, 255);
    Uint32 green = SDL_MapRGBA(surface->format, 0, 255, 0, 255);

    SDL_FillRect(screen, nil, grey);
    SDL_Flip(screen);
    //SDL_Delay(2000);

    SDL_FillRect(surface, nil, green);
    SDL_BlitSurface(surface, nil, screen, nil);
    SDL_Flip(screen);
    //SDL_Delay(2000);

    SDL_FreeSurface(surface);

    [p release];

    SDL_Quit();

    return 0;
}

(truncated trace to remove code leading up to SDL_main)

#0  0x94b54ed7 in objc_msgSend ()
#1  0x00119001 in ?? ()
#2  0x90f0f9e6 in -[NSCGSContext _invalidate] ()
#3  0x90f0f95a in -[NSCGSContext dealloc] ()
#4  0x90f0f92b in -[NSWindowGraphicsContext dealloc] ()
#5  0x93491528 in CFRelease ()
#6  0x934be0ed in _CFAutoreleasePoolPop ()
#7  0x90c1cdd6 in NSPopAutoreleasePool ()
#8  0x90c1dc32 in -[NSAutoreleasePool release] ()
#9  0x00001e21 in SDL_main (argc=1, argv=0x109fd0) at SDLMain.m:44

The above execution was in a 64bit version. With a i386 arch the error
indicates a potential double free with a similar stack trace if a breakpoint is
set in malloc_error_break. In all cases the error does not occur on every
execution, however I have not been able to make this fail when I switch back to
the 1.2.13 framework.

Hope this all makes sense...

cheers,

Andrew.
Comment 1 Ryan C. Gordon 2011-08-23 13:49:11 UTC
This should be fixed in hg changeset 8e0dd46ad0e0.

--ryan.