Hang in SDL_Init

Hello SDL developers–

I have turned up a hang in SDL_Init that has me completely
baffled. Below is a test program that reproduces the
problem. I’m hoping someone can help point me in the right
direction.

I am using SDL inside another X windows program, so I
communicate with the SDL back-end by setting the SDL_WINDOWID
and SDL_VIDEO_X11_VISUALID environment variables. Because
of other constraints in my program, I also call XInitThreads.

I am running on Linux Red Hat 8.0 with Xv support and XFree86
4.2.0, and using SDL version 1.2.

The program below is saved as the file “sdlhang.c” and
compiled as follows:

gcc -g -O2 -c sdlhang.c

g++ -g -O2 sdlhang.o -o sdlhang -rdynamic
/usr/local/vbrick/lib/libSDL-1.2.so.0 -lpthread -L/usr/X11R6/lib -lXext -lX1
1 -lm -lz

(note that my SDL is installed into /usr/local/vbrick/lib/)

After compiling sdlhang, I run the following shell script:

#!/bin/sh

iter=0

while /bin/true ; do
./sdlhang

iter=`echo $iter + 1 | bc -q`
echo "Completed iteration $iter"

done

After some number of iterations – sometimes over several
hundred, but usually before 50 iterations – the test program
will hang with a backtrace similar to the following:

(gdb) bt
#0 0x42028d69 in sigsuspend () from /lib/i686/libc.so.6
#1 0x400a8108 in __pthread_wait_for_restart_signal ()
from /lib/i686/libpthread.so.0
#2 0x400aa480 in __pthread_alt_lock () from /lib/i686/libpthread.so.0
#3 0x400a6f87 in pthread_mutex_lock () from /lib/i686/libpthread.so.0
#4 0x40321faa in _XUnregisterFilter () from /usr/X11R6/lib/libX11.so.6
#5 0x403030de in XGetVisualInfo () from /usr/X11R6/lib/libX11.so.6
#6 0x40047ff4 in add_visual_byid (this=0x8058a00, visual_id=0x8053837 “35”)
at SDL_x11modes.c:267
#7 0x4004811e in X11_GetVideoModes (this=0x8058a00) at SDL_x11modes.c:485
#8 0x40049e64 in X11_VideoInit (this=0x8058a00, vformat=0xbffff660)
at SDL_x11video.c:432
#9 0x40040014 in SDL_VideoInit (driver_name=0x0, flags=0) at
SDL_video.c:236
#10 0x4001e5bb in SDL_InitSubSystem (flags=1048624) at SDL.c:71
#11 0x4001e5fa in SDL_Init (flags=1048624) at SDL.c:163
#12 0x0804a405 in main (argc=1, argv=0xbffff824) at sdlhang.c:136
#13 0x420158d4 in __libc_start_main () from /lib/i686/libc.so.6

The problem goes away if I comment out the call to XInitThreads,
but unfortunately this isn’t a solution for me, since I need
this elsewhere in my application.

Any help would be appreciated. Thanks very much.

–Howdy=============================
Howdy Pierce
Managing Partner
Cardinal Peak, LLC

email: howdy -at- cardinalpeak.com

Here is the sdlhang.c code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#include “…/…/mpeg4ip/lib/SDL/include/SDL.h”

typedef struct pwcntl_s {

Display *display;
int screen;
Window parent;
Drawable d;

Visual *visual;
int depth;

unsigned long bg_color;

/* current window coordinates */
int cur_x;
int cur_y;
int cur_w;
int cur_h;

} pwcntl_t;

int main (int argc, char **argv)
{
pwcntl_t *pwcntl;
XEvent xev;
XVisualInfo vi;
XSetWindowAttributes attr;
static char windowid[1024];
static char visualid[1024];

pwcntl = (pwcntl_t *) malloc(sizeof(pwcntl_t));
assert(pwcntl != NULL);

pwcntl->display = XOpenDisplay(NULL);
if(NULL == pwcntl->display) {
printf(“Cannot open X display\n”);
exit(1);
}

XInitThreads();

XLockDisplay(pwcntl->display);
pwcntl->screen = DefaultScreen(pwcntl->display);

if(XMatchVisualInfo(pwcntl->display, pwcntl->screen,
16, TrueColor, &vi)) {
pwcntl->depth = 16;
pwcntl->visual = vi.visual;
} else if(XMatchVisualInfo(pwcntl->display, pwcntl->screen,
15, TrueColor, &vi)) {
pwcntl->depth = 15;
pwcntl->visual = vi.visual;
} else if(XMatchVisualInfo(pwcntl->display, pwcntl->screen,
24, TrueColor, &vi)) {
pwcntl->depth = 24;
pwcntl->visual = vi.visual;
} else if(XMatchVisualInfo(pwcntl->display, pwcntl->screen,
32, TrueColor, &vi)) {
pwcntl->depth = 32;
pwcntl->visual = vi.visual;
} else if(XMatchVisualInfo(pwcntl->display, pwcntl->screen,
8, TrueColor, &vi)) {
printf(“Sorry, do not support 8-bit color depth\n”);
XUnlockDisplay(pwcntl->display);
exit(1);
} else {
printf(“No matching TrueColor visuals found!\n”);
XUnlockDisplay(pwcntl->display);
exit(1);
}

printf(“Selected visual with depth %d\n”, pwcntl->depth);

pwcntl->cur_x = 10;
pwcntl->cur_y = 10;
pwcntl->parent = RootWindow(pwcntl->display, pwcntl->screen);

pwcntl->cur_w = 352;
pwcntl->cur_h = 264 + 135;

pwcntl->bg_color = BlackPixel(pwcntl->display, pwcntl->screen);

attr.background_pixel = pwcntl->bg_color;
attr.border_pixel = attr.background_pixel;

/* create & map the window */
pwcntl->d = XCreateWindow(pwcntl->display, pwcntl->parent,
pwcntl->cur_x, pwcntl->cur_y,
pwcntl->cur_w, pwcntl->cur_h, 0,
pwcntl->depth, InputOutput, pwcntl->visual,
CWBackPixel | CWBorderPixel, &attr);

XMapRaised (pwcntl->display, pwcntl->d);

XSelectInput(pwcntl->display, pwcntl->d, StructureNotifyMask);

while(1) {
XWindowEvent(pwcntl->display, pwcntl->d, StructureNotifyMask, &xev);
if (xev.type == MapNotify)
break;
}

XUnlockDisplay(pwcntl->display);

/* now SDL_Init */
snprintf(windowid, sizeof(windowid), “SDL_WINDOWID=%d”, (int) pwcntl->d);
putenv(windowid);
printf(“set env var: %s\n”, windowid);

snprintf(visualid, sizeof(visualid), “SDL_VIDEO_X11_VISUALID=%d”,
(int) XVisualIDFromVisual(pwcntl->visual));
putenv(visualid);
printf(“set env var: %s\n”, visualid);

SDL_Init (SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);

/* if got to here, we’re ok */
printf(“SUCCESS!!!\n”);

exit(0);
}