Navigation Menu

Skip to content

Commit

Permalink
windows: first shot at naming threads with SetThreadDescription().
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
icculus committed Jan 28, 2017
1 parent 95ab9dc commit 8fa9b57
Showing 1 changed file with 40 additions and 13 deletions.
53 changes: 40 additions & 13 deletions src/thread/windows/SDL_systhread.c
Expand Up @@ -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);
}
}
}

Expand Down

0 comments on commit 8fa9b57

Please sign in to comment.