Search code examples
pythonbreakpointspdb

Are nested breakpoints possible in pdb--if not, what prevents them?


Following a tutorial on Python's debugger, I used pdb.set_trace() to interrupt the sample code. It worked, but what if you are at the interactive prompt and want another nested breakpoint?

(Pdb) def test(): pdb.set_trace(); print "don't print this yet"
(Pdb) test()
don't print this yet

It didn't stop. Is the debugger fundamentally "one deep"? e.g. is this is a limitation of Python's hooks, or just something pdb doesn't choose to do?


Solution

  • is this is a limitation of Python's hooks, or just something pdb doesn't choose to do?

    It appears to be a limitation of the hooks.

    I did a test to see what was being called and what wasn't (putting print statements in /usr/lib/python2.7/bdb.py)

    Quick inspection finds set_trace in pdb.py:

    def set_trace():
        Pdb().set_trace(sys._getframe().f_back)
    

    That calls set_trace in bdb.py

    def set_trace(self, frame=None):
        """Start debugging from `frame`.
        If frame is not specified, debugging starts from caller's frame.
        """
        if frame is None:
            frame = sys._getframe().f_back
        self.reset()
        while frame:
            frame.f_trace = self.trace_dispatch
            self.botframe = frame
            frame = frame.f_back
        self.set_step()
        sys.settrace(self.trace_dispatch)
    

    This sets up a callback to trace_dispatch, also in bdb.py. The sys.settrace code itself is perhaps in threading.py:

    def settrace(func):
        global _trace_hook
        _trace_hook = func
    

    GitHub search finds no more references for _trace_hook, so presumably that's picked up magically in C code somewhere.

    When test() is called, it turns out the sys.settrace() call is made...but then the call to trace_dispatch() does not happen.