Discussion:
GNUstep, Valgring and Memory leaks.
(too old to reply)
Ronan Collobert
2004-08-31 09:50:44 UTC
Permalink
Hello,

I am a developper of a large "machine learning" library (see
www.torch.ch). Until now, we were using C++, but for many reasons we would
like to switch to Objective-C. Preliminary comparisons showed that
performances of Objective-C and GNUstep-foundation for our problems is
really great.

However, one of my main concern is debugging facilities in Objective-C. We
used to employ valgrind (http://valgrind.kde.org/) a lot (in particular
for leak problems detection). Unfortunately, it seems that many small
leaks occurs when using GNUstep (see in attachment the output of valgrind,
for the base example dictionary.m). Some leaks are related to the objc
library, some to the ld library, and some to the GNUstep library.

Many of these leaks are not really important (it is for example memory
allocated in NSObject:initialize only once, or memory allocated for the
locales in NSProcessInfo) but still, it becomes quickly annoying to find
our own memory problem with such an output.

Also, it seems that valgrind is lost with the Objective-C object
allocation: if we do not free an object, valgrind seems not to see the
correct line in the code where the object was allocated.

Are you guys using valgrind with GNUstep, and if yes, how do you deal with
memory leaks detection? Do you believe that the memory leaks mentioned
above will be corrected in the near future?

Regards,
Ronan.
Richard Frith-Macdonald
2004-08-31 10:47:22 UTC
Permalink
Post by Ronan Collobert
However, one of my main concern is debugging facilities in
Objective-C. We
used to employ valgrind (http://valgrind.kde.org/) a lot (in particular
for leak problems detection).
GNUstep has quite a lot of debugging facilities built in ... see
NSDebug.h in
the base library for information about debugging object
allocation/deallocation.
Post by Ronan Collobert
Unfortunately, it seems that many small
leaks occurs when using GNUstep (see in attachment the output of valgrind,
for the base example dictionary.m). Some leaks are related to the objc
library, some to the ld library, and some to the GNUstep library.
Many of these leaks are not really important (it is for example memory
allocated in NSObject:initialize only once, or memory allocated for the
locales in NSProcessInfo) but still, it becomes quickly annoying to find
our own memory problem with such an output.
Also, it seems that valgrind is lost with the Objective-C object
allocation: if we do not free an object, valgrind seems not to see the
correct line in the code where the object was allocated.
Are you guys using valgrind with GNUstep,
I can't speak for anyone else, but I don't use it.
Post by Ronan Collobert
and if yes, how do you deal with
memory leaks detection? Do you believe that the memory leaks mentioned
above will be corrected in the near future?
As I'm not familiar with valgrind, I can't be sure about what the
reports mean.
If bug reports for memory leaks which have a real impact are filed,
they will
get fixed as a high priority, but my impression is that the log is
identifying
situations I would not call leaks ... if memory is intentionally
allocated for
the lifetime of the process and never explicitly freed, I wouldn't call
it a leak.
As you mention, this is often the case in +initialize methods.
If there is a cheap, simple way to tell valgrind about these situations
(or
a trivial way to alter the code to avoid worrying valgrind) I'd happily
accept
patches to do it.

I know that there are also situations where there are intentional leaks
...
ie. where memory is deliberately leaked because freeing it is difficult
for
some reason, and the leak should not be a problem. For instance,
libobjc (part of gcc rather than gnustep) does this when changing class
lookup tables ... so that it can avoid having to lock protect all code
using
the tables in a multi-threaded environment. The leaked version of the
table is there so that another thread which happens to be using the
table at the point when it is updated will be able to continue correctly
without crashing. The only reason this is not utterly horrible is that
these tables are only rarely changed. It would be better if this leak
was
fixed, but it's not seen as high priority by the gcc maintainers.
Nicola Pero
2004-08-31 11:06:08 UTC
Permalink
I know that there are also situations where there are intentional leaks ...
ie. where memory is deliberately leaked because freeing it is difficult for
some reason, and the leak should not be a problem. For instance,
libobjc (part of gcc rather than gnustep) does this when changing class
lookup tables ... so that it can avoid having to lock protect all code using
the tables in a multi-threaded environment. The leaked version of the
table is there so that another thread which happens to be using the
table at the point when it is updated will be able to continue correctly
without crashing. The only reason this is not utterly horrible is that
these tables are only rarely changed. It would be better if this leak was
fixed, but it's not seen as high priority by the gcc maintainers.
Good explanation

The leak is there because it's impossible to fix it ... unless you add
locking, which would slow down things considerably (the whole point of all
the design of this stuff is precisely to avoid locking).

It's a trade-off -- you could either use locks, or accept that you might
be going to waste (once) a little bit of memory per process. By a little
bit I mean something between a few hundreds to a few thousands bytes, I
don't remember how the tables are sized, but it's not more than that, and
it's normally going to happen only at startup when you load all the
classes. If you load dynamically more classes again later, it might
happen again, but it's very rare unless you're dynamically loading
thousands of classes.

Nowadays those few hundreds/thousands bytes leaked once at startup (or
potentially when a very large framework or library is loaded) are nothing,
while locking/unlocking every time you access any of those tables, for the
whole process execution, can affect speed considerably.

If someone is so worried about a those bytes of memory, I suppose libobjc
could have a compile-time option to turn on locking and deallocating
memory properly once the tables are extended. That might be useful for
embedded systems or systems where RAM/memory is really tight. It makes no
sense on a PC, where you definitely want to avoid the locking, as that
will give you measurable speed-ups, while you don't care about a few
hundred lost bytes at startup which has no impact whatsoever on your
application.

Anyway, yes I suppose that might be a "fix", it could be done, but I
wouldn't recommend anyone using it. :-)
Matt Rice
2004-08-31 23:19:13 UTC
Permalink
--- Richard Frith-Macdonald <***@brainstorm.co.uk>
wrote:
<snip>
Post by Richard Frith-Macdonald
If there is a cheap, simple way to tell valgrind
about these situations
there is, you can create suppressions files
http://electra.lbl.gov/ATLAS/valgrind_HOWTO.html#SUPPRESSION


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Ronan Collobert
2004-09-01 11:30:16 UTC
Permalink
Hey,

Thanks for all your answers, I will live with those memory leaks.

Note that concerning the use of valgrind with GNUstep, there is a tricky
"bug" in NSProcessInfo related to the processing of the arguments argv[]
given to the program:

On my computer (an intel linux debian testing machine), NSProcessInfo
reads the arguments argv[] using what is given in
/proc/<processid>/cmdline. When launching a GNUstep program with a command
such as:
valgrind --tool=memcheck mygnustepprogram myargs

then if in "mygnustepprogram" I use
[[NSProcessInfo processInfo] arguments] to obtain the command line
arguments, they will contain all the command line, including valgrind
arguments:
valgrind --tool=memcheck mygnustepprogram myargs

This is very weird, because the arguments given directly with
main(int argc, char **argv)
contain the correct answer:
mygnustepprogram myargs

It seems that in this special case, reading /proc is not a good idea. I
had a look on the code of valgrind: they load "by hand" the program into
memory. Note that a command line like:
/usr/bin/time -p mygnustepprogram myargs

will work fine with NSProcessInfo (time is using a standard "execvp"
system call).

Ronan.
Post by Matt Rice
<snip>
Post by Richard Frith-Macdonald
If there is a cheap, simple way to tell valgrind
about these situations
there is, you can create suppressions files
http://electra.lbl.gov/ATLAS/valgrind_HOWTO.html#SUPPRESSION
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
Loading...