diff --git a/Lib/bdb.py b/Lib/bdb.py --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -256,10 +256,6 @@ 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 def set_quit(self): self.stopframe = self.botframe diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py --- a/Lib/test/test_sys_settrace.py +++ b/Lib/test/test_sys_settrace.py @@ -232,6 +232,18 @@ [(5, 'line'), (6, 'line')] * 10 + [(5, 'line'), (5, 'return')]) +def _issue_17277(tracefunc): + sys._getframe().f_back.f_trace = tracefunc + sys.settrace(tracefunc) + sys.settrace(None) +def issue_17277(tracefunc): + _issue_17277(tracefunc) + # Checking the frame line number when no global trace function and the + # frame has a local f_trace function. + lineno = 4 + tracefunc(sys._getframe(), 'called', None) + +issue_17277.events = [(5, 'called')] class Tracer: def __init__(self): @@ -388,6 +400,8 @@ (257, 'line'), (257, 'return')]) + def test_17_issue_17277(self): + self.run_test2(issue_17277) class RaisingTraceFuncTestCase(unittest.TestCase): def setUp(self): diff --git a/Objects/frameobject.c b/Objects/frameobject.c --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -30,10 +30,12 @@ int PyFrame_GetLineNumber(PyFrameObject *f) { - if (f->f_trace) - return f->f_lineno; - else - return PyCode_Addr2Line(f->f_code, f->f_lasti); + if (f->f_trace) { + PyThreadState *tstate = PyThreadState_GET(); + if (tstate->tracing) + return f->f_lineno; + } + return PyCode_Addr2Line(f->f_code, f->f_lasti); } static PyObject *