web-dev-qa-db-fra.com

Bdbquit levé lors du débogage de python

Récemment, lors de l'ajout du débogueur à mon code python 2.7.10, le message suivant s'affiche:

Traceback (most recent call last):
  File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/connectors/amqplib_connector.py", line 191, in acking_callback
    callback(message.body)
  File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/consumable_message_queue.py", line 32, in deserialized_callback
    self._callback_method(msg)
  File "/Users/isaachess/Programming/vivint/Platform/BusinessLogic/businesslogic/util/statsd_util.py", line 95, in _time_func
    retVal = f(*args, **kwargs)
  File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
    try:
  File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
    try:
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 49, in trace_dispatch
    return self.dispatch_line(frame)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 68, in dispatch_line
    if self.quitting: raise BdbQuit
BdbQuit

C’est après l’insertion des lignes:

import pdb; pdb.set_trace()

dans le code.

Je ne peux pas comprendre pourquoi cela se produit. J'ai lu sur Bdb et Bdbquit, mais je ne comprends pas pourquoi cela se produit dans mon code. Quelqu'un peut-il me donner des indices sur les raisons pour lesquelles cela se produit en général? Je vraiment veux que le débogueur fonctionne à nouveau.

16
isaachess

Si vous continuez à partir de l'invite (pdb) et laissez votre code se terminer normalement, je ne m'attendrais pas à une sortie identique à la trace que vous avez indiquée, mais si vous quittez pdb avec la commande quit ou ^ D (EOF), une telle trace se produit car il n'y a rien à intercepter l'exception BdbQuit levée lorsque le débogueur se ferme. Dans bdb.py, self.quitting est défini sur True par la méthode set_quit (et par les clauses finally dans les différentes méthodes d'exécution). Méthodes de répartition appelées par trace_dispatchraise BdbQuit lorsque self.quitting est True et que la clause except: typique de BdbQuit est une simple instruction pass; pdb hérite de tout cela de gdb.

En bref, la gestion des exceptions permet de désactiver la fonction de trace système utilisée par le débogueur lorsque l’interaction du débogueur se termine plus tôt.

Une façon d'éviter ce traçage est d'utiliser pdb différemment. Plutôt que d'appeler pdb.set_trace() à partir de votre code (et de ne pas gérer BdbQuit du tout), vous pouvez appeler votre code dans pdb (plutôt que l'inverse), à ​​ce stade, l'exception BdbQuit sera gérée de la manière prévue par pdb. Cela vous permettra également de choisir des emplacements de points d'arrêt sans modifier votre code (à l'aide de la commande pdb's break). Ou vous pouvez mélanger les deux approches; exécutez votre code sous les appels pdb, pdb.set_trace() et tous, et ces appels constitueront des points d'arrêt que vous ne pourrez supprimer qu'en modifiant votre code.

Vous pouvez appeler votre code dans pdb en utilisant la commande pdb avec votre appel de script comme argument de ligne de commande ou avec python -m pdb.

8
Eirik Fuller

Je me suis heurté à cela quand j'ai laissé import pdb et une pdb.set_trace() dans mon code de production. Lorsque la ligne pdb.set_trace() a été exécutée, python attendait mon entrée pour lui indiquer ccontinuer ou y accéder, etc ... Parce que le code python était appelé par un serveur Web, je n'étais pas là pour appuyer sur c afin de continuer. Après si longtemps (je ne sais pas combien de temps), il a finalement levé l'exception BdbQuit.

Je n'avais rien configuré pour attraper cette exception, donc il a soulevé 500 dans mon serveur web.

Il m'a fallu un certain temps pour comprendre que mon code de débogage fonctionnant dans un démon/arrière-plan était à l'origine du problème. Je me sentais idiot.

3
teewuane

Outre la réponse d'Eirik Fuller, j'aimerais ajouter que vous ne pouvez pas utiliser pdb dans quelque chose qui s'exécute dans un processus différent. Pour le débogage, vous pouvez vérifier cette réponse: https://stackoverflow.com/a/23654936/7806805 mais cela semble très rudimentaire ou vous pouvez faire exécuter votre programme en un seul thread. Consultez la documentation: https://docs.python.org/3/library/concurrent.futures.html . Pour les problèmes de multitraitement, vous pouvez même passer par https://www.reddit.com/r/learnpython/comments/46x9sm/why_is_pdbset_trace_crashing_whenever_it_is_in_an_an/

Quoi qu'il en soit, votre question manque de contexte bien nécessaire. S'il vous plaît ajouter à votre question. 

2
Ishan Srivastava

Une des raisons possibles est que vous exécutez le Python script in the background. Lorsqu'un processus s'exécute en arrière-plan, vous ne pouvez pas envoyer d'entrée au processus via un terminal. La console pdb ne peut donc pas fonctionner. Finalement, il soulève bdbquit. 

0
Siva Prakash