summaryrefslogtreecommitdiffstats
path: root/Modules/_lsprof.c
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2007-09-06 08:30:51 (GMT)
committerArmin Rigo <arigo@tunes.org>2007-09-06 08:30:51 (GMT)
commitbddc3416f8ff0b1436e219aa8281ccad845d81f6 (patch)
tree3c3f094325d78b309e9ab80d5b88c55a24502126 /Modules/_lsprof.c
parent5768d577d396d25d8f00672616528d7a234025b6 (diff)
downloadcpython-bddc3416f8ff0b1436e219aa8281ccad845d81f6.zip
cpython-bddc3416f8ff0b1436e219aa8281ccad845d81f6.tar.gz
cpython-bddc3416f8ff0b1436e219aa8281ccad845d81f6.tar.bz2
Patch #1733973 by peaker:
ptrace_enter_call() assumes no exception is currently set. This assumption is broken when throwing into a generator.
Diffstat (limited to 'Modules/_lsprof.c')
-rw-r--r--Modules/_lsprof.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index 5b03b56..7e9975f 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -369,11 +369,20 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
ProfilerEntry *profEntry;
ProfilerContext *pContext;
+ /* In the case of entering a generator expression frame via a
+ * throw (gen_send_ex(.., 1)), we may already have an
+ * Exception set here. We must not mess around with this
+ * exception, and some of the code under here assumes that
+ * PyErr_* is its own to mess around with, so we have to
+ * save and restore any current exception. */
+ PyObject *last_type, *last_value, *last_tb;
+ PyErr_Fetch(&last_type, &last_value, &last_tb);
+
profEntry = getEntry(pObj, key);
if (profEntry == NULL) {
profEntry = newProfilerEntry(pObj, key, userObj);
if (profEntry == NULL)
- return;
+ goto restorePyerr;
}
/* grab a ProfilerContext out of the free list */
pContext = pObj->freelistProfilerContext;
@@ -386,10 +395,13 @@ ptrace_enter_call(PyObject *self, void *key, PyObject *userObj)
malloc(sizeof(ProfilerContext));
if (pContext == NULL) {
pObj->flags |= POF_NOMEMORY;
- return;
+ goto restorePyerr;
}
}
initContext(pObj, pContext, profEntry);
+
+restorePyerr:
+ PyErr_Restore(last_type, last_value, last_tb);
}
static void