5 ms·
Yes, a segfault is a type of abort (well, "a type of unintended program death", since you can also define aborts to be SIGABRT only), but in some parlances, "cr
by Manishearth 10y ago
Yes, a segfault is a type of abort (well, "a type of unintended program death", since you can also define aborts to be SIGABRT only), but in some parlances, "crash" is used to refer specifically to segfaults. Or in general, kernel-enforced program death, or non-anticipated crashes.
Segfaults are usually indicative of bad memory safety issues; ones which were not anticipated.
For example, the following two pieces of code do essentially the same thing on a null ptr, assuming the first one triggers a segfault:
int contents = *ptr;
if (!ptr)
abort()
int contents = *ptr;
The difference is that the abort in the second one is an anticipated one. The program was written defensively, saying that "if the ptr is null here, please abort". In the first case, the program will crash with SIGSEGV, but it could also end up with the compiler exploiting the fact that it is allowed to assume that ptr is non-null when dereferenced and performing some optimizations that make bad things happen.
Also, segfaults don't just occur on null pointers, they occur whenever a pointer whose virtual address is currently not allocated by the process. A use after free, basically. In this case, you have two ways something can go -- it can either segfault (the best result!), or your pointer may by chance still point to memory owned by the process, just not the memory that it's supposed to. This can lead to all kinds of badness.
In Rust, for example, you represent nullables with `Option<T>` (like Haskell's Maybe or Java's Optional). Rust forces you to deal with the `None` case whenever you wish to interact with the Option. You have the ability to assert that the Option contains something and obtain the inner value via `unwrap()` or `expect()`. These will panic (unwind, but this can also be set to abort. for simplicity, let's just assume it's an abort). Usually ends with the program or thread exiting.). Now, runtime-wise speaking, `let x = nullable.unwrap()` isn't really that different from `int contents = *ptr;` when the latter is null and segfaults. Both end up with the program exiting, and with much sadness on the part of the user.
However, the first one was anticipatory. With the Rust panic, the programmer said "okay, I believe that this can never be None here, and if not, something is horribly wrong, please abort". Something went horribly wrong, and it aborted. With the segfault, there was no explicit acknowledgement, and it was the kernel -- not the programmer -- intervening and shutting down the program. Like I already said, the kernel intervening is the best possible result here, other results are much worse.
So while effect wise an explicit abort and segfault are quite similar, implication-wise they're quite different. A lot of people thus distinguish between the two by using "crash" to refer to segfaults and other memory safety crashes exclusively. There's not much consistency here, so I thought it would be worth clarifying -- "'Safety' doesn't mean your program will never crash." is false if you define crash as segfault :)