SDL3 : SIGSEGV: address not mapped to object (fault address: 0x0)

Hi,
I am porting shadps4 to FreeBSD, and i have a problem with SIGSEGV on FreeBSD.
The problem is NULL with environ variable.
This is an official bug. I think the problem is inside SDL3. Do you have any idea?

[[APP BUG]: SIGSEGV: address not mapped to object (fault address: 0x0) · Issue #2765 · shadps4-emu/shadPS4 · GitHub](Ps4 emulator)

It looks like the application initializes SDL in a separate thread.

The FreeBSD getenv manual calls out that combining getenv and putenv can results in undefined behavior:

SDL assumes SDL_Init is run very early in the lifetime of a process, when multithreading is not an issue.
Environment variables are notoriously tricky to use in multithreaded environments.
This is also why you see SDL_CreateEnvironment_REAL in the stacktrace: SDL is copying the environmment to avoid multithreading issues.

so SDL getenv uses wrong. How to fix this problem ?

Where do you see getenv ?

frame #3: 0x00001f3449e01cdc shadps4`SDL_CreateEnvironment_REAL(populated=true) at SDL_getenv.c:129:34
   126 	        char **strings = (char **)dlsym(RTLD_DEFAULT, "environ");
   127 	        if (strings) {
   128 	            for (int i = 0; strings[i]; ++i) {
-> 129 	                char *variable = SDL_strdup(strings[i]);
   130 	                if (!variable) {
   131 	                    continue;
   132 	                }
(lldb) print strings[0]
(char *) 0x0000365a3fabfe00 "`\xae\xa2?Z6"
(lldb) print strings[1]
(char *) 0x0000365a3fa10500 "\xb8bPJ4\U0000001f"
(lldb) print *(strings)
(char *) 0x0000365a3fabfe00 "`\xae\xa2?Z6"

I stand corrected. SDL does not call getenv, but uses the environ symbol.

SDL wants to clone the environment, and thus needs to iterate all keys.
SDL does this here.

Yes, but in environ variable is garbage

The small program below prints all environment variables. (It works fine on Linux)

#include <SDL3/SDL.h>
int main(int argc, char *argv[]) {
    SDL_Environment *env = SDL_CreateEnvironment(true);
    char **env_vars = SDL_GetEnvironmentVariables(env);
    for (size_t i = 0; env_vars[i] != NULL; i++) {
        SDL_Log("[%d] %s", i, env_vars[i]);
    }
    SDL_free(env_vars);
    SDL_DestroyEnvironment(env);
    return 0;
}

I’ve got a few questions:

  1. Does the program work on your system?
  2. When copying and adapting into shadps4 (running it in the thread that calls SDL_Init), does it print sensible thins?

I have FreeBSD RELEASE 14.2 amd64.
I tried this, but without output.


#include <SDL3/SDL.h>
#include <SDL3/SDL_stdinc.h>
#include <iostream>
#include <thread>

void sdl_worker() {
    if (!SDL_SetHint(SDL_HINT_APP_NAME, "Test")) {
        std::cerr << "Failed to set SDL window hint: " << SDL_GetError() << std::endl;
    }

    if (!SDL_Init(SDL_INIT_VIDEO)) {
        std::cerr << "SDL_Init failed: " << SDL_GetError() << std::endl;
        return;
    }

    SDL_Environment *env = SDL_CreateEnvironment(true);
    if (!env) {
        std::cerr << "SDL_CreateEnvironment failed: " << SDL_GetError() << std::endl;
        SDL_Quit();
        return;
    }

    char **env_vars = SDL_GetEnvironmentVariables(env);
    if (env_vars) {
        for (size_t i = 0; env_vars[i] != NULL; ++i) {
            std::cout << "[" << i << "] " << env_vars[i] << std::endl;
        }
        SDL_free(env_vars);
    }

    SDL_DestroyEnvironment(env);
    SDL_Quit();
}

int main(int argc, char* argv[]) {
    std::thread worker(sdl_worker);;
    worker.join();

    return 0;
}

when i tried your code add to shadps4 after SDL_Init() so crash is inside SDL_Init()

No output at all? Not even an error message from your added error checking?

when i tried your code add to shadps4 after SDL_Init() so crash is inside SDL_Init()

We already established it crashes inside SDL_Init (from your stack trace in the GitHub issue), so you have to run the code first (before SDL_Init).
But since it even fails to print anything when running on the main thread, don’t bother running it.

Can you please create a GitHub issue with:

  • links to the GitHub issue and this conservation
  • Result of running the last SDL_Environment c++ test code, with a complete copy-paste of stdout+stderr (don’t forget to censor PII)?

I remember there being an issue with environ on FreeBSD, but I cannot find it right now.

Add SDL_Process subsystem by Semphriss · Pull Request #10618 · libsdl-org/SDL · GitHub contains:

I asked on a #freebsd-devel why we can t access environ, and they say it s because our use of version scripts. We d need to explicitly add environ (and __progname) to the global section.

Just a note - SDL3/SDL.h includes SDL3/SDL_stdinc.h, so you don’t really need it there

Also I find myself SDL3 working weird with other thread libraries. Maybe SDL Threads will work better?

I mean, is this really related to SDL_Environment? Does not SDL3 create it also internally at initialization?

The problem is inside SDL_SetHint() this is first call SDL, but i commented this code, and
the second call is SDL_Init() (shadps4). I forget for this changes. I am sorry.
I will to create github issue with this problem.

I tried with SDL_Threads and the result is the same.