libsdl-org / SDL_image

Image decoding for many popular formats for Simple Directmedia Layer.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SEGMENTATION FAULT with IMG_Load_RW in SDL2

oregu1 opened this issue · comments

Get into segmentation fault while running the project in mix with SDL2 & Wasm Workers.
Segfault appears at SDL2 method IMG_Load_RW execution but can't understand why.

Version of emscripten/emsdk:

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.47 (431685f05c67f0424c11473cc16798b9587bb536)
clang version 18.0.0 (https://github.com/llvm/llvm-project 21030b9ab4487d845e29792063f5666d8c4b8e09)
Target: wasm32-unknown-emscripten
Thread model: posix

Uncaught RuntimeError: Aborted(segmentation fault)

Uncaught RuntimeError: Aborted(segmentation fault)
    at abort (mob1x.js:862:40)
    at segfault (mob1x.js:589:2)
    at imports.<computed> (mob1x.js:8326:24)
    at mob1x.wasm.SAFE_HEAP_STORE_i32_4_4 (mob1x.wasm:0xff1e37)
    at SDL_RWtell (SDL_rwops.c:798)
    at IMG_LoadPNG_RW (IMG_png.c:258)
    at IMG_LoadTyped_RW (IMG.c:289)
    at IMG_Load_RW (IMG.c:212)
    at mob1x.wasm._KBTexture2D::InitWithImage(char const*, DIRECTORY_TYPES, bool) (https://------/mob1x.wasm)
    at mob1x.wasm._KBTextureStorage::LoadTextureFromFile(char const*, DIRECTORY_TYPES, bool) (https://------/mob1x.wasm)
    at mob1x.wasm._KBGUIFont::InitFonts() (https://------/mob1x.wasm)
    at mob1x.wasm._KBGUI::Init() (https://------/mob1x.wasm)

user callback triggered after runtime exited or application aborted. Ignoring.

user callback triggered after runtime exited or application aborted.  Ignoring. 2 [mob1x.js:4540:6](https://------/mob1x.js)
    callUserCallback https://------/mob1x.js:4540
    doCallback https://------/mob1x.js:6848
    reportReadyStateChange https://------/mob1x.js:6869
    onreadystatechange https://------/mob1x.js:6703
    (Async: EventHandlerNonNull)
    fetchXHR https://------/mob1x.js:6694
    performUncachedXhr https://------/mob1x.js:6874
    onsuccess https://------/mob1x.js:6786
    (Async: EventHandlerNonNull)
    fetchLoadCachedData https://------/mob1x.js:6768
    _emscripten_start_fetch https://------/mob1x.js:6905
    x https://------/mob1x.js:8326
    emscripten_fetch https://------/mob1x.wasm:1527442
    mob1x.wasm._KBHTTPQuery::Run() https://------/mob1x.wasm:1548884
    mob1x.wasm._KBHTTPManager::RunQuery(_KBHTTPQuery*) https://------/mob1x.wasm:1838212
    mob1x.wasm._KBHTTPManager::AddQuery(_KBHTTPQuery*) https://------/mob1x.wasm:1837294
    mob1x.wasm._KBHTTPManager::Get(char const*, _KBHTTPQueryCallback*, bool, int) https://------/mob1x.wasm:614490
    mob1x.wasm._KBResourceManager::CheckoutResourceVersion(int) https://------/mob1x.wasm:1983027
    mob1x.wasm._KBResourceManager::Init() https://------/mob1x.wasm:883127
    mob1x.wasm._KBCore::Init() https://------/mob1x.wasm:879105
    mob1x.wasm.initCore() https://------/mob1x.wasm:14950189
    mob1x.wasm.allocateSystem() https://------/mob1x.wasm:96246
    dynCall_v https://------/mob1x.wasm:16697430
    x https://------/mob1x.js:8348
    createExportWrapper https://------/mob1x.js:884
    browserIterationFunc https://------/mob1x.js:6291
    callUserCallback https://------/mob1x.js:4544
    runIter https://------/mob1x.js:4618
    Browser_mainLoop_runner https://------/mob1x.js:4519
    (Async: FrameRequestCallback)
    requestAnimationFrame https://------/mob1x.js:4858
    Browser_mainLoop_scheduler_rAF https://------/mob1x.js:1557
    Browser_mainLoop_runner https://------/mob1x.js:4523
    (Async: FrameRequestCallback)
    requestAnimationFrame https://------/mob1x.js:4858
    Browser_mainLoop_scheduler_rAF https://------/mob1x.js:1557
    Browser_mainLoop_runner https://------/mob1x.js:4523
    (Async: FrameRequestCallback)
    requestAnimationFrame https://------/mob1x.js:4858
    Browser_mainLoop_scheduler_rAF https://------/mob1x.js:1557
    setMainLoop https://------/mob1x.js:4531
    _emscripten_set_main_loop https://------/mob1x.js:6292

CMakeLists.txt config

(CMAKE_BUILD_TYPE STREQUAL "Debug")
	set(USE_FLAGS "-sUSE_ZLIB=1 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png,jpg'] -O0 -flto -g -sWASM_WORKERS=1" CACHE STRING "Compilation flags" FORCE)

	set(LINKING_FLAGS "--preload-file ${ASSETS_PATH}/assets@/assets -sFULL_ES2 -sWASM=1 -sFETCH=1 --use-preload-plugins -sEXIT_RUNTIME=1 -sALLOW_MEMORY_GROWTH=1 -sEXPORTED_FUNCTIONS=['_main','_photoTaken','_malloc','_setNotificationToken','_interceptPushNotification'] -sEXPORTED_RUNTIME_METHODS=[cwrap] -sFORCE_FILESYSTEM=1 -lidbfs.js -O0 -flto -g -sAUDIO_WORKLET=1 -sWASM_WORKERS=1 -sASYNCIFY -sASYNCIFY_STACK_SIZE=65536 -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS=['png,jpg'] -sSAFE_HEAP=1" CACHE STRING "Linking flags" FORCE)

	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS}")

	add_definitions(-DTARGET_WEB -DDEBUG -DMA_ENABLE_AUDIO_WORKLETS)

Source code

SDL_Surface *imgRef = 0;
                
    if(filePath)
    {
        char * buffer = 0;
        long bufferLength = 0;
        
        FM->LoadDataAsset(filePath, &buffer, &bufferLength);
        
        if(buffer)
        {
            SDL_RWops* rw = SDL_RWFromConstMem(buffer, bufferLength);
            if(rw)
                imgRef = IMG_Load_RW(rw, 1); //1 to release/free RWops
            free(buffer);
        }
    }

    if (imgRef)
    {
        if (imgRef->format->format == SDL_PIXELFORMAT_ABGR8888)
            pixelFormat = kTexture2DPixelFormat_RGBA8888;
        else if (imgRef->format->format == SDL_PIXELFORMAT_RGBA4444)
            pixelFormat = kTexture2DPixelFormat_RGBA4444;
        else if (imgRef->format->format == SDL_PIXELFORMAT_RGB24)
            pixelFormat = kTexture2DPixelFormat_RGB24;
        else if (imgRef->format->format == SDL_PIXELFORMAT_INDEX8)
            pixelFormat = kTexture2DPixelFormat_A8;

        InitWithData(imgRef->pixels, pixelFormat, imgRef->w, imgRef->h, alias);
        
        SDL_FreeSurface(imgRef); 
        return true;
    }
    
    return false;
LoadDataAsset(const char * assetName, char ** buffer, long* length)
{
    FILE * file = fopen(assetName, "rb");
    if(file) {
        fseek(file, 0, SEEK_END);
        *length = ftell(file);
        fseek(file, 0, SEEK_SET);

        *buffer = (char *) malloc(*length + 1);
        fread(*buffer, *length, 1, file);
        
        fclose(file);
    }
}

Do you have the source code for SDL_image and SDL that is being used? Those line numbers don't correspond to the latest release.

Our project is made with emscripten version 3.1.47 where SDL2 as port is used and I can't say what version is ported there. Actually I don't know right now how to do it.
The only thing that I found is that in emsdk folder generated by emscripten lies sdl2_image.6.0.zip & sdl2.24.2.zip archives.
Hope it will help somehow.

Do you have the source code for SDL_image and SDL that is being used? Those line numbers don't correspond to the latest release.

@slouken I've found what SDL version is used in my project. It's 2.24.2 for SDL and 6.0 for SDL2_image

@slouken Sam any ideas???