From 7bcabc60a36eb5910bd162d54ece449f5249bbcd Mon Sep 17 00:00:00 2001 From: Neal Norwitz Date: Sun, 20 Nov 2005 23:58:38 +0000 Subject: Fix a few more memory leaks Document more info about the benefits of configuring without pymalloc when running valgrind --- Misc/README.valgrind | 16 +++++++++++++++- Python/ast.c | 12 ++++++++++-- Python/compile.c | 3 +++ Python/modsupport.c | 1 + 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/Misc/README.valgrind b/Misc/README.valgrind index 8e480e9..157bdc3 100644 --- a/Misc/README.valgrind +++ b/Misc/README.valgrind @@ -12,6 +12,19 @@ Misc/valgrind-python.supp. Second, you must do one of the following: * Uncomment the lines in Misc/valgrind-python.supp that suppress the warnings for PyObject_Free and PyObject_Realloc +If you want to use Valgrind more effectively and catch even more +memory leaks, you will need to configure python --without-pymalloc. +PyMalloc allocates a few blocks in big chunks and most object +allocations don't call malloc, they use chunks doled about by PyMalloc +from the big blocks. This means Valgrind can't detect +many allocations (and frees), except for those that are forwarded +to the system malloc. Note: configuring python --without-pymalloc +makes Python run much slower, especially when running under Valgrind. +You may need to run the tests in batches under Valgrind to keep +the memory usage down to allow the tests to complete. It seems to take +about 5 times longer to run --without-pymalloc. + + Details: -------- Python uses its own small-object allocation scheme on top of malloc, @@ -21,7 +34,8 @@ Valgrind may show some unexpected results when PyMalloc is used. Starting with Python 2.3, PyMalloc is used by default. You can disable PyMalloc when configuring python by adding the --without-pymalloc option. If you disable PyMalloc, most of the information in this document and -the supplied suppressions file will not be useful. +the supplied suppressions file will not be useful. As discussed above, +disabling PyMalloc can catch more problems. If you use valgrind on a default build of Python, you will see many errors like: diff --git a/Python/ast.c b/Python/ast.c index 87a9a4b..731bf9a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -1054,8 +1054,12 @@ ast_for_listcomp(struct compiling *c, const node *n) return NULL; } - if (asdl_seq_LEN(t) == 1) + if (asdl_seq_LEN(t) == 1) { lc = comprehension(asdl_seq_GET(t, 0), expression, NULL); + /* only free the sequence since we grabbed element 0 above */ + if (lc) + asdl_seq_free(t); /* ok */ + } else lc = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL); @@ -1222,9 +1226,13 @@ ast_for_genexp(struct compiling *c, const node *n) return NULL; } - if (asdl_seq_LEN(t) == 1) + if (asdl_seq_LEN(t) == 1) { ge = comprehension(asdl_seq_GET(t, 0), expression, NULL); + /* only free the sequence since we grabbed element 0 above */ + if (ge) + asdl_seq_free(t); /* ok */ + } else ge = comprehension(Tuple(t, Store, LINENO(ch)), expression, NULL); diff --git a/Python/compile.c b/Python/compile.c index 4d637ae..5905c45 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2384,7 +2384,10 @@ compiler_import_as(struct compiler *c, identifier name, identifier asname) dot = strchr(src, '.'); attr = PyString_FromStringAndSize(src, dot ? dot - src : strlen(src)); + if (!attr) + return -1; ADDOP_O(c, LOAD_ATTR, attr, names); + Py_DECREF(attr); src = dot + 1; } } diff --git a/Python/modsupport.c b/Python/modsupport.c index 197d99b..fbfb48d 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -82,6 +82,7 @@ Py_InitModule4(char *name, PyMethodDef *methods, char *doc, } Py_DECREF(v); } + Py_DECREF(n); } if (doc != NULL) { v = PyString_FromString(doc); -- cgit v0.12