diff options
author | Fred Drake <fdrake@acm.org> | 2001-10-04 19:26:43 (GMT) |
---|---|---|
committer | Fred Drake <fdrake@acm.org> | 2001-10-04 19:26:43 (GMT) |
commit | 4ec5d5699de7a67dac59a59077ee8d0a777df586 (patch) | |
tree | cd26b96a9ff7c86373300f29f9098e98f6c2fffd /Python/ceval.c | |
parent | d1de6eacf22caf95aba6d76058267c8f5b6543b8 (diff) | |
download | cpython-4ec5d5699de7a67dac59a59077ee8d0a777df586.zip cpython-4ec5d5699de7a67dac59a59077ee8d0a777df586.tar.gz cpython-4ec5d5699de7a67dac59a59077ee8d0a777df586.tar.bz2 |
Fix bug in profiler modifications detected only in debug builds.
The new profiler event stream includes a "return" event even when an
exception is being propogated, but the machinery that called the profile
hook did not save & restore the exception. In debug mode, the exception
was detected during the execution of the profile callback, which did not
have the proper internal flags set for the exception. Saving & restoring
the exception state solves the problem.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 99822e8..bccd90d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -48,6 +48,8 @@ static int prtrace(PyObject *, char *); #endif static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *, int, PyObject *); +static void call_trace_protected(Py_tracefunc, PyObject *, + PyFrameObject *, int); static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); @@ -2297,9 +2299,13 @@ eval_frame(PyFrameObject *f) } } if (tstate->c_profilefunc) { - if (call_trace(tstate->c_profilefunc, - tstate->c_profileobj, f, - PyTrace_RETURN, retval)) { + if (why == WHY_EXCEPTION) + call_trace_protected(tstate->c_profilefunc, + tstate->c_profileobj, f, + PyTrace_RETURN); + else if (call_trace(tstate->c_profilefunc, + tstate->c_profileobj, f, + PyTrace_RETURN, retval)) { Py_XDECREF(retval); retval = NULL; why = WHY_EXCEPTION; @@ -2821,6 +2827,23 @@ call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f) } } +static void +call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, + int what) +{ + PyObject *type, *value, *traceback; + int err; + PyErr_Fetch(&type, &value, &traceback); + err = call_trace(func, obj, frame, what, NULL); + if (err == 0) + PyErr_Restore(type, value, traceback); + else { + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); + } +} + static int call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame, int what, PyObject *arg) |