SDL_Quit() causes SIGBUS error - c

The following basic SDL2 code taken from a tutorial website is causing some strange trouble :
#include <SDL2/SDL.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define SCREENH 768
#define SCREENW 1366
SDL_Window *window = NULL;
SDL_Surface *screenSurface = NULL;
SDL_Surface *windowSurface = NULL;
int init_SDL() {
int success = 0;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL could not initialize! ");
printf("SDL_Error: %s\n",SDL_GetError());
success = -1;
}
else {
window = SDL_CreateWindow("SDL2_Tutorial02",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,SCREENW,SCREENH,SDL_WINDOW_SHOWN);
if(window == NULL) {
printf("Window could not be created! ");
printf("SDL Error: %s\n",SDL_GetError());
}
else {
screenSurface = SDL_GetWindowSurface(window);
}
}
return success;
}
int loadMedia() {
int success = 0;
windowSurface = SDL_LoadBMP("Images/Hallo.bmp");
if(windowSurface == NULL) {
printf("Unable to load image! ");
printf("SDL Error: %s\n",SDL_GetError());
success = -1;
}
return success;
}
void close() {
SDL_FreeSurface(windowSurface);
windowSurface = NULL;
SDL_DestroyWindow(window);
window = NULL;
SDL_Quit();
}
int main(int argc,char *argv[]) {
assert(init_SDL() == 0);
assert(loadMedia() == 0);
SDL_BlitSurface(windowSurface,NULL,screenSurface,NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(3000);
close();
exit(EXIT_SUCCESS);
}
As soon as SDL_Quit(), placed in close(), is invoked I receive a memory access error. Using GDB the following is revealed:
49 SDL_Quit();
(gdb) n
Program received signal SIGBUS, Bus error.
0x00007ffff68a5895 in ?? () from /usr/lib/x86_64-linux-gnu/libX11.so.6
(gdb)
The strange about that is when I place SDL_Quit() outside of close() like this:
void close() {
SDL_FreeSurface(windowSurface);
windowSurface = NULL;
SDL_DestroyWindow(window);
window = NULL;
}
int main(int argc,char *argv[]) {
assert(init_SDL() == 0);
assert(loadMedia() == 0);
SDL_BlitSurface(windowSurface,NULL,screenSurface,NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(3000);
close();
SDL_Quit();
exit(EXIT_SUCCESS);
}
all things are fine. SDL_Quit() works without error. Why does it cause a SIGBUS Error when I invoke SDL_Quit() in another function ?
EDIT: This code was compiled on ubuntu 14.04 with gcc and the following compile command
gcc -g3 -o tutorial tutorial.c `sdl2-config --cflags --libs`

Your function close() is in conflict with an internal SDL function with the same name causing weird behavior (actually, it is the libc standard close() syscall called by SDL).
Rename your function and it should be fine.

Related

SDL_Window does not display after build/compilation, Ubuntu 20.04

Currently using SDL2, and attempting to output a basic SDL Window (Ubuntu 20.04) with the C programming language. Program runs, window does not display.
Would like to preface that I've gotten the SDL_Window to show up once before, but (possibly unrelated) after the successful integration of SDL2_gfx, there seems to be issues with the window displaying.
I've run the code both on the Eclipse IDE and in the main linux command line, same error persists, with both a clean build, and a successful compilation, but the window does not show on the screen.
See code below.
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
int main(int argc, char **argv) {
SDL_Window *window;
if(SDL_Init(SDL_INIT_VIDEO) < 0){
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
return 1;
}
window = SDL_CreateWindow("SDL Example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_ALLOW_HIGHDPI);
if(window == NULL){
printf("SDL window failed to initialize: %s\n", SDL_GetError());
return 1;
}
SDL_Event e;
int quit = 0;
while(quit == 0){
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
quit = 1;
}
if(e.type == SDL_KEYDOWN){
quit = 1;
}
if(e.type == SDL_MOUSEBUTTONDOWN){
quit = 1;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
Few points/disclaimers: This question has been asked by MacOS users, some suggestions include putting in
if(SDL_Init(SDL_INIT_EVERYTHING) < 0)...
vs
if(SDL_Init(SDL_INIT_VIDEO) < 0)....
This has been attempted but I do not have audio support configured for SDL
Also....
SDL_WINDOW_ALLOW_HIGHDPI
Has been changed to various flags, and this has been unsuccessful.
Any advice/suggestions/solutions?

Why isn't my image displaying using SDL2?

I just started coding a game using SDL2 in C, but I quickly ran into a problem : my images are not displayed on the window. I already made the following checks:
the window and the renderer are successfully created
my .bmp files are correctly loaded
the SDL_RenderCopy() function is called, and returns no error
the SDL_RenderPresent() function is called and returns no error
I'm not trying to display my images on a 0x0px surface
my image is a .bmp file
Here is some code, I hope this will help (I'm sorry it's quite disorganized):
Edit: I simplified the showed code
TrapAdventures.c (main file):
#include <SDL2/SDL.h>
#include <stdio.h>
#include "HobbesSDL.h"
#include "TrapInit.h"
#include "TrapKeyboard.h"
#define Ellipsis (return 0)
#define Pass ((void)0)
#define NullKeycode ((SDL_Keycode)0)
int main(void){
HobbesBool TrapRunning = HOBBES_TRUE;
HobbesWindow *TrapWindow;
HobbesRenderer *TrapRenderer;
if (TrapInitContext("Trap adventures", &TrapWindow, &TrapRenderer) != 0){
TrapRunning = HOBBES_FALSE;
}
HobbesSprite *TrapPlayer;
if (TrapInitSprite(&TrapPlayer, TrapRenderer) != 0)
TrapRunning = HOBBES_FALSE;
while (TrapRunning){
if (TrapGetKeyState(TrapKeySpace))//Quit program if spacebar is pressed
TrapRunning = HOBBES_FALSE;
SDL_RenderClear(TrapRenderer);
if (HobbesDisplaySprite(TrapPlayer) != 0){
printf("Error while displaying player!\n");
TrapRunning = HOBBES_FALSE;
}
SDL_RenderPresent(TrapRenderer);
SDL_Delay(50);
}
HobbesDestroySprite(TrapPlayer);
SDL_DestroyRenderer(TrapRenderer);
SDL_DestroyWindow(TrapWindow);
HobbesQuit();
printf("End!\n");
return 0;
}
The HobbesSprite type defined in HobbesSDL.h (my own (and small) library, using SDL2):
typedef struct HobbesSprite {
SDL_Renderer *renderer;
SDL_Surface *surface;
SDL_Texture *texture;
HobbesRect *rect;
HobbesHitbox *hitbox;
HobbesBool hidden;
} HobbesSprite;
Some of the functions in HobbesSDL.c that I use in this code:
#include <SDL2/SDL.h>
#include "HobbesSDL.h"
#include <errno.h>
int HobbesInit(void){
int ret = SDL_Init(SDL_INIT_VIDEO);
if (ret != 0)
fprintf(stderr, "Error while initializing SDL2: %s", SDL_GetError());
return ret;
}
int HobbesDisplaySprite(HobbesSprite *sprite){
if (SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, (SDL_Rect *)sprite->rect) != 0 && !sprite->hidden){
fprintf(stderr, "Error while displaying sprite: %s\n", SDL_GetError());
fclose(stderr);
return -1;
}
return 0;
}
void HobbesUpdateWindow(HobbesRenderer *renderer){
SDL_RenderPresent(renderer);
}
TrapInit.c:
#include <SDL2/SDL.h>
#include "HobbesSDL.h"
#include "TrapInit.h"
/*These first four functions will be used to initialize the rendering context*/
int TrapInitSDL(){
return HobbesInit();
}
HobbesWindow *TrapInitWindow(const char name[]){
SDL_Window *window = SDL_CreateWindow(name, 0, 0, 1000, 1000, 0);
if (window == NULL){
fprintf(stderr, "Error while creating window: %s\n", SDL_GetError());
}
return window;
}
HobbesRenderer *TrapInitRenderer(HobbesWindow *window){
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL){
fprintf(stderr, "Error while creating renderer: %s\n", SDL_GetError());
}
return renderer;
}
int TrapInitContext(const char name[], HobbesWindow **wptr, HobbesRenderer **rptr){
//Initializes the rendering context using the above functions
int InitSDLResult = TrapInitSDL();
*wptr = TrapInitWindow(name);
*rptr = TrapInitRenderer(*wptr);
if (InitSDLResult != 0 || *wptr == NULL || *rptr == NULL)
return 1;
return 0;
}
/*The following function will be used to create every sprite needed in the game*/
int TrapInitSprite(HobbesSprite **Player, HobbesRenderer *renderer){
*Player = HobbesCreateSprite(renderer, "Images/Player.bmp", 0, 724);
if (*Player == NULL)
return 1;
return 0;
}
(I'm sorry that my code is so unclear, but I do my best :) )
My OS is MacOS Big Sur 11.6.4, my graphic card Intel Iris Pro Graphics 6200 1536 Mo, my processor is a 3,3 GHz Intel Core i7 four cores.
Finally, even thought I use the gcc command to compile, my compiler is clang (Apple made the choice to use clang by default, but the command is still gcc…).
If you need any other information, just ask in the comments and I'll answer you the best I can.
Do you have any ideas?
I did a lot of tests, and finally found the problem.
The problem was that I tried to convert a HobbesRect * to a SDL_Rect *, but I did it wrong. If you look at the code of HobbesDisplaySprite, I do something like this:
SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, (SDL_Rect *)sprite->rect) //(SDL_Rect *)sprite->rect is the problem
I solved my problem using a far more explicit conversion:
SDL_RenderCopy(sprite->renderer, sprite->texture, NULL, &((SDL_Rect){sprite->rect->x, sprite->rect->y, sprite->rect->w, sprite->rect->h}))
Thank you all for your interest in my problem! I'll try to put less code in my question next time ;) !

SDL2 compiles but doen't open window

I am trying to setup a SDL2 project on Eclipse on Mac.
I tried the following code and I have no errors reported. However, the window does not open but the icon of a "ghost" program that opens.
The "ghost" program:
#include <stdio.h>
#include <SDL2/SDL.h>
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_VIDEO) != 0 )
{
fprintf(stdout,"Failed to initialize the SDL (%s)\n",SDL_GetError());
return -1;
}
{
SDL_Window* pWindow = NULL;
pWindow = SDL_CreateWindow("My first SDL2 application",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
SDL_WINDOW_SHOWN);
if( pWindow )
{
SDL_Delay(3000);
SDL_DestroyWindow(pWindow);
}
else
{
fprintf(stderr,"Error creating the window: %s\n",SDL_GetError());
}
}
SDL_Quit();
return 0;
}
SDL overwrites the main but it expects main to be declared as
int main(int argc, char* argv[])
if you declare it as char** instead of char* argv[], the template will not be picked up.
The delay won't do very much: all you will get is a title and a frame. Change the SDL_Delay to an event handler like this
bool running = true;
while (running)
{
SDL_Event e;
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
running = false;
break;
}
}
}
You can then drag the window around. It will contain the the background.

