-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy paththread_helper.py
More file actions
94 lines (86 loc) · 3.6 KB
/
thread_helper.py
File metadata and controls
94 lines (86 loc) · 3.6 KB
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
#!/usr/bin/env python
from __future__ import absolute_import
import sys
if sys.platform.startswith("win"):
def namer():
import ctypes
import threading
import time
from ctypes import wintypes
class THREADNAME_INFO(ctypes.Structure):
_pack_ = 8
_fields_ = [
("dwType", wintypes.DWORD),
("szName", wintypes.LPCSTR),
("dwThreadID", wintypes.DWORD),
("dwFlags", wintypes.DWORD),
]
def __init__(self):
self.dwType = 0x1000
self.dwFlags = 0
def debugChecker():
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
RaiseException = kernel32.RaiseException
RaiseException.argtypes = [wintypes.DWORD, wintypes.DWORD, wintypes.DWORD,
ctypes.c_void_p]
RaiseException.restype = None
IsDebuggerPresent = kernel32.IsDebuggerPresent
IsDebuggerPresent.argtypes = []
IsDebuggerPresent.restype = wintypes.BOOL
MS_VC_EXCEPTION = 0x406D1388
info = THREADNAME_INFO()
while True:
time.sleep(1)
if IsDebuggerPresent():
for thread in threading.enumerate():
if thread.ident is None:
continue # not started
if hasattr(threading, "_MainThread"):
if isinstance(thread, threading._MainThread):
continue # don't name the main thread
info.szName = "%s (Python)" % (thread.name,)
info.dwThreadID = thread.ident
try:
RaiseException(MS_VC_EXCEPTION, 0,
ctypes.sizeof(info) / ctypes.sizeof(ctypes.c_void_p),
ctypes.addressof(info))
except:
pass
dt = threading.Thread(target=debugChecker,
name="MSVC debugging support thread")
dt.daemon = True
dt.start()
namer()
del namer
elif sys.platform.startswith("linux"):
def namer():
import ctypes, ctypes.util, threading
libpthread_path = ctypes.util.find_library("pthread")
if not libpthread_path:
return
libpthread = ctypes.CDLL(libpthread_path)
if not hasattr(libpthread, "pthread_setname_np"):
return
pthread_setname_np = libpthread.pthread_setname_np
pthread_setname_np.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
pthread_setname_np.restype = ctypes.c_int
orig_setter = threading.Thread.__setattr__
def attr_setter(self, name, value):
orig_setter(self, name, value)
if name == "name":
ident = getattr(self, "ident", None)
if ident:
try:
pthread_setname_np(ident, str(value))
except:
pass # Don't care about failure to set name
threading.Thread.__setattr__ = attr_setter
#set the thread name to itself to trigger the new logic
for thread in threading.enumerate():
if thread.name:
if hasattr(threading, "_MainThread"):
if isinstance(thread, threading._MainThread):
continue # don't name the main thread
thread.name = thread.name
namer()
del namer