2016-05-10 19 views
0

Ich habe ein [großes] Programm, das plötzlich ein Problem irgendwo in einer Endlosschleife hat. Ich kann diese Schleife nicht finden.Python PDB wird nicht aufhören

ich getan habe:

import pdb 
pdb.run ('main()') 

Also, wenn das Programm in die Endlosschleife, ich traf Kontrolle-C und ...... es nichts tut. Wenn ich pdb nicht benutze, funktioniert control-C auch nicht.

Ich überschreie die Signale nicht. Selbst wenn ich das tue, macht control-C nichts.

Ich lief dies in lldb, um zu sehen, ob das Problem irgendwo in C++ - Land war, und es ist nicht - es ist definitiv eingefroren Ausführen von Python Mist (auf Thread # 7, wenn das wichtig ist).

Wie bekomme ich pdb, um tatsächlich auf Control-c zu brechen?

+0

AFAIK, Ctrl-C sollte einen Interrupt im Haupt-Thread auslösen und wirkt sich nicht auf Thread # 7 aus, außer das gesamte Programm stoppt. Ich nehme an, der Haupt-Thread hat einen 'try ... except:' irgendwo (das ist ein nackter, außer dass keine Ausnahmeklasse angegeben ist), der den 'KeyboardInterrupt' abfängt. –

+0

Dies ist auch ein Multithread-Programm. Sind Sie sicher, dass es keinen Stillstand gegeben hat? –

+0

Thread 7 lief frei und Thread 1 wartete darauf, dass er eine Zustandsvariable beendete, weshalb control-C nicht funktionierte. Und ja: Es war kein Deadlock (es wurde 100% CPU verwendet). Mein erster Gedanke war "Oh, gut, eine Schleife - keine Sackgasse!" Dann konnte ich es nicht debuggen ... – iAdjunct

Antwort

1

Hier ist ein einfaches ‚Debugger‘, die die Anzahl der jede Zeile übergangen zählt, und wirft einen Fehler, wenn eine Zeile getroffen wird Zu viel zeit. Hoffentlich kann es helfen, die Schleife zu finden, wenn es wirklich eine gibt.

from bdb import Bdb 
from collections import Counter 

class LoopDetector(Bdb): 
    def __init__(self, maxhits): 
     Bdb.__init__(self) 
     self.counter = Counter() 
     self.maxhits = maxhits 

    def do_clear(self, arg): 
     pass 

    def user_line(self, frame): 
     filename = frame.f_code.co_filename 
     lineno = frame.f_lineno 
     key = (filename, lineno) 
     self.counter[key] += 1 
     if self.counter[key] >= self.maxhits: 
      raise ValueError('Too many hits at %s:%s' % key) 

LoopDetector(1000).set_trace() 

x = 1 
y = x + 2 
for i in range(200): 
    y += i 

while True: # An exception gets raised here 
    y -= 1 

print 'Does not get here' 

Dies muss einmal pro Thread durchgeführt werden, da es nur den aktuellen Thread betrifft.

+0

Dies war nicht die Antwort, auf die ich gehofft hatte ("Hier ist, wie du' pdb' arbeitest! "), Aber das hat absolut funktioniert - ich fand meine Schleife, die nur schüchtern von unendlich war (beginnend bei -1e32 und addieren twopi bis es positiv wurde). – iAdjunct

0

einen Blick in den docs PDB Nehmen

sollten Sie einen Haltepunkt hinzufügen in Ihnen (main in Ihrem Beispiel) funktionieren mit pdb.set_trace() Dann können Sie die Funktion über die Befehlszeile (zB python myprog.py) und das Programm läuft Stoppen Sie, wo Sie den Haltepunkt setzen.

import pdb 

def main(): 
    i = 0 

    while i<10: 
     print i 
     if i == 8: 
      pdb.set_trace() 
     i += 1 

In dem obigen Beispiel die das Programm für die Fehlersuche zu stoppen, wenn i==8

+1

OPs Problem ist, dass sie nicht wissen, wo die Schleife ist. –

+0

@AlexHall hat mehr gelesen und fand diese [Frage] (http://stackoverflow.com/questions/10239760/interrupt-pause-running-python-program-in-pdb). Scheint so, als ob es nur in Python funktioniert 3 – lsxliron

+0

Nun, das hilft auch nicht, weil OP sagt, dass Ctrl-C das Programm sowieso nicht beeinflusst. Und wenn es helfen würde, würde der Ort, an dem der Kommentar gepostet werden würde, in der Frage sein, um sicherzustellen, dass OP benachrichtigt wurde. –