Search code examples
clinuxsdlsdl-ttfsigbus

TTF_RenderText_Solid causes SIGBUS


I have this code, which should load a font using SDL2_ttf and draw a text onto the screen:

Structs declaration:

typedef struct {
    SDL_Window* win;
    SDL_Event* e;

    SDL_Renderer* renderer;
} SL_Window;

typedef struct {
    TTF_Font* font;
    char* file;
    size_t size;
} SL_Font;

typedef struct {
    SL_Font* font;
    char* text;
    SDL_Renderer* renderer;
    SDL_Texture* texture;

    SDL_Rect rect;

    SDL_Color color;
} SL_Text;

Text rendering header:

SL_Font* SL_loadFont(const char* file, int size) {
    SL_Font* font = (SL_Font*)SL_malloc(sizeof(SL_Font));

    font->font = TTF_OpenFont(file, size);
    if (!font->font) {
        SL_log(SL_LOG_ERROR, "Error loading font \"%s\": %s", file, TTF_GetError());
        SL_free(font);
        return NULL;
    }

    size_t __size = strlen(file) + 1;

    font->file = (char*)malloc(__size);
    strncpy(font->file, file, __size);
}
SL_Text* SL_createText(SL_Window* window, SL_Font* font) {
    SL_Text* text = (SL_Text*)SL_malloc(sizeof(SL_Text));
    text->font = font;
    text->renderer = window->renderer;

    text->texture = NULL;

    text->color.r = 0;
    text->color.g = 0;
    text->color.b = 0;
    text->color.a = 255;

    text->rect.x = 0;
    text->rect.y = 0;
    text->rect.w = 1000;
    text->rect.h = 1000;
}

void SL_setTextString(SL_Text* text, const char* string) {
    size_t __size = strlen(string) + 1;
    text->text = (char*)SL_malloc(__size);

    strncpy(text->text, string, __size);

    SDL_Surface* surface = TTF_RenderText_Solid(text->font->font, text->text, text->color);

    if (text->texture) SDL_DestroyTexture(text->texture);
    text->texture = SDL_CreateTextureFromSurface(text->renderer, surface);
    SDL_FreeSurface(surface);
}

void SL_windowDrawText(SL_Window* window, SL_Text* text) {
    SDL_RenderCopy(window->renderer, text->texture, NULL, &text->rect);
}

...

And main:

...
SL_Font* font = SL_loadFont("res/test_font.ttf", 24);
if (!font) return -1;
SL_Text* text = SL_createText(window, font);
SL_setTextString(text, "test text");
...

But it gives me SIGBUS whenever I try to call SL_setTextString(SL_Text* text, const char* string) function. It appears on the line SDL_Surface* surface = TTF_RenderText_Solid(text->font->font, text->text, text->color).

GDB backtrace:

#0  0x00007ffff7fa0139 in  () at /lib/x86_64-linux-gnu/libSDL2_ttf-2.0.so.0
#1  0x00007ffff7fa0c4f in TTF_RenderUTF8_Solid () at /lib/x86_64-linux-gnu/libSDL2_ttf-2.0.so.0
#2  0x00007ffff7fa0fd9 in TTF_RenderText_Solid () at /lib/x86_64-linux-gnu/libSDL2_ttf-2.0.so.0
#3  0x000055555555711b in SL_setTextString (text=0x555555a52460, string=0x555555559082 "test text") at CGraphics.c:65
#4  0x0000555555556834 in main (argc=1, argv=0x7fffffffde78) at SLE_shapes.c:23

And by the way, a list of common SIGBUS causes would be much appreciated.


Solution

  • As @keltar said, my problem was once again cause by my inattention and also C's way of handling variables, which are without proper initialization can have absolutely random values, which means that unset pointers aren't necessarily NULL as well.