@@ -217,7 +217,38 @@ def register_signal_handlers(self):
217
217
signal .signal (signal .SIGQUIT , self .schedule_shutdown )
218
218
signal .signal (signal .SIGUSR1 , self .kill_child )
219
219
signal .signal (signal .SIGUSR2 , self .add_child )
220
-
220
+ signal .signal (signal .SIGINFO , self .current_state )
221
+
222
+ def current_state (self ):
223
+ tmap = {}
224
+ main_thread = None
225
+ import traceback
226
+ from cStringIO import StringIO
227
+ # get a map of threads by their ID so we can print their names
228
+ # during the traceback dump
229
+ for t in threading .enumerate ():
230
+ if getattr (t , "ident" , None ):
231
+ tmap [t .ident ] = t
232
+ else :
233
+ main_thread = t
234
+
235
+ out = StringIO ()
236
+ sep = "=" * 49 + "\n "
237
+ for tid , frame in sys ._current_frames ().iteritems ():
238
+ thread = tmap .get (tid , main_thread )
239
+ if not thread :
240
+ # skip old junk (left-overs from a fork)
241
+ continue
242
+ out .write ("%s\n " % (thread .getName (), ))
243
+ out .write (sep )
244
+ traceback .print_stack (frame , file = out )
245
+ out .write (sep )
246
+ out .write ("LOCAL VARIABLES\n " )
247
+ out .write (sep )
248
+ pprint (frame .f_locals , stream = out )
249
+ out .write ("\n \n " )
250
+ self .logger .info (out .getvalue ())
251
+
221
252
def _schedule_shutdown (self ):
222
253
self .schedule_shutdown (None , None )
223
254
0 commit comments