Make traceback objects collectable.

This should eliminate the traceback returned by sys.exc_info() as a
common source of memory leaks.
This commit is contained in:
Jeremy Hylton 2001-10-22 22:17:41 +00:00
parent d703057752
commit fd14d8e187
1 changed files with 46 additions and 2 deletions

View File

@ -36,12 +36,36 @@ static void
tb_dealloc(tracebackobject *tb)
{
Py_TRASHCAN_SAFE_BEGIN(tb)
_PyObject_GC_UNTRACK(tb);
Py_XDECREF(tb->tb_next);
Py_XDECREF(tb->tb_frame);
PyObject_DEL(tb);
PyObject_GC_Del(tb);
Py_TRASHCAN_SAFE_END(tb)
}
static int
tb_traverse(tracebackobject *tb, visitproc visit, void *arg)
{
int err = 0;
if (tb->tb_next) {
err = visit((PyObject *)tb->tb_next, arg);
if (err)
return err;
}
if (tb->tb_frame)
err = visit((PyObject *)tb->tb_frame, arg);
return err;
}
static void
tb_clear(tracebackobject *tb)
{
Py_XDECREF(tb->tb_next);
Py_XDECREF(tb->tb_frame);
tb->tb_next = NULL;
tb->tb_frame = NULL;
}
PyTypeObject PyTraceBack_Type = {
PyObject_HEAD_INIT(&PyType_Type)
0,
@ -57,6 +81,25 @@ PyTypeObject PyTraceBack_Type = {
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
(traverseproc)tb_traverse, /* tp_traverse */
(inquiry)tb_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
};
static tracebackobject *
@ -69,7 +112,7 @@ newtracebackobject(tracebackobject *next, PyFrameObject *frame, int lasti,
PyErr_BadInternalCall();
return NULL;
}
tb = PyObject_NEW(tracebackobject, &PyTraceBack_Type);
tb = PyObject_GC_New(tracebackobject, &PyTraceBack_Type);
if (tb != NULL) {
Py_XINCREF(next);
tb->tb_next = next;
@ -77,6 +120,7 @@ newtracebackobject(tracebackobject *next, PyFrameObject *frame, int lasti,
tb->tb_frame = frame;
tb->tb_lasti = lasti;
tb->tb_lineno = lineno;
_PyObject_GC_TRACK(tb);
}
return tb;
}