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