J'ai un module que j'utilise pour des situations comme celle-ci - où un processus s'exécutera pendant une longue période mais se bloquera parfois pour des raisons inconnues et irréprochables. C'est un peu hacky, et ne fonctionne que sur unix (nécessite des signaux):
import code, traceback, signal
def debug(sig, frame):
"""Interrupt running process, and provide a python prompt for
interactive debugging."""
d={'_frame':frame} # Allow access to frame object.
d.update(frame.f_globals) # Unless shadowed by global
d.update(frame.f_locals)
i = code.InteractiveConsole(d)
message = "Signal received : entering python shell.\nTraceback:\n"
message += ''.join(traceback.format_stack(frame))
i.interact(message)
def listen():
signal.signal(signal.SIGUSR1, debug) # Register handler
Pour l'utiliser, il suffit d'appeler la fonction listen () à un moment donné au démarrage de votre programme (vous pouvez même la coller dans site.py pour que tous les programmes python l'utilisent), et laissez-la s'exécuter. À tout moment, envoyez au processus un signal SIGUSR1, en utilisant kill ou en python:
os.kill(pid, signal.SIGUSR1)
Cela provoquera la rupture du programme sur une console python au point où il se trouve actuellement, vous montrant la trace de la pile et vous permettant de manipuler les variables. Utilisez control-d (EOF) pour continuer à fonctionner (mais notez que vous interromprez probablement toutes les E / S, etc. au point que vous signalez, donc ce n'est pas totalement non intrusif.
J'ai un autre script qui fait la même chose, sauf qu'il communique avec le processus en cours via un canal (pour permettre le débogage des processus en arrière-plan, etc.). C'est un peu grand pour poster ici, mais je l'ai ajouté comme recette de livre de recettes en python .