-2

UPDATE:Check my answer for details, pointer error.

I have a function, that is supposed to load a few test assets and blit them onto screen using SDL2. This function throws a segfault immediately before executing any commands, with no clear cause. Keep in mind that some of the variables in this function are globals.

Function contents:

    printf("DEBUG");
    int menuSelect = 0;
    printf("declare");
    SDL_Surface* bg = SDL_LoadBMP("menubg.bmp");
    printf("bg load");
    SDL_Surface* menu1 = TTF_RenderText_Solid(font,"HACKING PROGRAM",whiteclr);
    printf("title blip");
    SDL_BlitSurface(bg,NULL,screen,NULL);
    printf("event");
    SDL_Event* event;
    printf("menu2");
    SDL_Surface* menu2 = TTF_RenderText_Solid(font,"Hack",whiteclr);
    printf("rect");
    SDL_Rect menu2r = CreateRect(5,30,menu2->w,menu2->h);
    printf("free");
    SDL_FreeSurface(menu2);
    SDL_FreeSurface(menu1);
    while(SDL_WaitEvent(event))
    {
        switch(event->type)
        {
            case SDL_MOUSEBUTTONDOWN:
                if(event->motion.x > menu2r.x && event->motion.x < menu2r.x+menu2r.w && event->motion.y > menu2r.y && event->motion.y < menu2r.y+menu2r.h)
                {
                    SDL_FreeSurface(bg);
                    return 0;
                }
                break;
            case SDL_MOUSEMOTION:
                if(event->motion.x > menu2r.x && event->motion.x < menu2r.x+menu2r.w && event->motion.y > menu2r.y && event->motion.y < menu2r.y+menu2r.h)
                {
                    menuSelect=1;
                }
                else
                {
                    menuSelect=0;
                }
                break;
        }
        if(menuSelect==1)
        {
            menu2 = TTF_RenderText_Solid(font,"Hack",selectclr);
        }
        else
        {
            menu2 = TTF_RenderText_Solid(font,"Hack",selectclr);
        }
    }
    return 0;
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • Have you tried running in gdb or other debugger? debug print statements do not help you if they do not get executed. :) How are you executing this? Do you get a core file? What is the full exception output? – Rob Sep 18 '17 at 16:28
  • 1
    printf may not print instantly. Try `fflush(stdout);` after each print to pin down where it fails. – KaeptnNemo Sep 18 '17 at 16:29
  • 1
    @KaeptnNemo is right. Alternatively, and more in line with the mainstream, write error messages to the aptly named `stderr`, which for exactly this reason is not buffered by default. – Peter - Reinstate Monica Sep 18 '17 at 16:33
  • @Rob I'm not very good at using debuggers, but I know for certain that it is a segfault, and i know exactly in which stack frame it fails in, but ill try to gt more data out of this damn hard gdb – jfkjsu3v95 Sep 18 '17 at 16:37
  • 2
    @jfkjsu3v95 _" I'm not very good at using debuggers"_ Get familiar with it. That's an essential skill. – user0042 Sep 18 '17 at 16:39
  • It seems like the segfault is caused by the free statements before the while statement, even though they are both valid surfaces, which is confirmable too. – jfkjsu3v95 Sep 18 '17 at 16:41
  • So, I have confirmed that neither of them is NULL. They are both valid surfaces – jfkjsu3v95 Sep 18 '17 at 16:46
  • 1
    @jfkjsu3v95 Also regarding your _superior_ `printf()` statements. Add a `\n` at each line to ensure flushing the output. – user0042 Sep 18 '17 at 16:58

2 Answers2

1
  1. Double check the paths on fonts, images, etc. Are they correct in relation to the root directory of the project? They are quite sensitive. To avoid simple mistakes like these: go to point 2.
  2. Apply some basic exception handling. For example:

    SDL_Surface* bg = SDL_LoadBMP("menubg.bmp");
    
    if(bg == NULL)
    {
        // This code will be run when menubg.bmp cannot be loaded.
    }
    

    It's good practice to always check the outcome of your statement to make sure it worked as planned.

  3. Use a debugger. GDB is the most popular one; but I personally use DDD, a visual debugger that is run on GDB. It's very lightweight and has both graphical and console input.
  4. Document your code. Even if it's a personal project and you're not going to show it to anyone. Explain what each statement does and why it's needed; you'll get a clearer sense of the code and you may find the problem itself.

Also, it's while(SDL_WaitEvent(&event)) not while(SDL_WaitEvent(event)).

0

This is actually a stupid error, and something that might happen to anyone who is a newbie to SDL. WaitEvent(SDL_Event*) should be fed &event, as in event should be the event, not a pointer to the event. By changing while(SDL_WaitEvent(event)) to while(SDL_WaitEvent(&event)) and changing SDL_Event* event; to SDL_Event event; this problem is fixed.

For anyone else experiencing any kind of segfault, debugging hard will do the job. The guys here at SO greatly helped me in tracing down and fixing my stupid error, and educated me as a developer.