diff --git a/Include/frameobject.h b/Include/frameobject.h --- a/Include/frameobject.h +++ b/Include/frameobject.h @@ -42,8 +42,8 @@ int f_lasti; /* Last instruction if called */ /* Call PyFrame_GetLineNumber() instead of reading this field directly. As of 2.3 f_lineno is only valid when tracing is - active (i.e. when f_trace is set). At other times we use - PyCode_Addr2Line to calculate the line from the current + active (i.e. when f_trace is set and not Py_None). At other times + we use PyCode_Addr2Line to calculate the line from the current bytecode index. */ int f_lineno; /* Current line number */ int f_iblock; /* index in f_blockstack */ diff --git a/Lib/bdb.py b/Lib/bdb.py --- a/Lib/bdb.py +++ b/Lib/bdb.py @@ -74,7 +74,13 @@ self.botframe = frame.f_back # (CT) Note that this may also be None! return self.trace_dispatch if not (self.stop_here(frame) or self.break_anywhere(frame)): - # No need to trace this function + # When frame is stopframe, we are re-entering a generator frame + # where the {next, until, return} command had been previously + # issued, so we need to enable tracing in this function. + if (self.stopframe is frame and + frame.f_code.co_flags & CO_GENERATOR): + return self.trace_dispatch + # No need to trace this function. return # None # Ignore call events in generator except when stepping. if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: diff --git a/Objects/frameobject.c b/Objects/frameobject.c --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -30,7 +30,7 @@ int PyFrame_GetLineNumber(PyFrameObject *f) { - if (f->f_trace) + if (f->f_trace && f->f_trace != Py_None) return f->f_lineno; else return PyCode_Addr2Line(f->f_code, f->f_lasti); @@ -93,7 +93,7 @@ /* You can only do this from within a trace function, not via * _getframe or similar hackery. */ - if (!f->f_trace) + if (!f->f_trace || f->f_trace == Py_None) { PyErr_Format(PyExc_ValueError, "f_lineno can only be set by a" diff --git a/Python/ceval.c b/Python/ceval.c --- a/Python/ceval.c +++ b/Python/ceval.c @@ -1288,7 +1288,8 @@ /* line-by-line tracing support */ if (_Py_TracingPossible && - tstate->c_tracefunc != NULL && !tstate->tracing) { + tstate->c_tracefunc != NULL && !tstate->tracing && + f->f_trace != Py_None) { int err; /* see maybe_call_line_trace for expository comments */ diff --git a/Python/sysmodule.c b/Python/sysmodule.c --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -424,12 +424,13 @@ { PyObject *callback; PyObject *result; + PyObject *temp; if (what == PyTrace_CALL) callback = self; else callback = frame->f_trace; - if (callback == NULL) + if (callback == NULL || callback == Py_None) return 0; result = call_trampoline(callback, frame, what, arg); if (result == NULL) { @@ -438,15 +439,10 @@ frame->f_trace = NULL; return -1; } - if (result != Py_None) { - PyObject *temp = frame->f_trace; - frame->f_trace = NULL; - Py_XDECREF(temp); - frame->f_trace = result; - } - else { - Py_DECREF(result); - } + temp = frame->f_trace; + frame->f_trace = NULL; + Py_XDECREF(temp); + frame->f_trace = result; return 0; }