New submission from Sriram Rajagopalan: Consider this simple python program -
1 #!/usr/bin/python 2 3 import pdb 4 import sys 5 import traceback 6 7 def trace_exception( type, value, tb ): 8 traceback.print_tb( tb ) 9 pdb.post_mortem( tb ) 10 11 sys.excepthook = trace_exception 12 13 def func(): 14 print ( "Am here in func" ) 15 pdb.set_trace() 16 print ( "Am here after pdb" ) 17 print ( "Am going to assert now" ) 18 assert False 19 print ( "Am here after exception" ) 20 21 def main(): 22 func() 23 24 if __name__ == "__main__": 25 main() On running this program - % ./python /tmp/test.py Am here in func > /tmp/test.py(16)func() -> print ( "Am here after pdb" ) (Pdb) c Am here after pdb Am going to assert now File "/tmp/test.py", line 25, in <module> main() File "/tmp/test.py", line 22, in main func() File "/tmp/test.py", line 16, in func print ( "Am here after pdb" ) > /tmp/test.py(16)func() -> print ( "Am here after pdb" ) >>>> This should have been at the line corresponding to "Am going to assert now" (Pdb) This seems to be an bug ( due to a performance consideration ) with the way python bdb's set_continue() has been implemented - https://hg.python.org/cpython/file/2.7/Lib/bdb.py#l227 def set_continue(self): # Don't stop except at breakpoints or when finished self._set_stopinfo(self.botframe, None, -1) if not self.breaks: # no breakpoints; run without debugger overhead sys.settrace(None) frame = sys._getframe().f_back while frame and frame is not self.botframe: del frame.f_trace frame = frame.f_back Basically what happens after "c" in a "(Pdb)" prompt is that bdb optimizes for the case where there are no more break points found by cleaning up the trace callback from all the frames. However, all of this happens in the context of tracing itself and hence the trace_dispatch function in https://hg.python.org/cpython/file/2.7/Lib/bdb.py#l45 still returns back the trace_dispatch as the new system trace function. For more details on sys.settrace(), check https://docs.python.org/2/library/sys.html#sys.settrace Check, the function trace_trampoline at https://hg.python.org/cpython/file/2.7/Python/sysmodule.c#l353 which sets f->f_trace back to result at https://hg.python.org/cpython/file/2.7/Python/sysmodule.c#l377 This seems to be an bug ( due to a performance consideration ) with the way python bdb's set_continue() has been implemented - https://hg.python.org/cpython/file/2.7/Lib/bdb.py#l227 def set_continue(self): # Don't stop except at breakpoints or when finished self._set_stopinfo(self.botframe, None, -1) if not self.breaks: # no breakpoints; run without debugger overhead sys.settrace(None) frame = sys._getframe().f_back while frame and frame is not self.botframe: del frame.f_trace frame = frame.f_back Basically what happens after "c" in a "(Pdb)" prompt is that bdb optimizes for the case where there are no more break points found by cleaning up the trace callback from all the frames. However, all of this happens in the context of tracing itself and hence the trace_dispatch function in https://hg.python.org/cpython/file/2.7/Lib/bdb.py#l45 still returns back the trace_dispatch as the new system trace function. For more details on sys.settrace(), check https://docs.python.org/2/library/sys.html#sys.settrace Check, the function trace_trampoline at https://hg.python.org/cpython/file/2.7/Python/sysmodule.c#l353 which sets f->f_trace back to result at https://hg.python.org/cpython/file/2.7/Python/sysmodule.c#l377 Now, check the function PyFrame_GetLineNumber() which is used by the traceback to get the frame line number https://hg.python.org/cpython/file/2.7/Objects/frameobject.c#l63 int PyFrame_GetLineNumber(PyFrameObject *f) { if (f->f_trace) return f->f_lineno; else return PyCode_Addr2Line(f->f_code, f->f_lasti); } Basically this function returns back the stored f->f_lineno in case the f->f_trace is enabled. The fix is fortunately simple - Just set self.trace_dispatch to None if pdb set_continue decides to run without debugger overhead. ---------- components: Library (Lib) files: bdbfix.patch keywords: patch messages: 263553 nosy: Sriram Rajagopalan priority: normal severity: normal status: open title: pdb continue followed by an exception in the same frame shows incorrect frame linenumber type: behavior versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4, Python 3.5, Python 3.6 Added file: http://bugs.python.org/file42486/bdbfix.patch _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue26779> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com