-
Notifications
You must be signed in to change notification settings - Fork 0
/
nut_platform_debugging.hpp
92 lines (76 loc) · 2.53 KB
/
nut_platform_debugging.hpp
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once
#include "nut_types.hpp"
#include "nut_platform_strings.hpp"
namespace nut {
namespace platform {
namespace api {
using fnSetThreadDescription = HRESULT( WINAPI* )( HANDLE hThread, PCWSTR lpThreadDescription );
using fnGetThreadDescription = HRESULT( WINAPI* )( HANDLE hThread, PWSTR* ppszThreadDescription );
struct WinapiCalls
{
fnSetThreadDescription pfnSetThreadDescription = nullptr;
fnGetThreadDescription pfnGetThreadDescription = nullptr;
};
extern WinapiCalls g_calls;
void initialize();
}
#ifdef NUT_CONFIG_WANT_THREAD_NAMING
inline void setDebuggerThreadName_legacyImpl( HANDLE thread, const string& threadName )
{
auto threadID = GetThreadId( thread );
#pragma pack( push, 8 )
struct threadNamingStruct
{
DWORD type;
LPCSTR name;
DWORD threadID;
DWORD flags;
} nameSignalStruct = { 0 };
#pragma pack( pop )
nameSignalStruct.type = 0x1000;
nameSignalStruct.name = threadName.c_str();
nameSignalStruct.threadID = threadID;
nameSignalStruct.flags = 0;
__try
{
RaiseException( 0x406D1388, 0, sizeof( nameSignalStruct ) / sizeof( ULONG_PTR ),
reinterpret_cast<const ULONG_PTR*>( &nameSignalStruct ) );
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
}
}
#endif
//! Assign a thread name that will be visible in debuggers.
inline void setDebuggerThreadName( HANDLE thread, const string& threadName )
{
#ifdef NUT_CONFIG_WANT_THREAD_NAMING
// Prefer SetThreadDescription, but it is only available from Windows 10 version 1607 onwards.
if ( api::g_calls.pfnSetThreadDescription )
api::g_calls.pfnSetThreadDescription( thread, utf8ToWide( threadName ).c_str() );
else
setDebuggerThreadName_legacyImpl( thread, threadName );
#endif
}
inline string getThreadDescriptor( HANDLE thread )
{
auto id = GetThreadId( thread );
wchar_t* name = nullptr;
if ( api::g_calls.pfnGetThreadDescription )
api::g_calls.pfnGetThreadDescription( thread, &name );
static thread_local wchar_t buf[128];
if ( name )
{
StringCchPrintfW( buf, 128, L"0x%X (%s)", id, name );
LocalFree( name );
}
else
StringCchPrintfW( buf, 128, L"0x%X", id );
return wideToUtf8( buf );
}
inline string getCurrentThreadDescriptor()
{
return getThreadDescriptor( GetCurrentThread() );
}
}
}