April 15, 2014
On Tuesday, 15 April 2014 at 09:33:19 UTC, bearophile wrote:
> Walter Bright:
>
>> Valgrind is an incredibly useful tool, but programs run terribly slowly under it.
>
> On the other hand the C/C++ world in the last years has seen
> numerous advancements that D should keep an eye on. If you look
> at the latest versions of LLVM-Clang and GCC you see various
> "sanitizers" (available as built-in tools of the compiler) that
> don't use too much memory, don't slow down your code too much,
> and catch dangling or wrong pointers, integer overflows,
> past-by-one errors, and more. One of those tools is less needed
> by D (thanks to the good management of the array bounds), but the
> others are nice.
>
> Bye,
> bearophile

Except, as far as I am aware, they only work on GNU/Linux and Mac
OS X, leaving out all other operating systems out there.


--
Paulo
April 15, 2014
I think @safe guarantees are much stronger if you _start_ with @safe main and only interact with system code via small @trusted gateways. If it is @system code calling @safe, low-level trickery it allows is just too powerful to avoid with reasonably fast checks.
April 15, 2014
Paulo Pinto:

> Except, as far as I am aware, they only work on GNU/Linux and Mac OS X, leaving out all other operating systems out there.

Is "-fsanitize=integer" not available in the Windows version of Clang?

Perhaps it's a good idea to create something similar to the sanitizers (the memory one, etc) that work on all D compilers.

Bye,
bearophile
April 15, 2014
On Mon, 14 Apr 2014 23:14:06 -0400, lzzll <ownrepos@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
April 15, 2014
On Tuesday, 15 April 2014 at 12:12:00 UTC, Steven Schveighoffer wrote:
> The malloc is allowed, but only GC.malloc. C's malloc is not @safe as it requires free.

I think the reason is that it returns `void*` (needs a cast and has no length) and points to uninitialized memory, not because you need to free it manually. A memory leak is still memory safe.
April 15, 2014
On 4/15/2014 2:33 AM, bearophile wrote:
> On the other hand the C/C++ world in the last years has seen
> numerous advancements that D should keep an eye on. If you look
> at the latest versions of LLVM-Clang and GCC you see various
> "sanitizers" (available as built-in tools of the compiler) that
> don't use too much memory, don't slow down your code too much,
> and catch dangling or wrong pointers, integer overflows,
> past-by-one errors, and more. One of those tools is less needed
> by D (thanks to the good management of the array bounds), but the
> others are nice.

Or you can use @safe, which doesn't slow your code down at all, at least for the memory corruption problems.

April 15, 2014
On 4/15/2014 6:55 AM, "Marc Schütz" <schuetzm@gmx.net>" wrote:
> I think the reason is that it returns `void*` (needs a cast and has no length)
> and points to uninitialized memory, not because you need to free it manually.

Yes.

> A memory leak is still memory safe.

True, which is why we can guarantee memory safety with a GC.

April 15, 2014
On 4/15/2014 4:05 AM, bearophile wrote:
> Perhaps it's a good idea to create something similar to the sanitizers (the
> memory one, etc) that work on all D compilers.

That's what @safe is for.

April 15, 2014
Walter Bright:

> That's what @safe is for.

I think those sanitizers (but the integer-related one) are meant to help D programmers catch bugs in @system code.

Bye,
bearophile
April 15, 2014
On 4/15/2014 10:26 AM, bearophile wrote:
> Walter Bright:
>
>> That's what @safe is for.
>
> I think those sanitizers (but the integer-related one) are meant to help D
> programmers catch bugs in @system code.

I understand that. I've written my own sanitizers in the past and used them heavily. The big advantage of @safe is that it offers a guarantee, sanitizers do not.

Very little, however, of even a hardcore app needs to be @system. What little remains is often @system for performance reasons, where you'd turn off a sanitizer anyway.

To sum up, a sanitizer for D offers little incremental benefit, and has a substantial implementation cost. Such cost would take away from other improvements to D that would be far more valuable.