Thread: SDL code generating Segmentation fault

  1. #1
    Registered User
    Join Date
    Mar 2014
    Posts
    14

    SDL code generating Segmentation fault

    I picked up on SDL not long ago and its going pretty slow so far. Here is the code in c of tutorial 3 from the lazyfoo guide. The 2 problems I am having with my code is that I am always getting a segmentation fault at the end of the execution of the code, which I dont really understand why. And seconly, my even handling is obviously borked since it is not responding to the closing of the window.

    What am I doing wrong? I have to work this kink out before I move on to more advanced tutorials but I am pretty clueless whats going wrong. It is the code between line 31-52 that are handling the events for reference.

    Code:
    #include <SDL2/SDL.h>
    
    
    
    //Forward declerations of functions.
    int init(const char* title, int xpos, int ypos, int height, int width, int flags);
    void close();
    int loadmedia();
    
    
    //Image screens
    SDL_Window* Window = NULL;
    SDL_Surface* ScreenSurface = NULL;
    SDL_Surface* XOut = NULL;
    
    
    int main(int argc, char* args[])
    {
        const int SCREEN_HEIGHT = 640;
        const int SCREEN_WIDTH = 480;
        int running = 0;
    
    
        if(init("ATTACK!", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_HEIGHT, SCREEN_WIDTH, SDL_WINDOW_SHOWN) == 0)
        {
            printf("SDL Failed: %s.\n", SDL_GetError());
            return 1; //Something went wrong
        }
        else
        {
            if(loadmedia() == 1)
            {
                //Main loop flag
                int quit = 0;
    
    
                //Event variable
                SDL_Event event;
    
    
                //While application is running
                while( quit == 0 )
                {
                    //Handle events on queue
                    while( SDL_PollEvent( &event ) != 0 )
                    {
                        //User requests quit
                        if( event.type == SDL_QUIT )
                        {
                            quit = 1;
                        }
                    }
    
    
                //Apply the image
                SDL_BlitSurface( XOut, NULL, ScreenSurface, NULL );
    
    
                //Update the surface
                SDL_UpdateWindowSurface( Window );
                }
    
    
            }
            else
            {
                //Image application failed.
                printf("Image could be loaded: %s", SDL_GetError());
            }
        }
    
    
        //Exit SDL
        close();
    
    
        return 0;
    }
    
    
    int init(const char* title, int xpos, int ypos, int height, int width, int flags)
    {
        int success = 1;
        if(SDL_Init(SDL_INIT_VIDEO) == 0)
        {
            //If SDL_Init succeeded.
            Window = SDL_CreateWindow(title, xpos, ypos, height, width, flags);
    
    
            if(Window == NULL)
            {
                //Window creation failed!
                printf("Window could not be created: %s", SDL_GetError());
                success = 0;;
    
    
            }
            else
            {
                printf("Window succeded\n");
                ScreenSurface = SDL_GetWindowSurface(Window);
            }
    
    
    
    
        }
        else
        {
            //If SDL_Init failed!
            printf("SDL init failed with error: %s", SDL_GetError());
            success = 0;
        }
    
    
        return success;
    }
    
    
    
    
    int loadmedia()
    {
        //Loading success flag
        int success = 1;
    
    
        //Load splash image
        XOut = SDL_LoadBMP( "image.bmp" );
        if( XOut == NULL )
        {
            printf( "Unable to load image %s! SDL Error: %s\n", "image.bmp", SDL_GetError() );
            success = 0;
        }
    
    
        return success;
    }
    
    
    void close()
    {
        //Deallocate surface from SDL_LoadBMP
        SDL_FreeSurface( XOut );
        XOut = NULL;
    
    
        //Destroy window
        SDL_DestroyWindow( Window );
        Window = NULL;
    
    
        //Quit SDL subsystems
        SDL_Quit();
    }
    Last edited by Kotik; 04-15-2014 at 06:15 AM.

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I used to be an expert in SDL 1.2 but I haven't touched SDL 2 yet, so I thought I'd take a look at your code. It was very puzzling, I have to say. You're getting SIGBUS or SIGSEGV whenever SDL_Quit() is called, and in the meantime SDL_Event() is not returning anything, for any type of event. (This is easy to see, just print a message right before/after SDL_Quit() and inside the event loop.) Yet your code is very similar to the lazy foo example that does work.

    And you're not the only one with this problem: dsource.org - forums

    But the solution (in your case) turns out to be pretty bizarre. It's your function named close(). Somewhere deep inside SDL (or more likely the new X/Wayland stuff) there is a dependency on a function of the same name; if I install SDL 2 debugging info (libsdl2-dbg) I can see a dependency on
    Code:
    close@@GLIBC_2.2.5
    Well, that's just the standard close() syscall inside libc (man 2 close). And your close is overriding it. SDL is opening and closing file descriptors repeatedly as it opens a window (95 times actually), but when it tries to close() a file descriptor, it actually calls your close function (and SDL_Quit!).

    So the solution is just to rename your close function to something else; I used my_close. Amusingly, compiling your code as C++ also causes it to work, because C++ will mangle the function name into _Z7__closev, which doesn't conflict with the built-in close. The take-away from this is to be careful not to use built-in function names. But you can't always know what those are, so try to always have a known good version of your program. Make small changes, compile, and test. When it breaks, you can ask yourself, what did I just introduce?
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Some other comments about your code in general:
    • init() is a fairly common name as well, you may want to change that just to be safe.
    • Standard name for main()'s parameters are argc, and argv.
    • You should get in the habit of thinking of coordinates as X first, Y second. This means width first, height second. The rest of the world thinks this way, and if you get into the habit of thinking (height,width) it's very hard to change later. Trust me on this.
    • Your indentation is pretty good in general but be careful inside the while(quit==0) loop. Also, you are indenting your code more and more with if/else statements. Eventually it will get unwieldy. Remember you don't need an else when the if branch has a return; and if it gets too deep, keep breaking the code into functions.
    • Similarly, you sometimes have the successful branch first, and sometimes the failure case first. It's useful to adopt a consistent style here. For example, you might check all error conditions at the beginning and return from the function if they occur, and then just have the successful code at the end. It doesn't matter much what you do but you may find the consistency helpful.

    Have fun with SDL!
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Mar 2014
    Posts
    14
    Thanks a ton dwks. You are right about my error checking. I do have alot of room for improvment with my indentation.

    That did indeed fix my issue. I'll take that as a lesson to keep my function names more unique. I would never have come to that conclusion on my own.

  5. #5
    Registered User
    Join Date
    Nov 2013
    Posts
    107
    Quote Originally Posted by Kotik View Post
    Thanks a ton dwks. You are right about my error checking. I do have alot of room for improvment with my indentation.

    That did indeed fix my issue. I'll take that as a lesson to keep my function names more unique. I would never have come to that conclusion on my own.

    What IDE are you using, there are auto formatters in both VS (inclduing EE) and Code:Blocks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. segmentation fault in simple code
    By livin in forum C Programming
    Replies: 7
    Last Post: 11-21-2011, 08:19 AM
  2. Why this code gives a segmentation fault error?
    By xianwen in forum C Programming
    Replies: 2
    Last Post: 11-13-2011, 08:09 PM
  3. Segmentation Fault (Can Someone look at my code?)
    By jtkosh in forum C Programming
    Replies: 12
    Last Post: 09-27-2011, 07:06 PM
  4. Help with Segmentation fault - in simple code
    By ramchan in forum C Programming
    Replies: 8
    Last Post: 03-01-2009, 09:07 AM
  5. Help with code segmentation fault
    By blindleaf in forum C Programming
    Replies: 2
    Last Post: 04-10-2003, 03:00 PM