[Python-Dev] refleak hunting season

Neal Norwitz neal at metaslash.com
Tue Aug 3 06:20:18 CEST 2004


On Mon, Aug 02, 2004 at 03:39:36PM +0100, Michael Hudson wrote:
> 
> test_sax leaked [1899, 1899, 1899, 1899] references
>     no idea -- scary numbers, though!

It looks like the worst (only?) leakers are:

        test_expat_incomplete
        test_expat_inpsource_location

Both of these cause exceptions to be raised.  I don't know the pyexpat
code at all.  But I think I fixed a few leaks with the attached patch.
Some leaks were caught by the tests, but I doubt all were.  The patch
is a starting point if anyone else wants to give it a shot.  If not,
I'll add it to SF or review carefully and check in later.

Neal
-------------- next part --------------
Index: Modules/pyexpat.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v
retrieving revision 2.84
diff -u -w -r2.84 pyexpat.c
--- Modules/pyexpat.c	12 Oct 2003 19:09:37 -0000	2.84
+++ Modules/pyexpat.c	3 Aug 2004 04:14:27 -0000
@@ -104,12 +104,12 @@
 set_error_attr(PyObject *err, char *name, int value)
 {
     PyObject *v = PyInt_FromLong(value);
+    int rc = 0;
 
-    if (v != NULL && PyObject_SetAttrString(err, name, v) == -1) {
-        Py_DECREF(v);
-        return 0;
-    }
-    return 1;
+    if (v != NULL)
+        rc = PyObject_SetAttrString(err, name, v) != -1;
+    Py_XDECREF(v);
+    return rc;
 }
 
 /* Build and set an Expat exception, including positioning
@@ -359,7 +359,7 @@
 {
     PyThreadState *tstate = PyThreadState_GET();
     PyFrameObject *f;
-    PyObject *res;
+    PyObject *res = NULL;
 
     if (c == NULL)
         return NULL;
@@ -370,7 +370,7 @@
     tstate->frame = f;
 #ifdef FIX_TRACE
     if (trace_frame(tstate, f, PyTrace_CALL, Py_None) < 0) {
-	return NULL;
+	goto cleanup;
     }
 #endif
     res = PyEval_CallObject(func, args);
@@ -379,7 +379,7 @@
 	    PyTraceBack_Here(f);
 #ifdef FIX_TRACE
 	if (trace_frame_exc(tstate, f) < 0) {
-	    return NULL;
+	    goto cleanup;
 	}
     }
     else {
@@ -391,6 +391,7 @@
 #else
     }
 #endif
+cleanup:
     tstate->frame = f->f_back;
     Py_DECREF(f);
     return res;
@@ -996,6 +997,7 @@
         if (fp) {
             bytes_read = fread(buf, sizeof(char), BUF_SIZE, fp);
             if (bytes_read < 0) {
+                Py_XDECREF(readmethod);
                 PyErr_SetFromErrno(PyExc_IOError);
                 return NULL;
             }


More information about the Python-Dev mailing list