From owner-freebsd-hackers Thu Feb 22 23:52:15 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from gull.prod.itd.earthlink.net (gull.prod.itd.earthlink.net [207.217.121.85]) by hub.freebsd.org (Postfix) with ESMTP id 838B637B401 for ; Thu, 22 Feb 2001 23:52:09 -0800 (PST) (envelope-from fmela0@sm.socccd.cc.ca.us) Received: from sm.socccd.cc.ca.us (pool0451.cvx15-bradley.dialup.earthlink.net [209.179.45.196]) by gull.prod.itd.earthlink.net (EL-8_9_3_3/8.9.3) with ESMTP id XAA28552 for ; Thu, 22 Feb 2001 23:52:07 -0800 (PST) Message-ID: <3A96176A.CFE695F@sm.socccd.cc.ca.us> Date: Thu, 22 Feb 2001 23:55:22 -0800 From: Farooq Mela Reply-To: fmela0@sm.socccd.cc.ca.us X-Mailer: Mozilla 4.75 [en] (X11; U; FreeBSD 4.2-STABLE i386) X-Accept-Language: en MIME-Version: 1.0 To: freebsd-hackers@FreeBSD.ORG Subject: Re: Setting memory allocators for library functions. References: <200102230728.f1N7SW619041@guild.plethora.net> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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