stb icon indicating copy to clipboard operation
stb copied to clipboard

Segmentation fault when loading certain JPG files with clang

Open Yasso9 opened this issue 2 years ago • 4 comments

Hello, I have an issue, I don't know if it's me who doesn't get how things should works or if it's a bug.

When I compile my code with clang++ I get a segmentation fault if I use this JPG file (works well if I use png files) : https://user-images.githubusercontent.com/63962731/162726250-a5341182-9621-4f14-8a84-9ef99d05a51d.jpg If I compile with g++ I get no error. Note that I have g++ 11.2.0 and clang++ 13.0.0 and I use Windows

Steps to reproduce the behavior:

  1. Here is my code :
#include <stdio.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
int main(void) 
{
    int width, height, channels;
    unsigned char *img = stbi_load("test.jpg", &width, &height, &channels, 0);
    if(img == NULL) {
        printf("Error in loading the image\n");
        exit(1);
    }
    printf("Loaded image with a width of %dpx, a height of %dpx and %d channels\n", width, height, channels);
}
  1. Compile using clang++ file.cpp
  2. Execute using ./a.exe
  3. Here is my backtrace if you want to know :
Thread 1 received signal SIGSEGV, Segmentation fault.
0x008417d8 in stbi__err(char const*) ()
(gdb) bt
#0  0x008417d8 in stbi__err(char const*) ()
#1  0x00847849 in stbi__check_png_header(stbi__context*) ()
#2  0x00843db4 in stbi__png_test(stbi__context*) ()
#3  0x00843833 in stbi__load_main(stbi__context*, int*, int*, int*, int, stbi__result_info*, int) ()
#4  0x0084190e in stbi__load_and_postprocess_8bit(stbi__context*, int*, int*, int*, int) ()
#5  0x00841849 in stbi_load_from_file ()
#6  0x00841770 in stbi_load ()
#7  0x0084368a in main ()

I also receive a Segmentation fault with clang if the file doesn't exist, whereas with g++ I prints me Error in loading the image as it should be. Here is the backtrace for this :

Thread 1 received signal SIGSEGV, Segmentation fault.
0x003717d8 in stbi__err(char const*) ()
(gdb) bt
#0  0x003717d8 in stbi__err(char const*) ()
#1  0x00371737 in stbi_load ()
#2  0x0037368a in main ()

Yasso9 avatar Apr 11 '22 11:04 Yasso9

Your program is crashing in the common error-reporting function stbi_error. This function does nothing except assign a variable:

static int stbi__err(const char *str)
{
   stbi__g_failure_reason = str;
   return 0;
}

stbi__g_failure_reason is a thread-local variable. So the most likely reason here is that assigning to stbi__g_failure_reason is failing.

If you're including it in a C++ file and using C11 or later, then it's using the thread_local modifier to declare stbi__g_failure_reason. I don't know why that would fail. It may depend on what platform you're developing on.

As a workaround you can try defining STBI_NO_THREAD_LOCALS in the same place you define STB_IMAGE_IMPLEMENTATION, but even if the workaround works, it would be helpful to find out what's going wrong so we can fix it.

nothings avatar Apr 11 '22 12:04 nothings

Thanks for your answer. I can tell you that putting #define STBI_NO_THREAD_LOCALS solve the problem. I don't know what's causing thread_local to launch a segmentation fault here. I tried to use -pthread and -lpthread as compiler flag but I didn't work too. It may be an issue with clang.

Yasso9 avatar Apr 11 '22 15:04 Yasso9

It may be an issue with clang.

I'm on clang 13.0.0 on GNU/Linux and can't reproduce it. Could be windows related as well.

N-R-K avatar Apr 11 '22 15:04 N-R-K

I could reproduce it on Clang using Windows, and STBI_NO_THREAD_LOCALS solved it for me as well. It's no problem with your code though, this is the minimum case:

static thread_local bool foo = true;
int main()
{
    foo = false; // causes seg fault
}

This is with yesterday's version of Clang on the master branch using Windows. I cannot reproduce it with Clang on Linux, and neither with latest GCC & MSVC (the latter two I only tested on Windows).

paulvanvulpen avatar Nov 04 '22 19:11 paulvanvulpen

Closing this as it seems to be (as per the discussion thread) a Clang issue and nothing to do with stb_image per se.

rygorous avatar Jan 22 '23 22:01 rygorous