Strange segfault from SDL_FreeSurface

I have the following simple SDL code:
#include <SDL.h>
#include <stdbool.h>
#include <stdio.h>
// helpers
bool init(SDL_Window **win, SDL_Surface **surf) {
int const width = 800;
int const height = 600;
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
return false;
}
*win = SDL_CreateWindow("Picture test",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
width, height, 0);
if (*win == NULL) {
fprintf(stderr,
"Unable to create window: %s\n",
SDL_GetError());
return false;
}
*surf = SDL_GetWindowSurface(*win);
return true;
}
bool load_media(SDL_Surface **surf) {
*surf = SDL_LoadBMP("./sample.bmp");
if (*surf == NULL) {
fprintf(stderr, "Unable to load data: %s\n", SDL_GetError());
return false;
}
return true;
}
void close(SDL_Window **win, SDL_Surface **surf) {
SDL_FreeSurface(*surf);
SDL_DestroyWindow(*win);
SDL_Quit();
}
int main()
{
SDL_Window *win;
SDL_Surface *surf;
SDL_Surface *img;
if (!init(&win, &surf)) {
return EXIT_FAILURE;
}
if (!load_media(&img)) {
return EXIT_FAILURE;
}
SDL_BlitSurface(img, NULL, surf, NULL);
SDL_UpdateWindowSurface(win);
SDL_Delay(2000);
close(&win, &img);
}
My code always segfaults on close (the origin of the segfault according to GDB is the line SDL_FreeSurface(*surf)). More strangely, if I replace the call to close with its definition, this still segfaults in exactly the same place. Specifically, if I replace close(&win, &img) with:
SDL_FreeSurface(img);
SDL_DestroyWindow(win);
SDL_Quit();
the code still segfaults at exactly the same place, even though that function is not even being called. Only if I remove the entire close function does this work correctly. I am completely confused as to what could be causing this.
Please rename your function
void close(SDL_Window **win, SDL_Surface **surf)
since close is a standard C library function.
I can confirm this. Same scenario. Even with -Wall and -Wextra the compiler did not spit out a redeclaration warning. Same for open().
I need an experts' opinion if this is a gcc bug.
Solution 1: declare your close() as a static function (e.g. static close()).
Solution 2: rename your close() function to something else (e.g. my_close_foo()).

