From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/2592 Path: news.gmane.org!not-for-mail From: Rich Felker Newsgroups: gmane.linux.lib.musl.general Subject: Re: malloc(0) behaviour Date: Mon, 14 Jan 2013 19:24:42 -0500 Message-ID: <20130115002442.GU20323@brightrain.aerifal.cx> References: <1358206649.32505.21@driftwood> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1358209494 9577 80.91.229.3 (15 Jan 2013 00:24:54 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Tue, 15 Jan 2013 00:24:54 +0000 (UTC) To: musl@lists.openwall.com Original-X-From: musl-return-2593-gllmg-musl=m.gmane.org@lists.openwall.com Tue Jan 15 01:25:13 2013 Return-path: Envelope-to: gllmg-musl@plane.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by plane.gmane.org with smtp (Exim 4.69) (envelope-from ) id 1TuuL2-0007fq-6w for gllmg-musl@plane.gmane.org; Tue, 15 Jan 2013 01:25:12 +0100 Original-Received: (qmail 11619 invoked by uid 550); 15 Jan 2013 00:24:55 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Original-Received: (qmail 11611 invoked from network); 15 Jan 2013 00:24:55 -0000 Content-Disposition: inline In-Reply-To: <1358206649.32505.21@driftwood> User-Agent: Mutt/1.5.21 (2010-09-15) Xref: news.gmane.org gmane.linux.lib.musl.general:2592 Archived-At: On Mon, Jan 14, 2013 at 05:37:29PM -0600, Rob Landley wrote: > On 01/14/2013 11:17:47 AM, Igmar Palsenberg wrote: > >Hi, > > > >Is there a (good) reason for Musl to follow glibc's malloc(0) > >behaviour ? > > Because not doing so breaks some programs? (Dunno if it still does, > but last time I tried switching that config option off in uClibc the > linux from scratch build didn't finish.) I don't think it breaks any programs; the ones that depend on malloc(0) returning nonzero seem to use either gnulib or their own hacks to wrap malloc if the system malloc does not have this behavior. However, the bug that originally prompted me to switch the behavior was that the detection could be broken. gnulib was compiling a tiny test program to check the behavior of malloc, and with musl, it got linked to __simple_malloc, which was giving the malloc(0)!=NULL behavior. The full program then got linked to real malloc (where malloc(0) was returning a null pointer), and horribly broke, reporting spurious allocation failures and aborting. At that time, I researched and discussed the topic and the conclusion reached was that malloc(0)!=NULL makes more sense. > >Musl returns a valid pointer, which is fine according > >to the standard, but returning NULL is also fine. > > > >IMHO, returning NULL is better : It usually kills the program if > >actual storage is > >attempted. > > It also kills the program if they're checking the return code of > malloc() and treating NULL as an allocation failure indicator. NULL > has a defined meaning of "failed", when a zero length allocation is > trivial to satisfy and not necessarily wrong. > > Should a zero length file read return -1 instead of 0? Is it the > program's job to make sure it never makes a NOP syscall? Does adding > special case checks in your code to avoid such NOP calls actually > make the code smaller and simpler? Indeed, another argument for malloc(0)!=NULL is to avoid having to write special-case code to handle it. Wrapping malloc with a function that replaces an argument of 0 with an argument of 1 is not just a hack to get "GNU behavior"; it's what you probably want to be doing anyway (even if there were no GNU to copy) if there's a chance you might pass 0 to malloc. It leads to the simplest code. Of course it would make sense to give this wrapper a proper name rather than using macro hacks to "replace" malloc like gnulib does... Or, they could use my convenient formula... #undef malloc #define malloc(n) malloc((n)|1) which seems a lot cheaper than a wrapper. It can be applied to realloc too, but might get expensive with calloc. > >You also can't do that if a valid pointer > >is returned, so I really can't grasp the reason for returning a > >pointer at all, > > Not indicating that the allocation failed and triggering an assert() > when there isn't actually a problem with a legitimately zero length > array that had nothing in it? (Both times I debugged why LFS stuff > was failing that's what it turned out to be, but I didn't spend too > much time on it before just switching the uClibc option on to > support it.) While in some cases it would be nice to get a fault, you don't usually get a fault when trying to access past the end of a length-1 array, so why should you expect one when trying to access past the end of a "length-0 array"? > >except to support buggy and lazy programming. > > You're defining "lazy" here a "not adding a special case in the > caller for every use of malloc()". That's certainly a point of view, > but I'm not sure that's the word you want to use for it. "Not > sufficiently defensive programming" maybe? Well, doing nothing to account for the fact that malloc(0) "failing" might not indicate a problematic OOM condition is "lazy" in my book. > And "posix doesn't require this, therefore let's intentional break > it to force any programs with technical posix compatability issues > to use a different libc rather than change anything to humor us"... > not seeing it. When POSIX allows implementation options but one option has clear technical merits over the others, as is the case here, I don't see any good reason to take the low-quality option. Especially if most existing implementations already take the high-quality one, as this suggests to me it's somewhat reasonable for otherwise-portable programs to assume the high-quality behavior. > (Re: the "posix test" thread, having a ./configure --pedantic that > builds a musl without gnu/dammit extensions and safety tape over the > sharp bits sounds like a possible fun future thing. Having that be > the default, or adding a lot of runtime checks rather than > commenting stuff out at compile time, not so much...) Sounds like a lot of work for something that could be better accomplished with static analysis tools and such... Rich