3

I just finished a tetris clone using SDL 1.2, now I'm trying to make a better version using SDL2. But I'm getting segmentation fault and I don't know why.

Here's the valgrind report:

==9471== Memcheck, a memory error detector
==9471== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9471== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==9471== Command: ./tetris
==9471== 
==9471== Thread 2:
==9471== Invalid read of size 8
==9471==    at 0xB4B57A9: ??? (in /usr/lib/x86_64-linux-gnu/nvidia/current/libGL.so.319.82)
==9471==    by 0x4E8094E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x4E799EA: SDL_CreateTexture (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x4E79C6D: SDL_CreateTextureFromSurface (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x401176: load_texture.3137.2439 
==9471==    by 0x401194: video_load_image.2436
==9471==    by 0x4011B6: block_image_load_all.2429
==9471==    by 0x4017BD: run_game_logic.2384
==9471==    by 0x541B061: start_thread (pthread_create.c:312)
==9471==    by 0x5715A3C: clone (clone.S:111)
==9471==  Address 0x8c0 is not stack'd, malloc'd or (recently) free'd
==9471== 
==9471== 
==9471== Process terminating with default action of signal 11 (SIGSEGV)
==9471==  Access not within mapped region at address 0x8C0
==9471==    at 0xB4B57A9: ??? (in /usr/lib/x86_64-linux-gnu/nvidia/current/libGL.so.319.82)
==9471==    by 0x4E8094E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x4E799EA: SDL_CreateTexture (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x4E79C6D: SDL_CreateTextureFromSurface  (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.1.0)
==9471==    by 0x401176: load_texture.3137.2439
==9471==    by 0x401194: video_load_image.2436
==9471==    by 0x4011B6: block_image_load_all.2429
==9471==    by 0x4017BD: run_game_logic.2384
==9471==    by 0x541B061: start_thread (pthread_create.c:312)
==9471==    by 0x5715A3C: clone (clone.S:111)
==9471==  If you believe this happened as a result of a stack
==9471==  overflow in your program's main thread (unlikely but
==9471==  possible), you can try to increase the size of the
==9471==  main thread stack using the --main-stacksize= flag.
==9471==  The main thread stack size used in this run was 8388608.

And the functions:

SDL_Texture *video_load_image(const char *file)
{
    return load_texture(file);
}

static SDL_Texture *load_texture(const char *path)
{
    SDL_Surface *surface;
    SDL_Texture *texture;

    if((surface = SDL_LoadBMP(path)) == NULL){
        puts("invalid path");
        return NULL;
    }

    texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_FreeSurface(surface);

    return texture;
}

char *image_path[BLOCK_COUNT] = {
    "img/block_dark_cyan32.bmp", "img/block_dark_red32.bmp",
    "img/block_dark_brown32.bmp", "img/block_dark_magenta32.bmp",
    "img/block_dark_gray32.bmp", "img/block_dark_green32.bmp",
    "img/block_dark_blue32.bmp", 
    "img/block_wall32.bmp", "img/block_empty32.bmp"
};

SDL_Texture *textures[BLOCK_COUNT];

int block_image_load_all(void)
{
    for(int i = 0; i < BLOCK_COUNT; ++i){
        if((textures[i] = video_load_image(image_path[i])) == NULL){
            while(i > 0)
                video_free_image(textures[--i]);

            return ERROR;
        }
    }

    return SUCCESS;
}

What is causing segmentation fault here?

Update: switching the renderer to SDL_RENDERER_SOFTWARE solves the problem, but I would like to use SDL_RENDERER_ACCELERATED

I don't think the problem is the driver since I'm using SDL_RENDERER_ACCELERATED successfully in another program.

Martin G
  • 17,357
  • 9
  • 82
  • 98
2013Asker
  • 2,008
  • 3
  • 25
  • 36
  • 2
    Is renderer fully initialised at the time of textures loading? Are you sure your OpenGL driver operating correctly? Test it with `glxinfo` and `glxgears`, at least. Also, `valgrind` is memory debugger; in case of crashes, it is better to use ordinary debugger like `gdb` (but it is not directly related to your problem) – keltar Apr 01 '14 at 03:16
  • @keltar I believe it's something to do with this code or images because the `SDL_RENDERER_ACCELERATED` flag works correctly in another similar project. – 2013Asker Apr 01 '14 at 21:06
  • @keltar I tested with both as you suggested, no problems there. Is it possible that the image format is the problem? I created the blocks using gimp and exported as ARGB 32 bits. – 2013Asker Apr 01 '14 at 21:13
  • You don't show `BLOCK_COUNT`'s definition in your code - if it's more than the number of strings in `image_path` then you may call `video_load_image` with a null pointer. – M.M Apr 03 '14 at 03:47
  • @MattMcNabb `BLOCK_COUNT` is the exact number. I tried printing the path before loading and it fails on the first call. The surface is loaded, it's segfaulting after calling `SDL_CreateTextureFromSurface` – 2013Asker Apr 03 '14 at 04:44
  • 1
    @2013Asker how about you make complete compilable minimal example including one of your problematic images and upload it somewhere? There could be many reasons, but it is impossible to say by just these code fragments. – keltar Apr 03 '14 at 08:14
  • since you don't pass `renderer` to `load_texture()`, I assume it must be a global `SDL_Renderer *`? Could you post its declaration and initialisation? – EOF Apr 05 '14 at 22:37

3 Answers3

1

Make sure when using the SDL_CreateRender() to put -1 as your second argument so SDL auto chooses a valid Video Card to use.

If problem persists, then update your Video Card drivers (restart computer after) .

Comment if it still persists

saloomi2012
  • 337
  • 2
  • 12
0

I don't think the problem is the driver since I'm using SDL_RENDERER_ACCELERATED successfully in another program.

Yes, in all probable there would be problem in your program and not in the library.Looking the Valgrind error report, your program seems to have in big mess and memory is getting corrupted.This is is bit difficult to find by looking out your code snippet. There could be three probable reason of your problem:

  1. Heap Memory Overflow/Reading After freeing the memory.
  2. Stack Overflow Scenario.
  3. Synchronization problem in threads which resulting into some form of memory corruption.

All these problem are pretty difficult to identify and there is not sort cut way to find such bugs in big programs except debugging. You may want to refer my previous post on Valgrind/GDB and Helgrind.

https://stackoverflow.com/a/22658693/2724703

https://stackoverflow.com/a/22617989/2724703

Community
  • 1
  • 1
Mantosh Kumar
  • 5,659
  • 3
  • 24
  • 48
0

It doesn't look like you free the font in your code. Try:

TTF_CloseFont(TTF_Font *font);

after you finish using the font or it will cause a segmentation fault after a few hundred frames.

MoMoTaur
  • 1
  • 3