dereferencing null

Chad J chadjoan at __spam.is.bad__gmail.com
Wed Mar 7 07:10:32 PST 2012


On Wednesday, 7 March 2012 at 14:23:18 UTC, Chad J wrote:
> On 03/07/2012 07:57 AM, Steven Schveighoffer wrote:
>> On Mon, 05 Mar 2012 23:58:48 -0500, Chad J
>> <chadjoan at __spam.is.bad__gmail.com> wrote:
>>
>>>
>>> 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.
>>
>
> Alright, I think I see where the misunderstanding is coming 
> from.
>
> I have only ever encountered (1).  And I've encountered it a 
> lot.
>
> I didn't even consider (2) and (3) as possibilities.  Those are 
> far from my mind.
>
> I still have a nagging doubt though: since the dereference in 
> question is null, then there is no way for that particular 
> dereference to corrupt other memory.  The only way this happens 
> in (2) and (3) is that related code tries to write to invalid 
> memory.  But if we have other measures in place to prevent that 
> (bounds checking, other hardware signals, etc), then how is it 
> still possible to corrupt memory?
>
>>
>> [...]
>>
>> -Steve

I spoke too soon!
We missed one:

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.
4. null was being used as a sentinal value, and it snuck into
  a place where the value should not be a sentinal anymore.

I will now change what I said to reflect this:

I think I see where the misunderstanding is coming from.

I encounter (1) from time to time.  It isn't a huge problem 
because usually if I declare something the next thing on my mind 
is initializing it.  Even if I forget, I'll catch it in early 
testing.  It tends to never make it to anyone else's desk, unless 
it's a regression.  Regressions like this aren't terribly common 
though.  If you make my program crash from (1), I'll live.

I didn't even consider (2) and (3) as possibilities.  Those are 
far from my mind.  I think I'm used to VM languages at this point 
(C#, Java, Actionscript 3, Haxe, Synergy/DE|DBL, etc).  In the 
VM, (2) and (3) can't happen.  I never worry about those.  Feel 
free to crash these in D.

I encounter (4) a lot.  I really don't want my programs crashed 
when (4) happens.  Such crashes would be super annoying, and they 
can happen at very bad times.

------

Now then, I have 2 things to say about this:

- Why can't we distinguish between these?  As I said in my 
previous thoughts, we should have ways of ruling out (2) and (3), 
thus ensuring that our NullDerefException was caused by only (1) 
or (4).  It's possible in VM languages, but given that the VM is 
merely a cheesey abstraction, I beleive that it's always possible 
to accomplish the same things in D %100 of the time.  Usually 
this requires isolating the system bits from the abstractions.  
Saying it can't be done would be giving up way too easily, and 
you can miss the hidden treasure that way.

- If I'm given some sensible way of handling sentinal values then 
(4) will become a non-issue.  Then that leaves (1-3), and I am OK 
if those cause mandatory crashing.  I know I'm probably opening 
an old can of worms, but D is quite powerful and I think we 
should be able to solve this stuff.  My instincts tell me that 
managing sentinal values with special patterns in memory (ex: 
null values or separate boolean flags) all have pitfalls 
(null-derefs or SSOT violations that lead to desync).  Perhaps 
D's uber-powerful type system can rescue us?

The only other problem with this is... what if our list is not 
exhaustive, and (5) exists?




More information about the Digitalmars-d mailing list