From fd14d8e18723665578efe0a1416b134906075b78 Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Mon, 22 Oct 2001 22:17:41 +0000 Subject: Make traceback objects collectable. This should eliminate the traceback returned by sys.exc_info() as a common source of memory leaks. --- Python/traceback.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/Python/traceback.c b/Python/traceback.c index 539483d..7bbf852 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -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; } -- cgit v0.12