Bug report: memory leak in python 1.5.2
Michael P. Reilly
arcege at shore.net
Wed May 26 16:23:07 EDT 1999
Fred L. Drake <fdrake at cnri.reston.va.us> wrote:
: M.-A. Lemburg writes:
: > Don't why the free(new); is missing though... maybe some putenv()
: > implementation expect a malloced string (the putenv implementation
: > in posixmodule.c for NeXT does) while other make a copy first.
: At least on Solaris, the malloc()'ed memory must survive until the
: same key is re-used.
: I think using a Python string for the malloc()'ed memory is
: acceptable (it's just a buffer, after all). I took a stab at using a
: dictionary to "cache" the last string passed to putenv() for each key;
: when using the same key again, the old value is removed from the
: dictionary and deleted. Greg's code doesn't appear to leak with my
: patch, at any rate (running for over 7 minutes on a 200Mhz
: UltraSPARC).
: I've appended the patch below for others to try out and verify. If
: others get positive results and can't think of reasons not to accept
: this, perhaps I can knock Guido over the head with it when he gets
: back to town. ;-)
There is also the situation where some UNIX systems put the environment
initially in the u area, and it is difficult to programmatically determine
where different runtime segments are (where is the heap vs. where is the
u area).
Fred, your solution should work because it takes the problem case: what
to do with the string initially, but I think it might be better to copy
the values at module initialization time. I've included an addition to
Fred's patch to be called instead of the PyDict_New() function (in the
module init function).
Also, how should we deal with this in terms of C applications who might
change the environment? (Embedders beware!)
>From a programming standpoint, I don't think that it should be "proper"
to be changing the environment all that much. It's purpose is to
propragate values to child processes, not to store runtime values.
-Arcege
Example environment initialization schema (based on Fred Drake's patch).
PyObject *
system_environ_initialize(environ)
char **environ;
{ int i;
char **p;
PyObject *putenv_garbage;
PyObject *key, *env;
if ((posix_putenv_garbage = PyDict_New()) == NULL)
return NULL;
/* populate the dictionary with the values from the environment */
for (p = environ; *p; p++)
/* get the name of the environment variable */
for (i = 0; (*p)[i] && (*p)[i] != '='; i++) ;
key = PyString_FromStringAndSize(*p, i);
env = PyString_FromString(*p);
PyDict_SetItem(posix_putenv_garbage, key, env);
Py_DECREF(key);
Py_DECREF(env);
}
i = 0;
/* rewrite the entire environment with Python strings */
/* we rewrite the entire environment after reading it, not while
reading the address locations */
while (PyDict_Next(posix_putenv_garbage, &i, &key, &env))
putenv(PyString_AS_STRING(env));
return posix_putenv_garbage;
}
More information about the Python-list
mailing list