Hacker News new | ask | show | jobs
by iambvk 224 days ago
Doesn't null-pointer-dereference always crash the application?

Is it only an undefined-behavior because program-must-crash is not the explicitly required by these languages' specs?

3 comments

> Doesn't null-pointer-dereference always crash the application?

No. It's undefined behaviour, it may do anything or nothing.

> Is it only an undefined-behavior because program-must-crash is not the explicitly required by these languages' specs?

I don't understand the question here. It's undefined behaviour because the spec says it's undefined behaviour, which is some combination of because treating it as impossible allows many optimisation opportunities and because of historical accidents.

> No. It's undefined behaviour, it may do anything or nothing.

This is clearly nonsense.

It is not nonsense: see https://lwn.net/Articles/575563/

Compilers are allowed to assume undefined behavior doesn't happen, and dereferencing an invalid pointer is undefined behavior. You don't have to like it, but that's how it is.

> This is clearly nonsense.

It is indeed. Unfortunately it's also the C language standard.

No, it does not always crash. This is a common misconception caused by thinking about the problem on the MMU (hardware) level, where reading a null pointer predictably results in a page fault. If this was the only thing we had to contend with, then yes, it would immediately terminate the process, cutting down the risk of a null pointer dereference to just a crash.

The problem is instead in software - it is undefined behavior, so most compilers may optimize it out and write code that assumes it never happens, which often causes nightmarish silent corruption / control flow issues rather than immediately crashing. These optimizations are common enough for it to be a relatively common failure mode.

There is a bit of nuance that on non-MMU hardware such as microcontrollers and embedded devices, reading null pointers does not actually trigger an error on a hardware level, but instead actually gives you access to the 0 position on memory. This is usually either a feature (because it's a nice place to put global data) or a gigantic pitfall of its own (because it's the most likely place for accidental corruption to cause a serious problem, and reading it inadvertently may reveal sensitive global state).

> No, it does not always crash.

Can you give me an example that I can reproduce?

This crashes, but after doing something unexpected (printing "Wow" 4 times): https://godbolt.org/z/GPc7bEMn5
Only if that memory page is unmapped, and only if the optimizer doesn't detect that it's a null pointer and start deleting verification code because derefing null is UB, and UB is assumed to never happen.
How common is this in practice?
Compilers regularly delete null pointer checks when they can see that the pointer is dereferenced.
(GCC controls this with `-fno-delete-null-pointer-checks` https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#ind... )