-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
threadutil.cpp
119 lines (104 loc) · 2.81 KB
/
threadutil.cpp
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#ifdef _WIN32
#include <windows.h>
#ifdef __MINGW32__
#include <excpt.h>
#endif
#define TLS_SUPPORTED
#elif defined(__ANDROID__)
#define TLS_SUPPORTED
#endif
#include "base/basictypes.h"
#include "base/logging.h"
#include "thread/threadutil.h"
#ifdef __ANDROID__
#include <pthread.h>
#endif
#ifdef TLS_SUPPORTED
static __THREAD const char *curThreadName;
#endif
#ifdef __MINGW32__
#include <pshpack8.h>
typedef struct {
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
} THREADNAME_INFO;
#include <poppack.h>
static EXCEPTION_DISPOSITION NTAPI ignore_handler(EXCEPTION_RECORD *rec,
void *frame, CONTEXT *ctx,
void *disp)
{
return ExceptionContinueExecution;
}
#endif
void setCurrentThreadName(const char* threadName) {
#ifdef _WIN32
// Set the debugger-visible threadname through an unholy magic hack
static const DWORD MS_VC_EXCEPTION = 0x406D1388;
#endif
#if defined(_WIN32) && defined(__MINGW32__)
// Thread information for VS compatible debugger. -1 sets current thread.
THREADNAME_INFO ti;
ti.dwType = 0x1000;
ti.szName = threadName;
ti.dwThreadID = -1;
// Push an exception handler to ignore all following exceptions
NT_TIB *tib = ((NT_TIB*)NtCurrentTeb());
EXCEPTION_REGISTRATION_RECORD rec;
rec.Next = tib->ExceptionList;
rec.Handler = ignore_handler;
tib->ExceptionList = &rec;
// Visual Studio and compatible debuggers receive thread names from the
// program through a specially crafted exception
RaiseException(MS_VC_EXCEPTION, 0, sizeof(ti) / sizeof(ULONG_PTR),
(ULONG_PTR*)&ti);
// Pop exception handler
tib->ExceptionList = tib->ExceptionList->Next;
#elif defined(_WIN32)
#pragma pack(push,8)
struct THREADNAME_INFO {
DWORD dwType; // must be 0x1000
LPCSTR szName; // pointer to name (in user addr space)
DWORD dwThreadID; // thread ID (-1=caller thread)
DWORD dwFlags; // reserved for future use, must be zero
} info;
#pragma pack(pop)
info.dwType = 0x1000;
info.szName = threadName;
info.dwThreadID = -1; //dwThreadID;
info.dwFlags = 0;
#ifdef __MINGW32__
__try1 (ehandler)
#else
__try
#endif
{
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
}
#ifdef __MINGW32__
__except1
#else
__except(EXCEPTION_CONTINUE_EXECUTION)
#endif
{}
#else
#if defined(__ANDROID__)
pthread_setname_np(pthread_self(), threadName);
// #else
// pthread_setname_np(thread_name);
#endif
// Do nothing
#endif
// Set the locally known threadname using a thread local variable.
#ifdef TLS_SUPPORTED
curThreadName = threadName;
#endif
}
void AssertCurrentThreadName(const char *threadName) {
#ifdef TLS_SUPPORTED
if (strcmp(curThreadName, threadName) != 0) {
ELOG("Thread name assert failed: Expected %s, was %s", threadName, curThreadName);
}
#endif
}