Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <22145EB4-CF32-4BCA-8DE6-93790F3E267F@palsenberg.com>
Date: Tue, 15 Jan 2013 10:01:06 +0100
From: Igmar Palsenberg <igmar@...senberg.com>
To: musl@...ts.openwall.com
Subject: Re: malloc(0) behaviour



>> 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.)

It does. On the other hand : Those programs are broken anyway if you ask me.

>> 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.

Is that a bad thing in this case ? The reason I like musl is that is a conforming library : Not something that has numerous hacks / additions to make it backwards compatible, such I've seen with glibc. Usually, when I
try the same code on for example FreeBSD, all hell breaks loose. In  my experience, musl actually increase my programs portability.

> 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?
> 
>> 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.)

With my own code, I consider it a bug. Yes, opinions differ on this matter. I personally add abort() to code that shouldn't happen, or I consider bad. I do catch real bugs with this from
time to time.

>> 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?

Definitely the latter. Error checking is underrated matter if you ask me : People write code, and then spend ages debugging issues that would have been a non-issue when proper error checking has been done.
The "oh well, it never fails, so don't bother with error checking" thought.

> Whether or not defensive programming is an improvement is one of those perpetual arguments having to do with differing mindsets. In reality the reason you'd want to do it is some libc implementations might _not_ allow malloc(0) to succeed, and thus there are portability issues. But only for people who care about portability off glibc, which is an uphill battle in the first place.

Agree. I will stay a battle until the standard only gives you one direction, and "implementation defined" is removed from it. 

> That said, "I'm right because other people might think like I do and that would make me right" seems kind of a circular argument for a position being _better_. If posix required a valid pointer to be returned the positions would be reversed without any actual change in the technical merits.
> 
> 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.

It's a matter of opinion. I just wanted to know the logic behind returning a pointer in this case, while for example the *BSD libc's return a NULL. I handle this case in my code properly, and bluntly abort() if my code calls malloc(0). That's
good with my code, but might be bad with other people's code.

>> I suggest we make malloc(0) return a NULL pointer. Any objections ?
> 
> Only that it broke real world programs last time I tried it, but if you don't care about that then by all means force 'em to use a different libc.
> 
> (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...)

I'm happy I can try a different libc easily. Downside : I now have some if defined(__GLIBC__) in my code :(
I probably need some configure.ac magic.



	Igmar

 

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.