SDL_CreateThread address space leak

SDL_CreateThread is supposed to create a thread that upon returning ends the
thread cleanly. Instead, about 2MB of address space is not cleared up when
the function returns. This seems to be solely address space (VSZ) and not
real memory allocation. That’s at least what valgrind says. This is in
libsdl 1.2.8. I’ve no idea if the CVS fixes this bug.

Below is an example program to demonstrate leak.

To make the pthread version:

gcc -o thread_waste thread_wate.c -lpthread

To make the SDL version:

gcc -o sdl_thread_waste thread_waste.c -lSDL -DUSE_SDL

Run [sdl_]thread_waste and compare the virtual sizes. A test run
of 20 or 30 seconds should be enough time to clearly observe the phenomenon.
Just to further clarify, I’m using the Gentoo 1.2.8-r1 package of libsdl,
though I doubt that’s the issue. My CFLAGS were “-march=athlon-xp -O2” to
build libsdl, while I used the above lines solely for the test program.

Program Code--------------------

#include <unistd.h>

#ifdef USE_SDL
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#else
#include <pthread.h>
#endif

int zero = 0;

// Thread that immediately exits.
#ifdef USE_SDL
int waste_thread(void *unused attribute ((unused)))
#else
void *waste_thread()
#endif
{
//Do nothing.
#ifdef USE_SDL
return 0;
#else
pthread_exit(&zero);
#endif
}

int usage(char *name)
{
printf(“Usage: %s <time_to_run>\n”, name);
return 1;
}

int main(int argc, char *argv[])
{
int time, i;
#ifndef USE_SDL
pthread_attr_t attr;
pthread_t child;
#endif

if (argc != 2)
return usage(argv[0]);

time = atoi(argv[1]);

if (time < 1)
return usage(argv[0]);

for (i = 0; i < time; i++) {

#ifdef USE_SDL
SDL_CreateThread(waste_thread, NULL);
#else
pthread_attr_init(&attr);
// Make it detached.
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// // And one-to-one with kernel threads.
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&child, &attr, waste_thread, NULL);
#endif
// Sleep a second.
sleep(1);
}
return 0;
}

SDL_CreateThread is supposed to create a thread that upon returning ends the
thread cleanly. Instead, about 2MB of address space is not cleared up when
the function returns. This seems to be solely address space (VSZ) and not
real memory allocation. That’s at least what valgrind says. This is in
libsdl 1.2.8. I’ve no idea if the CVS fixes this bug.

Below is an example program to demonstrate leak.

To make the pthread version:

gcc -o thread_waste thread_wate.c -lpthread

To make the SDL version:

gcc -o sdl_thread_waste thread_waste.c -lSDL -DUSE_SDL

Run [sdl_]thread_waste and compare the virtual sizes. A test
run
of 20 or 30 seconds should be enough time to clearly observe the phenomenon.
Just to further clarify, I’m using the Gentoo 1.2.8-r1 package of libsdl,
though I doubt that’s the issue. My CFLAGS were “-march=athlon-xp -O2” to
build libsdl, while I used the above lines solely for the test program.

Program Code--------------------

#include <unistd.h>

#ifdef USE_SDL
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#else
#include <pthread.h>
#endif

int zero = 0;

// Thread that immediately exits.
#ifdef USE_SDL
int waste_thread(void *unused attribute ((unused)))
#else
void *waste_thread()
#endif
{
//Do nothing.
#ifdef USE_SDL
return 0;
#else
pthread_exit(&zero);
#endif
}

int usage(char *name)
{
printf(“Usage: %s <time_to_run>\n”, name);
return 1;
}

int main(int argc, char *argv[])
{
int time, i;
#ifndef USE_SDL
pthread_attr_t attr;
pthread_t child;
#endif

if (argc != 2)
    return usage(argv[0]);

time = atoi(argv[1]);

if (time < 1)
    return usage(argv[0]);

for (i = 0; i < time; i++) {

#ifdef USE_SDL
SDL_CreateThread(waste_thread, NULL);
#else
pthread_attr_init(&attr);
// Make it detached.
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// // And one-to-one with kernel threads.
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&child, &attr, waste_thread, NULL);
#endif
// Sleep a second.
sleep(1);
}
return 0;
}

#ifdef USE_SDL
SDL_CreateThread(waste_thread, NULL);
#else
pthread_attr_init(&attr);
// Make it detached.
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

SDL threads aren’t detached.

You need to call SDL_WaitThread() to clean it up when it’s done. If you
don’t, valgrind is correct that you are leaking memory, as this thread
is a zombie process under linux waiting to be collected.

–ryan.