Skip to content

Commit 89294e9

Browse files
author
jhylton
committed
Make traceback objects collectable.
This should eliminate the traceback returned by sys.exc_info() as a common source of memory leaks. git-svn-id: http://svn.python.org/projects/python/trunk@23894 6015fed2-1504-0410-9fe1-9d1591cc4771
1 parent 0c5daf6 commit 89294e9

1 file changed

Lines changed: 46 additions & 2 deletions

File tree

Python/traceback.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,36 @@ static void
3636
tb_dealloc(tracebackobject *tb)
3737
{
3838
Py_TRASHCAN_SAFE_BEGIN(tb)
39+
_PyObject_GC_UNTRACK(tb);
3940
Py_XDECREF(tb->tb_next);
4041
Py_XDECREF(tb->tb_frame);
41-
PyObject_DEL(tb);
42+
PyObject_GC_Del(tb);
4243
Py_TRASHCAN_SAFE_END(tb)
4344
}
4445

46+
static int
47+
tb_traverse(tracebackobject *tb, visitproc visit, void *arg)
48+
{
49+
int err = 0;
50+
if (tb->tb_next) {
51+
err = visit((PyObject *)tb->tb_next, arg);
52+
if (err)
53+
return err;
54+
}
55+
if (tb->tb_frame)
56+
err = visit((PyObject *)tb->tb_frame, arg);
57+
return err;
58+
}
59+
60+
static void
61+
tb_clear(tracebackobject *tb)
62+
{
63+
Py_XDECREF(tb->tb_next);
64+
Py_XDECREF(tb->tb_frame);
65+
tb->tb_next = NULL;
66+
tb->tb_frame = NULL;
67+
}
68+
4569
PyTypeObject PyTraceBack_Type = {
4670
PyObject_HEAD_INIT(&PyType_Type)
4771
0,
@@ -57,6 +81,25 @@ PyTypeObject PyTraceBack_Type = {
5781
0, /*tp_as_number*/
5882
0, /*tp_as_sequence*/
5983
0, /*tp_as_mapping*/
84+
0, /* tp_hash */
85+
0, /* tp_call */
86+
0, /* tp_str */
87+
0, /* tp_getattro */
88+
0, /* tp_setattro */
89+
0, /* tp_as_buffer */
90+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
91+
0, /* tp_doc */
92+
(traverseproc)tb_traverse, /* tp_traverse */
93+
(inquiry)tb_clear, /* tp_clear */
94+
0, /* tp_richcompare */
95+
0, /* tp_weaklistoffset */
96+
0, /* tp_iter */
97+
0, /* tp_iternext */
98+
0, /* tp_methods */
99+
0, /* tp_members */
100+
0, /* tp_getset */
101+
0, /* tp_base */
102+
0, /* tp_dict */
60103
};
61104

62105
static tracebackobject *
@@ -69,14 +112,15 @@ newtracebackobject(tracebackobject *next, PyFrameObject *frame, int lasti,
69112
PyErr_BadInternalCall();
70113
return NULL;
71114
}
72-
tb = PyObject_NEW(tracebackobject, &PyTraceBack_Type);
115+
tb = PyObject_GC_New(tracebackobject, &PyTraceBack_Type);
73116
if (tb != NULL) {
74117
Py_XINCREF(next);
75118
tb->tb_next = next;
76119
Py_XINCREF(frame);
77120
tb->tb_frame = frame;
78121
tb->tb_lasti = lasti;
79122
tb->tb_lineno = lineno;
123+
_PyObject_GC_TRACK(tb);
80124
}
81125
return tb;
82126
}

0 commit comments

Comments
 (0)