2013-04-23 18:51:17 +02:00
|
|
|
from __future__ import absolute_import
|
|
|
|
|
2013-03-06 19:28:41 +01:00
|
|
|
import code
|
|
|
|
import traceback
|
|
|
|
import signal
|
|
|
|
|
2016-06-04 20:38:42 +02:00
|
|
|
from types import FrameType
|
|
|
|
|
|
|
|
from typing import Optional
|
|
|
|
|
2013-03-06 19:28:41 +01:00
|
|
|
# Interactive debugging code from
|
|
|
|
# http://stackoverflow.com/questions/132058/showing-the-stack-trace-from-a-running-python-application
|
|
|
|
# (that link also points to code for an interactive remote debugger
|
|
|
|
# setup, which we might want if we move Tornado to run in a daemon
|
|
|
|
# rather than via screen).
|
|
|
|
def interactive_debug(sig, frame):
|
2016-06-04 20:38:42 +02:00
|
|
|
# type: (int, Optional[FrameType]) -> None
|
2013-03-06 19:28:41 +01:00
|
|
|
"""Interrupt running process, and provide a python prompt for
|
|
|
|
interactive debugging."""
|
2016-04-28 07:22:13 +02:00
|
|
|
d = {'_frame': frame} # Allow access to frame object.
|
2013-03-06 19:28:41 +01:00
|
|
|
d.update(frame.f_globals) # Unless shadowed by global
|
|
|
|
d.update(frame.f_locals)
|
|
|
|
|
|
|
|
message = "Signal recieved : entering python shell.\nTraceback:\n"
|
|
|
|
message += ''.join(traceback.format_stack(frame))
|
|
|
|
i = code.InteractiveConsole(d)
|
|
|
|
i.interact(message)
|
|
|
|
|
|
|
|
# SIGUSR1 => Just print the stack
|
|
|
|
# SIGUSR2 => Print stack + open interactive debugging shell
|
|
|
|
def interactive_debug_listen():
|
2016-06-04 20:38:42 +02:00
|
|
|
# type: () -> None
|
2016-10-17 08:22:00 +02:00
|
|
|
signal.signal(signal.SIGUSR1, lambda sig, stack: traceback.print_stack(stack))
|
2013-03-06 19:28:41 +01:00
|
|
|
signal.signal(signal.SIGUSR2, interactive_debug)
|