Use root X11 window as the main SDL2 window

I'm trying to make SDL2 use the root X window to display things, but it doesn't seem to work - the window doesn't get changed in any way. Also, the whole program doesn't quit after the SDL_Delay() for some reason. Is it not possible? Am I doing something wrong?
#include <SDL.h>
#include <X11/Xlib.h>
#include <stdio.h>
// clang -lSDL2 -lX11 -I/usr/include/SDL2 -Weverything x11.c -o x11
int main(void)
{
Display *x11_d;
int x11_s;
Window x11_w;
SDL_Window *w;
SDL_Renderer *r;
x11_d = XOpenDisplay(NULL);
if(!x11_d) {
fprintf(stderr, "couldn't open display\n");
return 1;
}
x11_s = DefaultScreen(x11_d);
x11_w = RootWindow(x11_d, x11_s);
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
fprintf(stderr, "couldn't initialize SDL: %s\n", SDL_GetError());
return 1;
}
w = SDL_CreateWindowFrom((void *)x11_w);
XCloseDisplay(x11_d);
if(!w) {
fprintf(stderr, "couldn't attach to the root X11 window: %s\n", SDL_GetError());
return 1;
}
r = SDL_CreateRenderer(w, -1, 0);
SDL_SetRenderDrawColor(r, 255, 0, 0, 255);
SDL_RenderClear(r);
SDL_RenderPresent(r);
SDL_Delay(5700);
SDL_Quit();
return 0;
}
You're closing the X Display right after you create the SDL window, so you lose the connection. That obviously isn't helping but you also left out about 95% of the code required to get X working. Tutorial here.

Resources