While converting some SDL2 code to c from
Lazy Foo 's c++ tutorials I came across a rather odd problem and am rather curious as to the reason for it.
gcc-4.7.1_multilib-x86_64-1alien
glibc-2.15_multilib-x86_64-8alien
Code:
void close(void)
{
SDL_FreeSurface(img);
SDL_DestroyWindow(window);
SDL_Quit();
}
/* If these lines of code are in a separate function, such as close(), rather than in main(),
* the program goes into an infinite loop, or freezes to which gdb
* gives the following after breaking from it.
*
* 0x00007ffff77fc270 in __read_nocancel () from /lib64/libc.so.6
*
* However, if I place the three lines at the end of the main()
* replacing the call to close() there's no problem and the
* examples run smoothly.
*/
int main(int argc, char **argv)
{
\*
*
* Writing it this way works just fine.
*
*\
SDL_FreeSurface(img);
SDL_DestroyWindow(window);
SDL_Quit();
return(0);
}
Anyway, I've solved it, so that's not my question. I just want to understand why things like this happen, because I've come across several weird oddities that I just can't figure out why.
Anyway, thanks for any help.
<Edit>
Well, while going through the assembly in gdb, and reviewing the code once again. I see the hang happens with the call to SDL_Init, for some such reason. From what little I can gather, it's either a compiler problem with gcc, or a libc problem.
Alrighty, a second test, I removed close() from within the single source file and wrote it in a separate file. Compiled both to objects, then linked them. Set a breakpoint for the function closs() and lo and behold, the program somehow skips out of the init() function at the call to SDL_Init and goes directly to the close() function.
Code:
#0 close (win=0xe, im=0x2) at close.c:9
#1 0x00007ffff68a39fe in xcb_disconnect () from /usr/lib64/libxcb.so.1
#2 0x00007ffff6ad7827 in XCloseDisplay () from /usr/lib64/libX11.so.6
#3 0x00007ffff7b9020f in ?? () from /usr/lib64/libSDL2-2.0.so.0
#4 0x00007ffff7b81983 in ?? () from /usr/lib64/libSDL2-2.0.so.0
#5 0x00007ffff7aea58f in ?? () from /usr/lib64/libSDL2-2.0.so.0
#6 0x0000000000400c34 in init () at 05-optimize.c:35
#7 0x0000000000400e33 in main (argc=1, argv=0x7fffffffdff8) at 05-optimize.c:121
And in the other program where it's all in one source,same thing.
And when I move the function to the beginning of the file,
Code:
#0 0x00007ffff77fc270 in __read_nocancel () from /lib64/libc.so.6
#1 0x00007ffff502f465 in ?? () from /usr/lib64/libdbus-1.so.3
#2 0x00007ffff5030289 in ?? () from /usr/lib64/libdbus-1.so.3
#3 0x00007ffff5031da2 in ?? () from /usr/lib64/libdbus-1.so.3
#4 0x00007ffff5027564 in ?? () from /usr/lib64/libdbus-1.so.3
#5 0x00007ffff5027405 in ?? () from /usr/lib64/libdbus-1.so.3
#6 0x00007ffff501234b in ?? () from /usr/lib64/libdbus-1.so.3
#7 0x00007ffff500ed88 in ?? () from /usr/lib64/libdbus-1.so.3
#8 0x00007ffff7b94e52 in ?? () from /usr/lib64/libSDL2-2.0.so.0
#9 0x00007ffff7b908fd in ?? () from /usr/lib64/libSDL2-2.0.so.0
#10 0x00007ffff7b817e1 in ?? () from /usr/lib64/libSDL2-2.0.so.0
#11 0x00007ffff7aea58f in ?? () from /usr/lib64/libSDL2-2.0.so.0
#12 0x0000000000400c5d in init () at 05-optimize.c:42
#13 0x0000000000400e5c in main (argc=1, argv=0x7fffffffdff8) at 05-optimize.c:121
Woops, it's getting late. Either way, interesting. Still have no idea what's going on, meh, I'll figure it out.
Just for completion's sake. The working code only shows this when I break at the first call to SDL_FreeSurface, SDL_DestroyWindow, or SDL_Quit (Doesn't matter which one I put in a function, all hang the same).
Code:
#0 main (argc=1, argv=0x7fffffffdff8) at 05-optimize.c:124
And the full code.
Code:
#include <stdio.h>
#include <SDL2/SDL.h>
#include <string.h>
SDL_Surface *window = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *img = NULL;
//SDL_Surface *stretchedimg = NULL;
enum USE_SDL_GETERROR
{
USE_GETERROR,
NOUSE_GETERROR
};
void pError(char *msg, int userr)
{
if(userr == USE_GETERROR)
printf(msg, SDL_GetError());
else
printf(msg);
}
int init(void)
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
pError("SDL could not initialize! error: %s\n", USE_GETERROR);
return(1);
} else {
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN);
if(window == NULL)
{
pError("Window could not be created! error: %s\n", USE_GETERROR);
return(1);
} else {
screen = SDL_GetWindowSurface(window);
}
}
return(0);
}
SDL_Surface *loadSurface(char *imgfile)
{
SDL_Surface *optimizedSurface = NULL;
SDL_Surface *loadedimg = SDL_LoadBMP(imgfile);
if(loadedimg == NULL)
{
pError("Unable to load image! error: %s\n", USE_GETERROR);
} else {
optimizedSurface = SDL_ConvertSurface(loadedimg, screen->format, NULL);
if(optimizedSurface == NULL)
{
pError("Unable to optimize image! error: %s\n", USE_GETERROR);
}
SDL_FreeSurface(loadedimg);
}
return(optimizedSurface);
}
int loadimg(char *imgfile)
{
img = loadSurface(imgfile);
if(img == NULL)
{
pError("Failed to load image!\n", NOUSE_GETERROR);
return(1);
}
return(0);
}
void run(void)
{
SDL_Event e;
while(1)
{
while(SDL_PollEvent(&e) != 0)
{
if((e.type == SDL_QUIT) || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE))
return;
}
SDL_Rect stretchRect;
stretchRect.x = 0;
stretchRect.y = 0;
stretchRect.w = 640;
stretchRect.h = 480;
SDL_BlitScaled(img, NULL, screen, &stretchRect);
SDL_UpdateWindowSurface(window);
}
}
#ifdef __USE_CLOSE
// This causes the hang.
void close(void)
{
SDL_FreeSurface(img);
SDL_DestroyWindow(window);
SDL_Quit();
}
#endif
int main(int argc, char **argv)
{
if(init() == 1)
{
printf("Failed to initialize!\n");
} else {
if(loadimg("stretch.bmp") == 1)
{
printf("Failed to load image!\n");
} else {
run();
}
}
#ifdef __USE_CLOSE
close(); // This is the other part that causes the hang.
#else
SDL_FreeSurface(img); // These three lines compile and run just fine.
SDL_DestroyWindow(window);
SDL_Quit();
#endif
return(0);
}
Pshhhh! I'll figure it out...