Move call_trace(..., PyTrace_CALL, ...) call to top of eval_frame. That
way it's called each time a generator is resumed. The tracing of normal functions should be unaffected by this change.
This commit is contained in:
parent
1b41079fd9
commit
6c0f20088f
|
@ -588,6 +588,41 @@ eval_frame(PyFrameObject *f)
|
|||
assert(stack_pointer != NULL);
|
||||
f->f_stacktop = NULL;
|
||||
|
||||
if (tstate->use_tracing) {
|
||||
if (tstate->c_tracefunc != NULL) {
|
||||
/* tstate->c_tracefunc, if defined, is a
|
||||
function that will be called on *every* entry
|
||||
to a code block. Its return value, if not
|
||||
None, is a function that will be called at
|
||||
the start of each executed line of code.
|
||||
(Actually, the function must return itself
|
||||
in order to continue tracing.) The trace
|
||||
functions are called with three arguments:
|
||||
a pointer to the current frame, a string
|
||||
indicating why the function is called, and
|
||||
an argument which depends on the situation.
|
||||
The global trace function is also called
|
||||
whenever an exception is detected. */
|
||||
if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
|
||||
f, PyTrace_CALL, Py_None)) {
|
||||
/* XXX Need way to compute arguments?? */
|
||||
/* Trace function raised an error */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (tstate->c_profilefunc != NULL) {
|
||||
/* Similar for c_profilefunc, except it needn't
|
||||
return itself and isn't called for "line" events */
|
||||
if (call_trace(tstate->c_profilefunc,
|
||||
tstate->c_profileobj,
|
||||
f, PyTrace_CALL, Py_None)) {
|
||||
/* XXX Need way to compute arguments?? */
|
||||
/* Profile function raised an error */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LLTRACE
|
||||
lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
|
||||
#endif
|
||||
|
@ -2496,41 +2531,6 @@ PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
|
|||
}
|
||||
}
|
||||
|
||||
if (tstate->use_tracing) {
|
||||
if (tstate->c_tracefunc != NULL) {
|
||||
/* tstate->c_tracefunc, if defined, is a
|
||||
function that will be called on *every* entry
|
||||
to a code block. Its return value, if not
|
||||
None, is a function that will be called at
|
||||
the start of each executed line of code.
|
||||
(Actually, the function must return itself
|
||||
in order to continue tracing.) The trace
|
||||
functions are called with three arguments:
|
||||
a pointer to the current frame, a string
|
||||
indicating why the function is called, and
|
||||
an argument which depends on the situation.
|
||||
The global trace function is also called
|
||||
whenever an exception is detected. */
|
||||
if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
|
||||
f, PyTrace_CALL, Py_None)) {
|
||||
/* XXX Need way to compute arguments?? */
|
||||
/* Trace function raised an error */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if (tstate->c_profilefunc != NULL) {
|
||||
/* Similar for c_profilefunc, except it needn't
|
||||
return itself and isn't called for "line" events */
|
||||
if (call_trace(tstate->c_profilefunc,
|
||||
tstate->c_profileobj,
|
||||
f, PyTrace_CALL, Py_None)) {
|
||||
/* XXX Need way to compute arguments?? */
|
||||
/* Profile function raised an error */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (co->co_flags & CO_GENERATOR) {
|
||||
/* Don't need to keep the reference to f_back, it will be set
|
||||
* when the generator is resumed. */
|
||||
|
|
Loading…
Reference in New Issue