/usr/lib/python3/dist-packages/provisioningserver/utils/debug.py is in python3-maas-provisioningserver 2.0.0~beta3+bzr4941-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | # Copyright 2015 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Utilities for debugging."""
__all__ = [
'get_full_thread_dump',
'print_full_thread_dump',
'register_sigusr2_thread_dump_handler',
]
import io
import signal
from sys import _current_frames as current_frames
import threading
from time import (
gmtime,
strftime,
)
import traceback
def get_full_thread_dump():
"""Returns a string containing a traceback for all threads"""
output = io.StringIO()
time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
thread_names = {}
for thread in threading.enumerate():
thread_names[thread.ident] = thread.name
output.write("\n>>>> Begin stack trace (%s) >>>>\n" % time)
for threadId, stack in current_frames().items():
output.write(
"\n# ThreadID: %s (%s)\n" %
(threadId, thread_names.get(threadId, "unknown")))
for filename, lineno, name, line in traceback.extract_stack(stack):
output.write(
'File: "%s", line %d, in %s\n' %
(filename, lineno, name))
if line:
output.write(" %s\n" % (line.strip()))
output.write("\n<<<< End stack trace <<<<\n\n")
thread_dump = output.getvalue()
output.close()
return thread_dump
def print_full_thread_dump(signum=None, stack=None):
"""Creates a full thread dump, then prints it to stdout."""
print(get_full_thread_dump())
def register_sigusr2_thread_dump_handler():
"""Installs a signal handler which will print a full thread dump
upon receiving SIGUSR2."""
# installing a signal handler only works from the main thread.
# some of our test cases may run this from something that isn't
# the main thread, however...
if threading.current_thread().__class__.__name__ == '_MainThread':
signal.signal(signal.SIGUSR2, print_full_thread_dump)
|