From: Armin Rigo Date: Thu, 6 Sep 2007 08:30:51 +0000 (+0000) Subject: Patch #1733973 by peaker: X-Git-Tag: v2.6a1~1340 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bddc3416f8ff0b1436e219aa8281ccad845d81f6;p=python Patch #1733973 by peaker: ptrace_enter_call() assumes no exception is currently set. This assumption is broken when throwing into a generator. --- diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c index 5b03b56839..7e9975f5a3 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