1
1
# -*- coding: ascii -*-
3
Thread monitor - Check the state of all threads.
5
Just call activate_hook() as early as possible in program execution.
6
Then you can trigger the output of tracebacks of all threads
7
by calling trigger_dump().
9
@copyright: 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
10
@license: GNU GPL Version 2
3
Thread monitor - Check the state of all threads.
5
Just call activate_hook() as early as possible in program execution.
6
Then you can trigger the output of tracebacks of all threads
7
by calling trigger_dump().
9
Usage of Python 2.5 is recommended because it allows for a much safer
10
and faster frame extraction.
12
@copyright: 2006 Alexander Schremmer <alex AT alexanderweb DOT de>
13
@license: GNU GPL Version 2
17
__all__ = "activate_hook trigger_dump dump_regularly".split()
16
23
from time import sleep
17
24
from StringIO import StringIO
22
from sets import Set as set
32
df = dump_file or sys.stderr
34
print >>s, "\nDumping thread %s:" % (label, )
36
raise ZeroDivisionError
37
except ZeroDivisionError:
38
f = sys.exc_info()[2].tb_frame.f_back.f_back
39
traceback.print_list(traceback.extract_stack(f, None), s)
40
df.write(s.getvalue())
42
def dump_hook(a, b, c): # arguments are ignored
45
if dumping and sys.exc_info()[0] is None:
46
thread = threading.currentThread()
49
to_dump.discard(thread)
54
def trigger_dump(dumpfile=None):
55
""" Triggers the dump of the tracebacks of all threads.
56
If dumpfile is specified, it is used as the output file. """
57
global dumping, dump_file, to_dump
59
to_dump = set(threading.enumerate())
60
if dumpfile is not None:
65
""" Activates the thread monitor hook. Note that this interferes
66
with any kind of profiler and some debugging extensions. """
69
sys.setprofile(dump_hook)
70
threading.setprofile(dump_hook)
26
from MoinMoin.support.python_compatibility import set
29
class AbstractMonitor(object):
30
def activate_hook(self):
31
""" Activates the thread monitor hook. Note that this might interfere
32
with any kind of profiler and some debugging extensions. """
33
raise NotImplementedError
35
def trigger_dump(self, dumpfile=None):
36
""" Triggers the dump of the tracebacks of all threads.
37
If dumpfile is specified, it is used as the output file. """
38
raise NotImplementedError
40
def hook_enabled(self):
41
""" Returns true if the thread_monitor hook is enabled. """
42
raise NotImplementedError
44
class LegacyMonitor(AbstractMonitor):
53
df = cls.dump_file or sys.stderr
55
print >>s, "\nDumping thread %s:" % (label, )
57
raise ZeroDivisionError
58
except ZeroDivisionError:
59
f = sys.exc_info()[2].tb_frame.f_back.f_back
60
traceback.print_list(traceback.extract_stack(f, None), s)
61
df.write(s.getvalue())
62
dump = classmethod(dump)
64
def dump_hook(cls, a, b, c): # arguments are ignored
65
if cls.dumping and sys.exc_info()[0] is None:
66
thread = threading.currentThread()
67
if thread in cls.to_dump:
68
cls.dump(repr(thread))
69
cls.to_dump.discard(thread)
70
cls.dumped.add(thread)
73
dump_hook = classmethod(dump_hook)
75
def trigger_dump(cls, dumpfile=None):
76
cls.to_dump = set(threading.enumerate())
77
if dumpfile is not None:
78
cls.dump_file = dumpfile
80
trigger_dump = classmethod(trigger_dump)
82
def activate_hook(cls):
83
sys.setprofile(cls.dump_hook)
84
threading.setprofile(cls.dump_hook)
85
cls.hook_enabled = True
86
activate_hook = classmethod(activate_hook)
88
def hook_enabled(cls):
89
return cls.hook_enabled
90
hook_enabled = classmethod(hook_enabled)
93
class DirectMonitor(AbstractMonitor):
96
assert hasattr(sys, "_current_frames")
98
def activate_hook(self):
101
def trigger_dump(self, dumpfile=None):
104
dumpfile = dumpfile or sys.stderr
105
cur_frames = sys._current_frames()
108
print >>s, "\nDumping thread (id %s):" % (i, )
109
traceback.print_stack(cur_frames[i], file=s)
110
dumpfile.write(s.getvalue())
112
def hook_enabled(self):
73
116
def dump_regularly(seconds):
74
117
""" Dumps the tracebacks every 'seconds' seconds. """