Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 22 Feb 2001 23:55:22 -0800
From:      Farooq Mela <fmela0@sm.socccd.cc.ca.us>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: Setting memory allocators for library functions.
Message-ID:  <3A96176A.CFE695F@sm.socccd.cc.ca.us>
References:  <200102230728.f1N7SW619041@guild.plethora.net>

next in thread | previous in thread | raw e-mail | index | archive | help
Peter Seebach wrote:
> 
> In message <3A961004.723691C9@sm.socccd.cc.ca.us>, Farooq Mela writes:
> >Of course I realize that allocating memory can fail. That is why I use
> >xmalloc and friends - so that I can avoid having to check for failure
> >each time I want to allocate memory.
> 
> That's the problem.  You still *NEED* to check.  You can't just exit; you
> have to figure out what you have open, and close it.  You have to figure
> out what files you may have been halfway through writing, and make sure that
> you aren't about to leave a critical file half-written, with the only copy
> of the rest of the data somewhere in memory.
> 
> It is very, very, rarely correct to say "oops, no memory, I will quit
> immediately without saving any work".
> 

This is not what I am arguing. I gave a simple example of an xmalloc
function which does just print an error and exit. However, I've written
many large applications using this sort of scheme where when allocation
fails, all sorts of cleanup is performed before the process exits
(cleaning up & restoring terminal mode, gracefully closing files /
sockets / etc, syslogging the event, etc). It is hardly ever a simple
exit as soon as allocation fails.

[snip] 

> There are very few programs where it is acceptable to abort just because
> you ran out of memory.
> 
> >I don't believe you understand what
> >I am proposing.
> 
> I do, lots of programs do it.  It's a bad idea.  You really still do have
> to check, because in almost all cases, there will be stuff you should do
> on your way down, beyond just "exit".
> 
> >It will still have to check for the allocation failing. But if this were
> >to be done, an application which installs its own allocators will not
> >have to worry about anything inside libc running out of memory, and will
> >not have to handle that error condition.
> 
> Of course it will!  It can't guarantee that the memory is available, and
> it can't guarantee that it cleans up properly, because "proper cleanup" may
> vary from one place to another.

What I mean here is that the *application* will not have to handle that
error condition. It will be handled by the the malloc wrapper(s).

> 
> >Furthermore, inside the
> >user-defined allocator (xmalloc etc), other types of cleanup can be
> >handled if the real malloc() returns NULL. (Atexit can only do so much.)
> 
> Exactly.  Atexit *can't do enough*.
> 
> Each individual place where you do something that *could* fail must be
> checked, and the failure handled correctly *for that place*.
> 
> You can't short-cut this; if you do, your code will inevitably fail in
> the most inconvenient possible way, because computers are ornery.
> 
> Yes, it's a lot of work checking for every single error that could occur,
> and handling it in a graceful fashion.  However, it is *MUCH* better
> for, say, gethostbyname to set errno to ENOMEM and return a null pointer,
> than for gethostbyname to ritually suicide the entire program.
> 
> The allocator which spews an error and dies is almost always an incorrect
> allocator.  There may be counterexamples, but they're rare, and since all
> of the relevant library functions can probably fail *FOR OTHER REASONS*,
> you still have to check all the return values and handle them yourself.

Yes, but you would not have to write code which checks for ENOMEM. I
will bet that the error handling code you write for getcwd giving ENOENT
is very different from the code which handles ENOMEM from getcwd.

I never write programs in which I must check the return value of each
and every call to malloc/realloc/etc. It would be a lot of repetitive
code. That is exactly why I use malloc wrappers, which then do all the
required cleanup if allocation fails. It is actually a very effective
system if done correctly, and makes life easier for me at least ;-). I
would rather not have to check the return value from something like
memory allocation, which is done very often in programs, and in todays
VM systems, doesnt fail until all swap space is consumed.

> 
> Even if you can prove that getaddrinfo can never fail because malloc failed,
> it can still fail for other reasons.  You still have to check for it failing.
> "Fixing" the allocator doesn't remove the need to check the return of every
> function that can fail.

Indeed. Getaddrinfo is an example of a function that can fail for other
reasons. But something such as asprintf or getcwd, etc, it is annoying
to have to write code which will perform the cleanup that a malloc
wrapper would otherwise execute.

I just believe it would be a convenience to programmers if this system
could be implemented. If someone prefers not to use it, and check each
return value, that is fine; they are not required to use it.

-Farooq

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3A96176A.CFE695F>