iAdjunct iAdjunct - 6 months ago 20
Python Question

Python PDB won't stop

I have a [large] program which has suddenly started having an issue somewhere in an infinite loop. I cannot find this loop.

I did:

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


So when the program enters the infinite loop, I hit control-C and...... it doesn't do anything. In fact, when I don't use pdb, control-C doesn't work either.

I'm not overriding the signals. Even if I do, control-C does nothing.

I ran this in
lldb
to see if the problem was somewhere in C++-land, and it's not - it's definitely frozen executing python crap (on thread #7 if that matters).

How do I get
pdb
to actually break on control-c?

Answer

Here's a simple 'debugger' that counts the number of times each line is passed over and raises an error when a line is hit too many times. Hopefully it can help find the loop if there really is one.

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'

This has to be done once per thread since it only affects the current thread.