J’ai cette application Python qui se coince de temps à autre et je ne peux pas savoir où.
Y a-t-il une manière de signaler l’interpréteur Python pour vous montrer le code exact qui exécute ?
Une sorte d’on-the-fly stacktrace ?
J’ai cette application Python qui se coince de temps à autre et je ne peux pas savoir où.
Y a-t-il une manière de signaler l’interpréteur Python pour vous montrer le code exact qui exécute ?
Une sorte d’on-the-fly stacktrace ?
J'ai le module que j'utilise pour des situations comme celle - ci, où un processus seront en cours d'exécution pendant une longue période, mais se coince parfois inconnus et irreproducable raisons. Son très orthodoxe, et ne fonctionne que sous 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 recieved : 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 le listen() la fonction à un moment donné de votre programme démarre (Vous pouvez même coller dans site.py pour avoir toutes python programmes de l'utiliser), et le laisser courir. À tout moment, envoyer le processus d'un signal SIGUSR1, à l'aide de tuer, ou en python:
os.kill(pid, signal.SIGUSR1)
Cela permettra d'interrompre le programme pour une console python au point où il en est actuellement au, en vous montrant la trace de la pile, et vous permettant de manipuler les variables. Contrôle de l'utilisation-d (EOF) pour continuer l'exécution (si la note que vous aurez probablement interrompre les I/O etc au point que vous avez du signal, de sorte qu'il n'est pas entièrement non-intrusif.
J'ai un autre script qui fait la même chose, sauf qu'il communique avec le processus en cours d'exécution à travers un tuyau (à des fins de débogage backgrounded processus, etc). Il est un peu grand pour poster ici, mais je l'ai ajouté comme un python cookbook.
La suggestion d'installer un gestionnaire de signal est un bon un, et je l'utilise beaucoup. Par exemple, bzr installe par défaut un SIGQUIT gestionnaire qui invoque pdb.set_trace()
immédiatement la chute dans un apb invite. (Voir la bzrlib.le cambriolage du module de source pour les détails.) Avec apb, vous pouvez non seulement obtenir l'état courant de la pile, mais également à inspecter des variables, etc.
Cependant, parfois, j'ai besoin de déboguer un processus que je n'ai pas eu la bonne idée d'installer le gestionnaire de signal. Sur linux, vous pouvez joindre gdb pour le processus et d'obtenir un python trace de la pile avec certains gdb macros. Mettre http://svn.python.org/projects/python/trunk/Misc/gdbinit en ~/.gdbinit
, alors:
gdb -p
PID
pystack
Il n'est pas totalement fiable, malheureusement, mais il fonctionne la plupart du temps.
Enfin, en joignant strace
peuvent souvent vous donner une bonne idée de ce qu'un processus est en train de faire.
>>> import traceback
>>> def x():
>>> print traceback.extract_stack()
>>> x()
[('<stdin>', 1, '<module>', None), ('<stdin>', 2, 'x', None)]
Vous pouvez également bien formater la trace de la pile, voir les docs .
Edit : Pour simuler le comportement de Java, comme suggéré par @ Douglas Leeder , ajoutez ceci:
import signal
import traceback
signal.signal(signal.SIGUSR1, lambda sig, stack: traceback.print_stack(stack))
au code de démarrage dans votre application. Vous pouvez ensuite imprimer la pile en envoyant SIGUSR1
au processus Python en cours d'exécution.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.