dereferencing null

Steven Schveighoffer schveiguy at yahoo.com
Wed Mar 7 07:07:35 PST 2012


On Wed, 07 Mar 2012 09:22:27 -0500, Chad J  
<chadjoan at __spam.is.bad__gmail.com> 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.

(1) occurs a lot, and in most cases, happens reliably.  Most QA cycles  
should find them.  There should be no case in which this is not a program  
error, to be fixed.
(2) and (3) are sinister because errors that occur are generally far away  
 from the root cause, and the memory you are using is compromised.  For  
example, a memory corruption can cause an error several hours later when  
you try to use the corrupted memory.

If allowed to continue, such corrupt memory programs can cause lots of  
problems, e.g. corrupt your saved data, or run malicious code (buffer  
overflow attack).  It's not worth saving anything.

> 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?

The null dereference may be a *result* of memory corruption.

example:

class Foo {void foo(){}}

void main()
{
    int[2] x = [1, 2];
    Foo f = new Foo;

    x.ptr[2] = 0; // oops killed f
    f.foo(); // segfault
}

Again, this one is benign, but it doesn't have to be.  I could have just  
nullified my return stack pointer, etc. along with f.

The larger point is, a SEGV means memory is not as it is expected.  Once  
you don't trust your memory, you might as well stop.

-Steve


More information about the Digitalmars-d mailing list