From 72b7acfe8ac26498dac57d751e1b3485d30a62e3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 16 Dec 2023 21:27:44 -0800 Subject: [PATCH] Don't create a TLS error buffer if we're just clearing the error Fixes https://github.com/libsdl-org/SDL/issues/7600 --- src/SDL_error.c | 16 ++++++++++++---- src/SDL_error_c.h | 2 +- src/thread/SDL_thread.c | 6 +++++- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/SDL_error.c b/src/SDL_error.c index e7773ca492..c8db336814 100644 --- a/src/SDL_error.c +++ b/src/SDL_error.c @@ -30,7 +30,7 @@ int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) if (fmt) { va_list ap; int result; - SDL_error *error = SDL_GetErrBuf(); + SDL_error *error = SDL_GetErrBuf(SDL_TRUE); error->error = SDL_ErrorCodeGeneric; @@ -62,7 +62,11 @@ int SDL_SetError(SDL_PRINTF_FORMAT_STRING const char *fmt, ...) /* Available for backwards compatibility */ const char *SDL_GetError(void) { - const SDL_error *error = SDL_GetErrBuf(); + const SDL_error *error = SDL_GetErrBuf(SDL_FALSE); + + if (!error) { + return ""; + } switch (error->error) { case SDL_ErrorCodeGeneric: @@ -76,7 +80,11 @@ const char *SDL_GetError(void) void SDL_ClearError(void) { - SDL_GetErrBuf()->error = SDL_ErrorCodeNone; + SDL_error *error = SDL_GetErrBuf(SDL_FALSE); + + if (error) { + error->error = SDL_ErrorCodeNone; + } } /* Very common errors go here */ @@ -84,7 +92,7 @@ int SDL_Error(SDL_errorcode code) { switch (code) { case SDL_ENOMEM: - SDL_GetErrBuf()->error = SDL_ErrorCodeOutOfMemory; + SDL_GetErrBuf(SDL_TRUE)->error = SDL_ErrorCodeOutOfMemory; return -1; case SDL_EFREAD: return SDL_SetError("Error reading from datastream"); diff --git a/src/SDL_error_c.h b/src/SDL_error_c.h index 291f04b068..ed5d06b49f 100644 --- a/src/SDL_error_c.h +++ b/src/SDL_error_c.h @@ -44,6 +44,6 @@ typedef struct SDL_error } SDL_error; /* Defined in SDL_thread.c */ -extern SDL_error *SDL_GetErrBuf(void); +extern SDL_error *SDL_GetErrBuf(SDL_bool create); #endif /* SDL_error_c_h_ */ diff --git a/src/thread/SDL_thread.c b/src/thread/SDL_thread.c index 84ec9a9ed7..4f3842c045 100644 --- a/src/thread/SDL_thread.c +++ b/src/thread/SDL_thread.c @@ -212,7 +212,7 @@ static void SDLCALL SDL_FreeErrBuf(void *data) #endif /* Routine to get the thread-specific error variable */ -SDL_error *SDL_GetErrBuf(void) +SDL_error *SDL_GetErrBuf(SDL_bool create) { #ifdef SDL_THREADS_DISABLED return SDL_GetStaticErrBuf(); @@ -223,6 +223,10 @@ SDL_error *SDL_GetErrBuf(void) const SDL_error *ALLOCATION_IN_PROGRESS = (SDL_error *)-1; SDL_error *errbuf; + if (!tls_errbuf && !create) { + return NULL; + } + /* tls_being_created is there simply to prevent recursion if SDL_CreateTLS() fails. It also means it's possible for another thread to also use SDL_global_errbuf, but that's very unlikely and hopefully won't cause issues.