Plug leak of stack frame object in exception handling code.

Also delay DECREF calls until after the structures have been updated
(for reentrancy awareness).
This commit is contained in:
Guido van Rossum 1997-05-20 17:06:11 +00:00
parent 32f92caa98
commit df4c308f5a

View file

@ -1755,31 +1755,41 @@ set_exc_info(tstate, type, value, tb)
PyObject *tb; PyObject *tb;
{ {
PyFrameObject *frame; PyFrameObject *frame;
PyObject *tmp_type, *tmp_value, *tmp_tb;
frame = tstate->frame; frame = tstate->frame;
if (frame->f_exc_type == NULL) { if (frame->f_exc_type == NULL) {
/* This frame didn't catch an exception before */ /* This frame didn't catch an exception before */
/* Save previous exception of this thread in this frame */ /* Save previous exception of this thread in this frame */
Py_XDECREF(frame->f_exc_type);
Py_XDECREF(frame->f_exc_value);
Py_XDECREF(frame->f_exc_traceback);
if (tstate->exc_type == NULL) { if (tstate->exc_type == NULL) {
Py_INCREF(Py_None); Py_INCREF(Py_None);
tstate->exc_type = Py_None; tstate->exc_type = Py_None;
} }
tmp_type = frame->f_exc_type;
tmp_value = frame->f_exc_value;
tmp_tb = frame->f_exc_traceback;
Py_XINCREF(tstate->exc_type); Py_XINCREF(tstate->exc_type);
Py_XINCREF(tstate->exc_value); Py_XINCREF(tstate->exc_value);
Py_XINCREF(tstate->exc_traceback); Py_XINCREF(tstate->exc_traceback);
frame->f_exc_type = tstate->exc_type; frame->f_exc_type = tstate->exc_type;
frame->f_exc_value = tstate->exc_value; frame->f_exc_value = tstate->exc_value;
frame->f_exc_traceback = tstate->exc_traceback; frame->f_exc_traceback = tstate->exc_traceback;
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
} }
/* Set new exception for this thread */ /* Set new exception for this thread */
tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value;
tmp_tb = tstate->exc_traceback;
Py_XINCREF(type); Py_XINCREF(type);
Py_XINCREF(value); Py_XINCREF(value);
Py_XINCREF(tb); Py_XINCREF(tb);
tstate->exc_type = type; tstate->exc_type = type;
tstate->exc_value = value; tstate->exc_value = value;
tstate->exc_traceback = tb; tstate->exc_traceback = tb;
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
/* For b/w compatibility */ /* For b/w compatibility */
PySys_SetObject("exc_type", type); PySys_SetObject("exc_type", type);
PySys_SetObject("exc_value", value); PySys_SetObject("exc_value", value);
@ -1791,29 +1801,36 @@ reset_exc_info(tstate)
PyThreadState *tstate; PyThreadState *tstate;
{ {
PyFrameObject *frame; PyFrameObject *frame;
PyObject *tmp_type, *tmp_value, *tmp_tb;
frame = tstate->frame; frame = tstate->frame;
if (frame->f_exc_type != NULL) { if (frame->f_exc_type != NULL) {
/* This frame caught an exception */ /* This frame caught an exception */
Py_XDECREF(tstate->exc_type); tmp_type = tstate->exc_type;
Py_XDECREF(tstate->exc_value); tmp_value = tstate->exc_value;
Py_XDECREF(tstate->exc_traceback); tmp_tb = tstate->exc_traceback;
Py_XINCREF(frame->f_exc_type); Py_XINCREF(frame->f_exc_type);
Py_XINCREF(frame->f_exc_value); Py_XINCREF(frame->f_exc_value);
Py_XINCREF(frame->f_exc_traceback); Py_XINCREF(frame->f_exc_traceback);
tstate->exc_type = frame->f_exc_type; tstate->exc_type = frame->f_exc_type;
tstate->exc_value = frame->f_exc_value; tstate->exc_value = frame->f_exc_value;
tstate->exc_traceback = frame->f_exc_traceback; tstate->exc_traceback = frame->f_exc_traceback;
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
/* For b/w compatibility */ /* For b/w compatibility */
PySys_SetObject("exc_type", frame->f_exc_type); PySys_SetObject("exc_type", frame->f_exc_type);
PySys_SetObject("exc_value", frame->f_exc_value); PySys_SetObject("exc_value", frame->f_exc_value);
PySys_SetObject("exc_traceback", frame->f_exc_traceback); PySys_SetObject("exc_traceback", frame->f_exc_traceback);
} }
Py_XDECREF(frame->f_exc_type); tmp_type = frame->f_exc_type;
Py_XDECREF(frame->f_exc_value); tmp_value = frame->f_exc_value;
Py_XDECREF(frame->f_exc_traceback); tmp_tb = frame->f_exc_traceback;
frame->f_exc_type = NULL; frame->f_exc_type = NULL;
frame->f_exc_value = NULL; frame->f_exc_value = NULL;
frame->f_exc_traceback = NULL; frame->f_exc_traceback = NULL;
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
} }
/* Logic for the raise statement (too complicated for inlining). /* Logic for the raise statement (too complicated for inlining).