Safe method wont check dangling pointer?

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Tue Apr 15 05:12:02 PDT 2014


On Mon, 14 Apr 2014 23:14:06 -0400, lzzll <ownrepos at gmail.com> wrote:

> Let me show some exmaple on c, and two common memory error detect tool.
>
> example 1 (stack overflow):
> ---
> int a = 100;
> printf("%p\n", &a);
>
> int *b = &a+1;
> printf("%p\n", &b);
>
> *b = 100;
> ---

import std.stdio;

void main() @safe
{
   int a = 100;
   writeln(&a); // line 6

   int *b = &a+1; // line 8
   *b = 100;
}

testsafe.d(6): Error: cannot take address of local a in @safe function main
testsafe.d(6): Error: safe function 'D main' cannot call system function  
'std.stdio.writeln!(int*).writeln' (wow, really?)
testsafe.d(8): Error: cannot take address of local a in @safe function main
testsafe.d(8): Error: pointer arithmetic not allowed in @safe functions

@safe prevents memory errors by preventing pointer arithmetic, and taking  
addresses of stack locals.

I was not aware that writeln is also unsafe! That must be a bug. Even  
writeln!int is unsafe.

> valgrind: nothing detected
> address sanitizer: ==1996== ERROR: AddressSanitizer:  
> stack-buffer-overflow on address 0x7fffc976dbc4
>
> example 2 (cross address)
> ---
> int a = 100;
> int b = 200;
> printf("%p\n", &a);
> printf("%p\n", &b);
>
> int *c = &a+(&b-&a);
> printf("%p\n", c);
>
> *c = 100;
> ---

illegal to use c's initializer in @safe code.

> Of course it can't be detected.

It's also not a memory corruption :)

optimizer will turn int *c = &a+(&b-&a) to int *c = &b;

>
> example 3 (heap overflow)
> ---
> int *a = (int*) malloc(sizeof(int));
> printf("%p\n", a);
>
> int *b = a + 1;
> printf("%p\n", b);
>
> *b = 100;
> ---

illegal to use b's initializer in @safe code. The malloc is allowed, but  
only GC.malloc. C's malloc is not @safe as it requires free.

> valgrind: Address 0x51f0044 is 0 bytes after a block of size 4 alloc'd
> address sanitizer: AddressSanitizer: heap-buffer-overflow on address  
> 0x60040000dff4
>
> It's possible to a certain extent.
> Reference:
> http://valgrind.org/docs/manual/mc-manual.html#mc-manual.vaddress
> http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
>
> I understand implemented this is hard and it need huge cost.
> It still be useful if we only use it to detect memory error and trun it  
> off when release.
> I'll be glad if I can see it on D after some years.

It's impossible to have 100% coverage. Using sentinels and instrumenting  
can help find memory errors, but just not allowing memory-unsafe code is  
more efficient and guaranteed.

Note that valgrind should be able to instrument D code as well.

-Steve


More information about the Digitalmars-d mailing list