1"""Signals.py -- dump a python stacktrace if something bad happens. 2 3 DO NOT USE THIS MODULE IN PRODUCTION CODE 4 5This module has two functions in its public API: 6 7- dumpStackOnFatalSignal() 8 This function will install signal handlers that print a stacktrace and 9 then reraise the signal. 10 11- resetFatalSignals() 12 Restores the signal handlers to the state they had before the call to 13 dumpStackOnFatalSignal. 14 15This module is not designed to provide fine grained control over signal 16handling. Nor is it intended to be terribly robust. It may give useful 17information when your program gets unexpected signals, but it might just 18as easily cause a crash when such a signal gets in. 19 20 DO NOT USE THIS MODULE IN PRODUCTION CODE 21""" 22 23import signal 24import traceback 25import os 26 27__all__ = ["dumpStackOnFatalSignal", "resetFatalSignals"] 28 29originalHandlers = None 30 31def dumpHandler(signum, frame): 32 """ 33 the signal handler used in this module: print a stacktrace and 34 then re-raise the signal 35 """ 36 resetFatalSignals() 37 print "*** Handling fatal signal '%d'." % signum 38 traceback.print_stack(frame) 39 print "*** Restored handlers and resignaling." 40 os.kill(os.getpid(), signum) 41 42def installHandler(sig): 43 """ 44 Install our signal handler for a signal. The original handler 45 is saved in 'originalHandlers'. 46 """ 47 originalHandlers[sig] = signal.signal(sig, dumpHandler) 48 49def dumpStackOnFatalSignal(): 50 """ 51 Install signal handlers that might print a useful stack trace when 52 this process receives a fatal signal. 53 54 NOTE: See module docstring 55 """ 56 57 global originalHandlers 58 if not originalHandlers: 59 originalHandlers = {} 60 installHandler(signal.SIGQUIT) 61 installHandler(signal.SIGILL) 62 installHandler(signal.SIGTRAP) 63 installHandler(signal.SIGABRT) 64 installHandler(signal.SIGEMT) 65 installHandler(signal.SIGFPE) 66 installHandler(signal.SIGBUS) 67 installHandler(signal.SIGSEGV) 68 installHandler(signal.SIGSYS) 69 70def resetFatalSignals(): 71 """ 72 Restore the original signal handlers 73 """ 74 global originalHandlers 75 if originalHandlers: 76 for sig in originalHandlers: 77 signal.signal(sig, originalHandlers[sig]) 78 originalHandlers = None 79