2010-10-12 5 views
0

Existe-t-il un moyen pratique d'obtenir une trace de pile plus détaillée sur une exception Python? J'espère trouver un utilitaire/module wrapper ou un autre moyen d'obtenir un peu plus d'informations de la trace de la pile sans avoir à modifier le script Python qui le génère. Je voudrais être capable de l'utiliser lors de l'exécution de tests unitaires, de doctests, ou lors de l'exécution d'utilitaires ou de scripts en ligne à partir du shell. En particulier, je pense que je voudrais avoir les valeurs des variables locales, ou peut-être juste les valeurs des arguments passés à la fonction la plus interne dans la trace de la pile. Certaines options pour définir le niveau de détail seraient astucieuses.Obtenir plus de détails à partir des traces de pile

Répondre

2

ne se rapportent pas à votre problème, mais vous trouverez peut-être ce code utile - démarre automatiquement la débogueur Python lorsqu'une exception fatale se produit. Bon pour travailler avec du code interactif. Il est à l'origine de ActiveState

# code snippet, to be included in 'sitecustomize.py' 
import sys 

def info(type, value, tb): 
    if hasattr(sys, 'ps1') or not sys.stderr.isatty(): 
     # we are in interactive mode or we don't have a tty-like 
     # device, so we call the default hook 
     sys.__excepthook__(type, value, tb) 
    else: 
     import traceback, pdb 
     # we are NOT in interactive mode, print the exception... 
     traceback.print_exception(type, value, tb) 
     print 
     # ...then start the debugger in post-mortem mode. 
     pdb.pm() 

sys.excepthook = info 
+0

Hey, merci pour cela. J'ai fini par emballer votre code dans un [module] (http://pypi.python.org/pypi/coroner) pour le rendre commode d'invoquer le débogage de pdb avec 'python -m coroner some_script.py'. Umm, j'espère que ça va? Je vous ai donné l'attribution dans les docs. Je vais probablement changer le module plus tard pour cracher des traces de pile comme je les veux, donc je n'ai pas besoin de les extraire avec pdb, et donc je peux l'utiliser pour des tests unitaires et autres. En attendant, cependant, cela pourrait être utile à quelqu'un. – intuited

+0

Hey, vous pouvez le faire avec 'ipython' aussi, je viens de réaliser. Vous passez l'option '-pdb' avant de passer' -c ... 'ou un nom de fichier. Il ne semble pas supporter '-m ...' mais peut-être pourrait-on le faire en passant '/ usr/lib/python ../runpy.py' comme nom de fichier. – intuited

0

tel que signifié par pyfunc, vous pouvez utiliser la fonction dans le module de retraçage, mais vous obtenez seulement un stacktrace.

Si vous voulez inspecter la pile, vous devez utiliser la fonction sys.exc_info() et parcourir le membre traceback et vider les informations de son cadre (tb_frame). Voir le python Reference Manual pour plus d'informations sur ces types.

Voici un exemple:

def killit(a): 
    a[10000000000000] = 1 

def test(a): 
    killit(a) 

def iterate_traceback(tb): 
    while tb is not None: 
     yield tb 
     tb = tb.tb_next 

try: 
    test(tuple()) 
except Exception as e: 

    import sys 
    exception_info = sys.exc_info() 

    traceback = exception_info[2] 
    for tb in iterate_traceback(traceback): 
     print "-" * 10 
     print tb.tb_frame.f_code 
     print tb.tb_frame.f_locals 
     print tb.tb_frame.f_globals 
Questions connexes