Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
loss in PyTraceBack_Here().
This commit is contained in:
parent
e5b0bd1ba2
commit
04eb777279
|
@ -10,6 +10,9 @@ Release date: TBA
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
|
||||||
|
loss in PyTraceBack_Here().
|
||||||
|
|
||||||
- Issue #28379: Added sanity checks and tests for PyUnicode_CopyCharacters().
|
- Issue #28379: Added sanity checks and tests for PyUnicode_CopyCharacters().
|
||||||
Patch by Xiang Zhang.
|
Patch by Xiang Zhang.
|
||||||
|
|
||||||
|
|
|
@ -132,47 +132,53 @@ newtracebackobject(PyTracebackObject *next, PyFrameObject *frame)
|
||||||
int
|
int
|
||||||
PyTraceBack_Here(PyFrameObject *frame)
|
PyTraceBack_Here(PyFrameObject *frame)
|
||||||
{
|
{
|
||||||
PyThreadState *tstate = PyThreadState_GET();
|
PyObject *exc, *val, *tb, *newtb;
|
||||||
PyTracebackObject *oldtb = (PyTracebackObject *) tstate->curexc_traceback;
|
PyErr_Fetch(&exc, &val, &tb);
|
||||||
PyTracebackObject *tb = newtracebackobject(oldtb, frame);
|
newtb = (PyObject *)newtracebackobject((PyTracebackObject *)tb, frame);
|
||||||
if (tb == NULL)
|
if (newtb == NULL) {
|
||||||
|
_PyErr_ChainExceptions(exc, val, tb);
|
||||||
return -1;
|
return -1;
|
||||||
tstate->curexc_traceback = (PyObject *)tb;
|
}
|
||||||
Py_XDECREF(oldtb);
|
PyErr_Restore(exc, val, newtb);
|
||||||
|
Py_XDECREF(tb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert a frame into the traceback for (funcname, filename, lineno). */
|
/* Insert a frame into the traceback for (funcname, filename, lineno). */
|
||||||
void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
|
void _PyTraceback_Add(const char *funcname, const char *filename, int lineno)
|
||||||
{
|
{
|
||||||
PyObject *globals = NULL;
|
PyObject *globals;
|
||||||
PyCodeObject *code = NULL;
|
PyCodeObject *code;
|
||||||
PyFrameObject *frame = NULL;
|
PyFrameObject *frame;
|
||||||
PyObject *exception, *value, *tb;
|
PyObject *exc, *val, *tb;
|
||||||
|
|
||||||
/* Save and clear the current exception. Python functions must not be
|
/* Save and clear the current exception. Python functions must not be
|
||||||
called with an exception set. Calling Python functions happens when
|
called with an exception set. Calling Python functions happens when
|
||||||
the codec of the filesystem encoding is implemented in pure Python. */
|
the codec of the filesystem encoding is implemented in pure Python. */
|
||||||
PyErr_Fetch(&exception, &value, &tb);
|
PyErr_Fetch(&exc, &val, &tb);
|
||||||
|
|
||||||
globals = PyDict_New();
|
globals = PyDict_New();
|
||||||
if (!globals)
|
if (!globals)
|
||||||
goto done;
|
goto error;
|
||||||
code = PyCode_NewEmpty(filename, funcname, lineno);
|
code = PyCode_NewEmpty(filename, funcname, lineno);
|
||||||
if (!code)
|
if (!code) {
|
||||||
goto done;
|
Py_DECREF(globals);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
|
frame = PyFrame_New(PyThreadState_Get(), code, globals, NULL);
|
||||||
|
Py_DECREF(globals);
|
||||||
|
Py_DECREF(code);
|
||||||
if (!frame)
|
if (!frame)
|
||||||
goto done;
|
goto error;
|
||||||
frame->f_lineno = lineno;
|
frame->f_lineno = lineno;
|
||||||
|
|
||||||
PyErr_Restore(exception, value, tb);
|
PyErr_Restore(exc, val, tb);
|
||||||
PyTraceBack_Here(frame);
|
PyTraceBack_Here(frame);
|
||||||
|
Py_DECREF(frame);
|
||||||
|
return;
|
||||||
|
|
||||||
done:
|
error:
|
||||||
Py_XDECREF(globals);
|
_PyErr_ChainExceptions(exc, val, tb);
|
||||||
Py_XDECREF(code);
|
|
||||||
Py_XDECREF(frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
|
Loading…
Reference in New Issue