Crash during SDL_UnlockSurface

I’ve been running into a problem that I think is a bug in SDL. The
situation is:

I have a surface (surface A) with SDL_SRCALPHA and SDL_RLEACCEL set. I blit
from that to surface B. (and use it for various things, never touching A).
I then free surface B. Afterwards, I do some direct manipulation of surface
A, and so I lock the surface, do my stuff, and then unlock it. During the
call to SDL_UnlockSurface, I get a crash.

It turns out that it crashes at SDL_RLEaccel.c, line 1433, which is
masksum = df->Rmask | df->Gmask | df->Bmask;

df is some junk pointer (usually null).

It looks to me like what happens is that A->map->dst gets set to B when I do
the blit, and then when B is freed that pointer is left dangling. When it
tries to access the fields of A->map->dst in RLEAlphaSurface, it crashes.

So, is this a known issue? Could someone with more knowledge of SDL
internals than me verify that this is the bug?

I’m including a short test case that illustrates the situation and behavior.
(Actually, this one doesn’t crash on my system, but Valgrind complains
loudly about reading from previously freed memory at the same point.) I
found the problem while using SDL 1.2.6; 1.2.8 seems to have the same
problem.

Thanks

Jared Minch

/* crash.c */

#include “SDL.h”

int main( int argc, char **argv )
{
SDL_Surface *screen;
SDL_Surface *s1, *s2;

/* Initialize SDL */
SDL_Init(SDL_INIT_VIDEO);

screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);

/* Create two surfaces */
s1 = SDL_CreateRGBSurface(SDL_SWSURFACE, 64, 64, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
s2 = SDL_CreateRGBSurface(SDL_SWSURFACE, 64, 64, 32,
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);

SDL_SetAlpha(s1, SDL_SRCALPHA | SDL_RLEACCEL, 0xff);

/* Blit from s1 to s2 */
SDL_BlitSurface(s1, NULL, s2, NULL);

/* Free s2 */
SDL_FreeSurface(s2);

/* Now lock and unlock s1 */
SDL_LockSurface(s1);
SDL_UnlockSurface(s1);

SDL_Quit();

return 0;
}

I’ve been running into a problem that I think is a bug in SDL. The
situation is:

I have a surface (surface A) with SDL_SRCALPHA and SDL_RLEACCEL set. I blit
from that to surface B. (and use it for various things, never touching A).
I then free surface B. Afterwards, I do some direct manipulation of surface
A, and so I lock the surface, do my stuff, and then unlock it. During the
call to SDL_UnlockSurface, I get a crash.

It turns out that it crashes at SDL_RLEaccel.c, line 1433, which is
masksum = df->Rmask | df->Gmask | df->Bmask;

Sounds like a bug to me. Can you put together a small test case and post
a link to it?

Thanks!
-Sam Lantinga, Software Engineer, Blizzard Entertainment