diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c index d259998b5e1..fc419b14cd0 100644 --- a/Modules/pyexpat.c +++ b/Modules/pyexpat.c @@ -264,6 +264,33 @@ getcode(enum HandlerTypes slot, char* func_name, int lineno) return NULL; } +static int +trace_frame(PyThreadState *tstate, PyFrameObject *f, int code, PyObject *val) +{ + int result = 0; + if (!tstate->use_tracing || tstate->tracing) + return 0; + if (tstate->c_profilefunc != NULL) { + tstate->tracing++; + result = tstate->c_profilefunc(tstate->c_profileobj, + f, code , val); + tstate->use_tracing = ((tstate->c_tracefunc != NULL) + || (tstate->c_profilefunc != NULL)); + tstate->tracing--; + if (result) + return result; + } + if (tstate->c_tracefunc != NULL) { + tstate->tracing++; + result = tstate->c_tracefunc(tstate->c_traceobj, + f, code , val); + tstate->use_tracing = ((tstate->c_tracefunc != NULL) + || (tstate->c_profilefunc != NULL)); + tstate->tracing--; + } + return result; +} + static PyObject* call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args) { @@ -273,6 +300,7 @@ call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args) if (c == NULL) return NULL; + f = PyFrame_New( tstate, /*back*/ c, /*code*/ @@ -282,9 +310,19 @@ call_with_frame(PyCodeObject *c, PyObject* func, PyObject* args) if (f == NULL) return NULL; tstate->frame = f; + if (trace_frame(tstate, f, PyTrace_CALL, Py_None)) { + Py_DECREF(f); + return NULL; + } res = PyEval_CallObject(func, args); if (res == NULL && tstate->curexc_traceback == NULL) PyTraceBack_Here(f); + else { + if (trace_frame(tstate, f, PyTrace_RETURN, res)) { + Py_XDECREF(res); + res = NULL; + } + } tstate->frame = f->f_back; Py_DECREF(f); return res;