SDL: Update thread naming on windows

From 42d6cf9ce759b9c5620c8ad195e419b937507ee7 Mon Sep 17 00:00:00 2001
From: Edoardo Lolletti <[EMAIL REDACTED]>
Date: Tue, 16 Jan 2024 22:42:15 +0100
Subject: [PATCH] Update thread naming on windows

---
 src/thread/windows/SDL_systhread.c | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c
index 7d4a2364976c..c8b564f7a546 100644
--- a/src/thread/windows/SDL_systhread.c
+++ b/src/thread/windows/SDL_systhread.c
@@ -112,11 +112,18 @@ typedef struct tagTHREADNAME_INFO
 } THREADNAME_INFO;
 #pragma pack(pop)
 
+static LONG NTAPI EmptyVectoredExceptionHandler(EXCEPTION_POINTERS *ExceptionInfo)
+{
+    (void)ExceptionInfo;
+    return EXCEPTION_CONTINUE_EXECUTION;
+}
+
 typedef HRESULT(WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
 
 void SDL_SYS_SetupThread(const char *name)
 {
     if (name) {
+        PVOID exceptionHandlerHandle;
 #ifndef __WINRT__ /* !!! FIXME: There's no LoadLibrary() in WinRT; don't know if SetThreadDescription is available there at all at the moment. */
         static pfnSetThreadDescription pSetThreadDescription = NULL;
         static HMODULE kernel32 = NULL;
@@ -126,6 +133,12 @@ void SDL_SYS_SetupThread(const char *name)
             if (kernel32) {
                 pSetThreadDescription = (pfnSetThreadDescription)GetProcAddress(kernel32, "SetThreadDescription");
             }
+            if (!kernel32 || !pSetThreadDescription) {
+                HMODULE kernelBase = GetModuleHandle(TEXT("KernelBase.dll"));
+                if (kernelBase) {
+                    pSetThreadDescription = (pfnSetThreadDescription)GetProcAddress(kernelBase, "SetThreadDescription");
+                }
+            }
         }
 
         if (pSetThreadDescription) {
@@ -141,14 +154,9 @@ void SDL_SYS_SetupThread(const char *name)
            but we still need to deal with older OSes and debuggers. Set it with the arcane
            exception magic, too. */
 
-        if (IsDebuggerPresent()) {
+        exceptionHandlerHandle = AddVectoredExceptionHandler(1, EmptyVectoredExceptionHandler);
+        if (exceptionHandlerHandle) {
             THREADNAME_INFO inf;
-
-            /* C# and friends will try to catch this Exception, let's avoid it. */
-            if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, SDL_TRUE)) {
-                return;
-            }
-
             /* This magic tells the debugger to name a thread if it's listening. */
             SDL_zero(inf);
             inf.dwType = 0x1000;
@@ -158,6 +166,7 @@ void SDL_SYS_SetupThread(const char *name)
 
             /* The debugger catches this, renames the thread, continues on. */
             RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR *)&inf);
+            RemoveVectoredExceptionHandler(exceptionHandlerHandle);
         }
     }
 }