Commit 9fd4d4dd39ba0b81f77ea93f459171cd6d18c4b7

Ryan C. Gordon 2016-02-21T17:05:25

Windows: let threads be named in the debugger. We now only raise the magic exception that names the thread when IsDebuggerPresent() returns true. In such a case, Visual Studio will catch the exception, set the thread name, and let the debugged process continue normally. If the debugger isn't running, we don't raise an exception at all. Setting the name is a debugger trick; if the debugger isn't running, the name won't be set if attached later in any case, so this doesn't lose functionality. This lets this code work without assembly code, on win32 and win64, and across various compilers. The only "gotcha" is that if you have something attached that looks like a debugger but doesn't respect this magic exception trick, the process will likely crash, but that's probably a deficiency of the attached program. Fixes Bugzilla #2089.

diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c
index 308145e..7f66cb3 100644
--- a/src/thread/windows/SDL_systhread.c
+++ b/src/thread/windows/SDL_systhread.c
@@ -145,9 +145,6 @@ SDL_SYS_CreateThread(SDL_Thread * thread, void *args)
     return 0;
 }
 
-#if 0  /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
-#ifdef _MSC_VER
-#pragma warning(disable : 4733)
 #pragma pack(push,8)
 typedef struct tagTHREADNAME_INFO
 {
@@ -158,48 +155,20 @@ typedef struct tagTHREADNAME_INFO
 } THREADNAME_INFO;
 #pragma pack(pop)
 
-static EXCEPTION_DISPOSITION
-ignore_exception(void *a, void *b, void *c, void *d)
-{
-    return ExceptionContinueExecution;
-}
-#endif
-#endif
-
 void
 SDL_SYS_SetupThread(const char *name)
 {
-    if (name != NULL) {
-        #if 0 /* !!! FIXME: revisit this later. See https://bugzilla.libsdl.org/show_bug.cgi?id=2089 */
-        #if (defined(_MSC_VER) && defined(_M_IX86))
-        /* This magic tells the debugger to name a thread if it's listening.
-            The inline asm sets up SEH (__try/__except) without C runtime
-            support. See Microsoft Systems Journal, January 1997:
-            http://www.microsoft.com/msj/0197/exception/exception.aspx */
-        INT_PTR handler = (INT_PTR) ignore_exception;
+    if ((name != NULL) && IsDebuggerPresent()) {
+        /* This magic tells the debugger to name a thread if it's listening. */
         THREADNAME_INFO inf;
-
+        SDL_zero(inf);
         inf.dwType = 0x1000;
         inf.szName = name;
         inf.dwThreadID = (DWORD) -1;
         inf.dwFlags = 0;
 
-        __asm {   /* set up SEH */
-            push handler
-            push fs:[0]
-            mov fs:[0],esp
-        }
-
-        /* The program itself should ignore this bogus exception. */
-        RaiseException(0x406D1388, 0, sizeof(inf)/sizeof(DWORD), (DWORD*)&inf);
-
-        __asm {  /* tear down SEH. */
-            mov eax,[esp]
-            mov fs:[0], eax
-            add esp, 8
-        }
-        #endif
-        #endif
+        /* The debugger catches this, renames the thread, continues on. */
+        RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
     }
 }