diff options
author | Armin Rigo <arigo@tunes.org> | 2007-09-06 08:35:34 +0000 |
---|---|---|
committer | Armin Rigo <arigo@tunes.org> | 2007-09-06 08:35:34 +0000 |
commit | 303d35082ccc6a32f196c2e8c3784b5bad8325df (patch) | |
tree | 628e20355040136ad7868c658bd2838a2c63630d | |
parent | a326ab2c9f34a3f5005cbbbc85f81ecf5d51c615 (diff) | |
download | cpython-git-303d35082ccc6a32f196c2e8c3784b5bad8325df.tar.gz |
Backport of r58004.
-rw-r--r-- | Modules/_lsprof.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index d35c894c5a..7eb9682323 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 |