summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-10-22 22:17:41 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-10-22 22:17:41 (GMT)
commitfd14d8e18723665578efe0a1416b134906075b78 (patch)
tree3a1c46b6c6db07e6d74b1ff269989721e24ffb6a
parentd703057752d52cef6082a920879a0b62cdeffaca (diff)
downloadcpython-fd14d8e18723665578efe0a1416b134906075b78.zip
cpython-fd14d8e18723665578efe0a1416b134906075b78.tar.gz
cpython-fd14d8e18723665578efe0a1416b134906075b78.tar.bz2
Make traceback objects collectable.
This should eliminate the traceback returned by sys.exc_info() as a common source of memory leaks.
-rw-r--r--Python/traceback.c48
1 files 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;
}