summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-10-18 10:26:25 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-10-18 10:26:25 (GMT)
commitdf0fd74ae8fa204aab51c35e10870fd99101e99c (patch)
treedac85a7dd7ba7df01d421644c9a4bca4a2578665
parentc411a7d8210febfbe96a2547357752be6be7adad (diff)
parent04eb7772794a11bdb7ed7cd132adebb2ae527191 (diff)
downloadcpython-df0fd74ae8fa204aab51c35e10870fd99101e99c.zip
cpython-df0fd74ae8fa204aab51c35e10870fd99101e99c.tar.gz
cpython-df0fd74ae8fa204aab51c35e10870fd99101e99c.tar.bz2
Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
loss in PyTraceBack_Here().
-rw-r--r--Misc/NEWS3
-rw-r--r--Python/traceback.c46
2 files changed, 29 insertions, 20 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 2b0397b..5d972fd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 3
Core and Builtins
-----------------
+- Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
+ loss in PyTraceBack_Here().
+
Library
-------
diff --git a/Python/traceback.c b/Python/traceback.c
index e8aac1b..9f8c568 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -132,47 +132,53 @@ newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
int
PyTraceBack_Here(PyFrameObject *frame)
{
- PyThreadState *tstate = PyThreadState_GET();
- PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
- PyTracebackObject *tb = newtracebackobject(oldtb, frame);
- if (tb == NULL)
+ PyObject *exc, *val, *tb, *newtb;
+ PyErr_Fetch(&exc, &val, &tb);
+ newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame);
+ if (newtb == NULL) {
+ _PyErr_ChainExceptions(exc, val, tb);
return -1;
- tstate->curexc_traceback = (PyObject *)tb;
- Py_XDECREF(oldtb);
+ }
+ PyErr_Restore(exc, val, newtb);
+ Py_XDECREF(tb);
return 0;
}
/* Insert a frame into the traceback for (funcname, filename, lineno). */
void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
{
- PyObject *globals = NULL;
- PyCodeObject *code = NULL;
- PyFrameObject *frame = NULL;
- PyObject *exception, *value, *tb;
+ PyObject *globals;
+ PyCodeObject *code;
+ PyFrameObject *frame;
+ PyObject *exc, *val, *tb;
/* Save and clear the current exception. Python functions must not be
called with an exception set. Calling Python functions happens when
the codec of the filesystem encoding is implemented in pure Python. */
- PyErr_Fetch(&exception, &value, &tb);
+ PyErr_Fetch(&exc, &val, &tb);
globals = PyDict_New();
if (!globals)
- goto done;
+ goto error;
code = PyCode_NewEmpty(filename, funcname, lineno);
- if (!code)
- goto done;
+ if (!code) {
+ Py_DECREF(globals);
+ goto error;
+ }
frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
+ Py_DECREF(globals);
+ Py_DECREF(code);
if (!frame)
- goto done;
+ goto error;
frame->f_lineno = lineno;
- PyErr_Restore(exception, value, tb);
+ PyErr_Restore(exc, val, tb);
PyTraceBack_Here(frame);
+ Py_DECREF(frame);
+ return;
-done:
- Py_XDECREF(globals);
- Py_XDECREF(code);
- Py_XDECREF(frame);
+error:
+ _PyErr_ChainExceptions(exc, val, tb);
}
static PyObject *