musl's abort() is quite elegant: http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=sr...
Every programmer should read the source to abort() at some point in their life.
41–50 of 61 posts
Re: Every programmer should read the source to abort() at some point in their life.
#42I may be wrong, but I thought that in a multithreaded environment, doing i++ is not atomic and could result in garbled data. Instead you should use __sync_add_and_fetch. However, I have no idea if it should be used inside abort().
i++ is atomic in most cases, unless i is an excessively wide integer, in abort I think they lock anyway so it doesn't matter (at least in uclibc)
And since abort still needs to work even without locks and on every platform...
Re: Every programmer should read the source to abort() at some point in their life.
#43Plan 9's abort causes an access fault, causing the current process to enter the `Broken' state. The process can then be inspected by a debugger. Pretty elegant. http://plan9.bell-labs.com/sources/plan9/sys/src/libc/9sys/a...
Very elegant, though in some cases 0x0 is addressable, in which case, the abort never happens.
Re: Every programmer should read the source to abort() at some point in their life.
#44I may be wrong, but I thought that in a multithreaded environment, doing i++ is not atomic and could result in garbled data. Instead you should use __sync_add_and_fetch. However, I have no idea if it should be used inside abort().
This is only true if the variable in question's memory is accessed by multiple threads at the same time, and there isn't any locking or synchronization method used to protect the memory.
In this case, even though it is a globally scoped variable, it's locked by the globally scoped mutex declared in the file. All increments are done in the locked sections, so there isn't any possibility of accessing the variable without having a lock.
It should be noted that there is a very minor race condition when abort() is called in two different threads sequentially, and every attempt up to line 89 doesn't work. The first call will get the lock, then go through to line 89, where it released the lock. The second thread will then get the lock, and go through the first section. When it hits the section line 89(if (been_there_done_that == 0)), that will resolve to false, because been_there_done_that is 1. It will then go on, leaving the first thread deadlocked at the LOCK attempt on line 91. This shouldn't result in any missed functionality, but I actually wonder why they're releasing the lock in the first place. Raise() isn't thread safe anyway, because the signal is applied to all threads in the process. Plus, you're trying to suicide the program. It's a bad idea to even have the possibility of multiple threads trying to kill themselves at the same time.
Re: Every programmer should read the source to abort() at some point in their life.
#45Earlier quoted context omitted.
And OSX's, which is rather similar to FreeBSD's but adds: * Writing to NULL * Writing to address 1 (unaligned write) * Writing to text space (read-only machine code) * Dividing by 0 * More violence than SIGABRT (SIGILL, SIGBUS) http://www.opensource.apple.com/source/Libc/Libc-262/stdlib/...
Looks to me like glibc and FreeBSD are the only ones that flush stdout, which I'd view as a bug on the other systems...
It's a bug in the spec, if anything. See the abort() spec http://pubs.opengroup.org/onlinepubs/009695399/functions/abo...
Vs the exit() spec http://pubs.opengroup.org/onlinepubs/000095399/functions/exi...
abort() is intended as a last-ditch effort. exit() is the one that attempts to flush all open buffered file descriptors, and should be used in lieu of abort except in cases where you know you're screwed, or explicitly want to throw a signal so a debugger can take a peek.
Re: Every programmer should read the source to abort() at some point in their life.
#46Re: Every programmer should read the source to abort() at some point in their life.
#47Earlier quoted context omitted.
I admit it's heavily commented, and his usual tangle of preprocessor macros are blissfully absent. But it contains hints of Drepperification, like the superfluous use of preincrement.
When I don't care about the result, I always write preinc/decrement too. Sure, it's superfluous on any non-braindead compiler (it should be able to see that you don't care about the result of a postincrement and elide the temporary), but it's just habit at this point. I fail to see how it reduces or changes readability though. Sounds like you just have an axe to grind with Drepper.
I thoroughly enjoyed his article about memory. He is obviously an extremely intelligent and knowledgeable guy.
I am afraid that he is too clever by half though, insofar as good code is clean and readable first, and clever second. Every time I've had an opportunity to interact with the glibc codebase I'm dismayed that such an important, core piece of software has been written so cleverly that it essentially can only be maintained by one guy.
Re: Every programmer should read the source to abort() at some point in their life.
#48For comparison, here's FreeBSD's abort(): http://svnweb.freebsd.org/base/head/lib/libc/stdlib/abort.c?... And GNU glibc's abort(): http://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib...
And OSX's, which is rather similar to FreeBSD's but adds: * Writing to NULL * Writing to address 1 (unaligned write) * Writing to text space (read-only machine code) * Dividing by 0 * More violence than SIGABRT (SIGILL, SIGBUS) http://www.opensource.apple.com/source/Libc/Libc-262/stdlib/...
Re: Every programmer should read the source to abort() at some point in their life.
#49Earlier quoted context omitted.
What does Dreppered mean?
It's probably a quip referring to Ulrich Drepper, a kernel hacker whose personality seems to be quite controversial according to a quick Google search. I'd love to hear the GP explain it further though.
Re: Every programmer should read the source to abort() at some point in their life.
#50Earlier quoted context omitted.
And OSX's, which is rather similar to FreeBSD's but adds: * Writing to NULL * Writing to address 1 (unaligned write) * Writing to text space (read-only machine code) * Dividing by 0 * More violence than SIGABRT (SIGILL, SIGBUS) http://www.opensource.apple.com/source/Libc/Libc-262/stdlib/...
Since dereferencing a null pointer and dividing by 0 are undefined by C, is the compiler required to emit the code for them? In practice, does it?