windows: first shot at naming threads with SetThreadDescription(). This is a bleeding edge API, added to Windows 10 Anniversary Edition (build 1607, specifically). https://msdn.microsoft.com/en-us/library/windows/desktop/mt774976(v=vs.85).aspx Nothing supports this yet, including WinDbg, Visual Studio, minidumps, etc, so we still need to also use the RaiseException hack. But presumably tools will use this API as a more robust and universal way to get thread names sooner or later, so we'll start broadcasting to it now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
diff --git a/src/thread/windows/SDL_systhread.c b/src/thread/windows/SDL_systhread.c
index 1d159db..aa73354 100644
--- a/src/thread/windows/SDL_systhread.c
+++ b/src/thread/windows/SDL_systhread.c
@@ -164,26 +164,53 @@ typedef struct tagTHREADNAME_INFO
} THREADNAME_INFO;
#pragma pack(pop)
+
+typedef HRESULT (WINAPI *pfnSetThreadDescription)(HANDLE, PCWSTR);
+
void
SDL_SYS_SetupThread(const char *name)
{
- if ((name != NULL) && IsDebuggerPresent()) {
- THREADNAME_INFO inf;
+ if (name != NULL) {
+ static HMODULE kernel32 = 0;
+ static pfnSetThreadDescription pSetThreadDescription = NULL;
+
+ if (!kernel32) {
+ kernel32 = LoadLibrary(L"kernel32.dll");
+ if (kernel32) {
+ pSetThreadDescription = (pfnSetThreadDescription) GetProcAddress(kernel32, "SetThreadDescription");
+ }
+ }
- /* C# and friends will try to catch this Exception, let's avoid it. */
- if (SDL_GetHintBoolean(SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING, SDL_FALSE)) {
- return;
+ if (pSetThreadDescription != NULL) {
+ WCHAR *strw = WIN_UTF8ToString(name);
+ if (strw) {
+ pSetThreadDescription(GetCurrentThread(), strw);
+ SDL_free(strw);
+ }
}
- /* This magic tells the debugger to name a thread if it's listening. */
- SDL_zero(inf);
- inf.dwType = 0x1000;
- inf.szName = name;
- inf.dwThreadID = (DWORD) -1;
- inf.dwFlags = 0;
+ /* Presumably some version of Visual Studio will understand SetThreadDescription(),
+ but we still need to deal with older OSes and debuggers. Set it with the arcane
+ exception magic, too. */
- /* The debugger catches this, renames the thread, continues on. */
- RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
+ if (IsDebuggerPresent()) {
+ 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_FALSE)) {
+ return;
+ }
+
+ /* This magic tells the debugger to name a thread if it's listening. */
+ SDL_zero(inf);
+ inf.dwType = 0x1000;
+ inf.szName = name;
+ inf.dwThreadID = (DWORD) -1;
+ inf.dwFlags = 0;
+
+ /* The debugger catches this, renames the thread, continues on. */
+ RaiseException(0x406D1388, 0, sizeof(inf) / sizeof(ULONG), (const ULONG_PTR*) &inf);
+ }
}
}