issue #195: MITOGEN_DUMP_THREAD_STACKS=1

pull/197/head
David Wilson 8 years ago
parent f06ae05734
commit 810f557514

@ -245,6 +245,9 @@ class ContextService(mitogen.service.Service):
# We don't need to wait for the result of this. Ideally we'd check its # We don't need to wait for the result of this. Ideally we'd check its
# return value somewhere, but logs will catch a failure anyway. # return value somewhere, but logs will catch a failure anyway.
context.call_async(ansible_mitogen.target.start_fork_parent) context.call_async(ansible_mitogen.target.start_fork_parent)
if os.environ.get('MITOGEN_DUMP_THREAD_STACKS'):
import mitogen.debug
context.call(mitogen.debug.dump_to_logger)
self._key_by_context[context] = key self._key_by_context[context] = key
self._refs_by_context[context] = 0 self._refs_by_context[context] = 0
return { return {

@ -507,6 +507,7 @@ class Importer(object):
self._context = context self._context = context
self._present = {'mitogen': [ self._present = {'mitogen': [
'compat', 'compat',
'debug',
'fakessh', 'fakessh',
'fork', 'fork',
'master', 'master',

@ -31,6 +31,7 @@ Basic signal handler for dumping thread stacks.
""" """
import difflib import difflib
import logging
import os import os
import signal import signal
import sys import sys
@ -39,6 +40,7 @@ import time
import traceback import traceback
LOG = logging.getLogger(__name__)
_last = None _last = None
@ -74,15 +76,13 @@ def format_stacks():
return '\n'.join(l) return '\n'.join(l)
def _handler(*_): def get_snapshot():
global _last global _last
s = format_stacks() s = format_stacks()
fp = open('/dev/tty', 'w', 1) snap = s
fp.write(s)
if _last: if _last:
fp.write('\n') snap += '\n'
diff = list(difflib.unified_diff( diff = list(difflib.unified_diff(
a=_last.splitlines(), a=_last.splitlines(),
b=s.splitlines(), b=s.splitlines(),
@ -91,25 +91,30 @@ def _handler(*_):
)) ))
if diff: if diff:
fp.write('\n'.join(diff) + '\n') snap += '\n'.join(diff) + '\n'
else: else:
fp.write('(no change since last time)\n') snap += '(no change since last time)\n'
_last = s _last = s
return snap
def _handler(*_):
fp = open('/dev/tty', 'w', 1)
fp.write(get_snapshot())
fp.close()
def install_handler(): def install_handler():
signal.signal(signal.SIGUSR2, _handler) signal.signal(signal.SIGUSR2, _handler)
def _thread_main(): def _logging_main():
while True: while True:
time.sleep(7) time.sleep(5)
l = format_stacks() LOG.info('PERIODIC THREAD DUMP\n\n%s', get_snapshot())
open('/tmp/stack.%s.log' % (os.getpid(),), 'wb', 65535).write(l)
break
def dump_periodically(): def dump_to_logger():
th = threading.Thread(target=main) th = threading.Thread(target=_logging_main)
th.setDaemon(True) th.setDaemon(True)
th.start() th.start()

Loading…
Cancel
Save