On Mon, 05 Mar 2012 23:58:48 -0500, Chad J <chadjoan@__spam.is.bad__gmail.com> wrote:

On 03/05/2012 11:27 PM, Jonathan M Davis wrote:
On Tuesday, March 06, 2012 05:11:30 Martin Nowak wrote:
There are two independent discussions being conflated here. One about
getting more
information out of crashes even in release mode and the other about
adding runtime checks to prevent crashing merely in debug builds.

A segfault should _always_ terminate a program - as should dereferencing a null pointer. Those are fatal errors. If we had extra checks, they would have
to result in NullPointerErrors, not NullPointerExceptions. It's horribly
broken to try and recover from dereferencing a null pointer. So, the question then becomes whether adding the checks and getting an Error thrown is worth doing as opposed to simply detecting it and printing out a stack trace. And throwing an Error is arguably _worse_, because it means that you can't get a
useful core dump.

Really, I think that checking for null when dereferencing is out of the
question. What we need is to detect it and print out a stacktrace. That will
maximize the debug information without costing performance.

- Jonathan M Davis

Why is it fatal?

A segmentation fault indicates that a program tried to access memory that is not available. Since the 0 page is never allocated, any null pointer dereferencing results in a seg fault.

However, there are several causes of seg faults:

1. You forgot to initialize a variable.
2. Your memory has been corrupted, and some corrupted pointer now points into no-mem land.
3. You are accessing memory that has been deallocated.

Only 1 is benign. 2 and 3 are fatal. Since you cannot know which of these three happened, the only valid choice is to terminate.

I think the correct option is to print a stack trace, and abort the program.

I'd like to be able to catch these. I tend to run into a lot of fairly benign sources of these, and they should be try-caught so that the user doesn't get the boot unnecessarily. Unnecessary crashing can lose user data. Maybe a warning message is sufficient: "hey that last thing you did didn't turn out so well; please don't do that again." followed by some automatic emailing of admins. And the email would contain a nice stack trace with line numbers and stack values and... I can dream huh.

You cannot be sure if your program is in a sane state.

I might be convinced that things like segfaults in the /general case/ are fatal. It could be writing to memory outside the bounds of an array which is both not bounds-checked and may or may not live on the stack. Yuck, huh. But this is not the same as a null-dereference:

Foo f = null;
f.bar = 4;  // This is exception worthy, yes,
             // but how does it affect unrelated parts of the program?

Again, this is a simple case.  There is also this case:

Foo f = new Foo();
... // some code that corrupts f so that it is now null
f.bar = 4;

This is not a "continue execution" case, and cannot be distinguished from the simple case by compiler or library code.

Philosophically, any null pointer access is a program error, not a user error, and should not be considered for "normal" execution. Terminating execution is the only right choice.

-Steve

Reply via email to