|
From: Salvador E. T. <sal...@in...> - 2004-06-11 18:15:55
|
Hi All!
May be my question is stupid but:
The glibc implementation of putenv doesn=B4t copy the string you pass.
It means that you can=B4t do it:
void Function(char *val)
{
char buffer[20];
snprintf(buffer,20,"VAR=3D%s",val);
putenv(buffer);
}
That=B4s because buffer will be invalid as soon as you leave "Function"=20
and putenv have a reference and not a copy.
So you have to do something like it:
void Function(char *val)
{
char buffer[20];
snprintf(buffer,20,"VAR=3D%s",val);
putenv(strdup(buffer));
}
But the valgrind is quite sure you leaked.
What=B4s the solution? In my current code I have:
char *b=3Dnew char[8+strlen(tmp)];
sprintf(b,"TMPDIR=3D%s",tmp);
putenv(b);
And valgrind reports the leak in the new, it means I have to use a=20
suppression for each point in the code where I do it and I can=B4t ask to=
=20
ignore all the pointers passed to putenv.
Is that the way to go?
Regards, SET
--=20
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Visit my home page: http://welcome.to/SetSoft or
http://www.geocities.com/SiliconValley/Vista/6552/
Alternative e-mail: se...@co... se...@ie...=20
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013
|
|
From: Oswald B. <os...@kd...> - 2004-06-11 22:42:49
|
On Fri, Jun 11, 2004 at 03:15:54PM -0300, Salvador Eduardo Tropea wrote: > What´s the solution? > there is no universal one. either always use the leaking version or make a configure check ... greetings -- Hi! I'm a .signature virus! Copy me into your ~/.signature, please! -- Chaos, panic, and disorder - my work here is done. |
|
From: Tom H. <th...@cy...> - 2004-06-12 16:10:16
|
In message <40C...@in...>
Salvador Eduardo Tropea <sal...@in...> wrote:
> That´s because buffer will be invalid as soon as you leave "Function"
> and putenv have a reference and not a copy.
> So you have to do something like it:
>
> void Function(char *val)
> {
> char buffer[20];
> snprintf(buffer,20,"VAR=%s",val);
> putenv(strdup(buffer));
> }
>
> But the valgrind is quite sure you leaked.
The reason for this appears to be that although libc takes a copy
of the pointer the structure in which that pointer is held is freed
when the programs exits and valgrind calls __libc_freeres to make
libc free it's resources.
It doesn't free the pointer you passed to putenv however as it can't
know how it was allocated. If you run with --run-libc-freeres=no then
you'll find that valgrind doesn't complain. That might cause other
problems however.
> What´s the solution?
I'm not sure there is a good one I'm afraid.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Salvador E. T. <sal...@in...> - 2004-06-14 14:55:40
|
Tom Hughes wrote:
>>What=B4s the solution?
>> =20
>>
>
>I'm not sure there is a good one I'm afraid.
> =20
>
Thanks (also to Oswald). I=B4m currently using some suppressions to just =
avoid the message.
BTW: Linux glibc 2.2.5 doesn=B4t make a copy of the string, the following=
=20
test program shows it:
<-------------------
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char s[]=3D"XXX=3DYYY", *x;
putenv(s);
x=3Dgetenv("XXX");
printf("%p vs %p\n",s,x);
x[1]=3D'p';
printf("s: %s\n",s);
return 0;
}
<-------------------
Here modifications to the value returned by getenv are reflected in the=20
value we passed to putenv, the pointers are the same.
Regards, SET
--=20
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Visit my home page: http://welcome.to/SetSoft or
http://www.geocities.com/SiliconValley/Vista/6552/
Alternative e-mail: se...@co... se...@ie...=20
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA Phone: +(5411) 4759 0013
|
|
From: Tom H. <th...@cy...> - 2004-06-14 16:26:03
|
In message <40C...@in...>
Salvador Eduardo Tropea <sal...@in...> wrote:
> BTW: Linux glibc 2.2.5 doesn´t make a copy of the string, the
> following test program shows it:
It won't make a copy of the string. That's the whole problem and is
why you need to allocate persistent storage for the string.
What is does do is have an allocated buffer that contains all the
pointers that have been passed to putenv. When the program exits that
buffer is freed and the pointer is lost so it winds up looking like
the memory given to putenv has been lost, which is has in fact, but
only for those few milliseconds during program exit.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Olly B. <ol...@su...> - 2004-06-16 13:30:58
|
On 2004-06-14, Tom Hughes <th...@cy...> wrote:
> What is does do is have an allocated buffer that contains all the
> pointers that have been passed to putenv. When the program exits that
> buffer is freed and the pointer is lost so it winds up looking like
> the memory given to putenv has been lost, which is has in fact, but
> only for those few milliseconds during program exit.
Couldn't valgrind intercept putenv() and track pointers passed, and not
report them as leaks? There's a slight wrinkle since you want to only
exclude the last pointer passed for a given variable name - so you
really need a parallel structure to that which glibc must have.
Cheers,
Olly
|