Jump to page: 1 2
Thread overview
halt with optional message?
Aug 11, 2011
bearophile
Aug 11, 2011
Vladimir Panteleev
Aug 11, 2011
bearophile
Aug 11, 2011
Vladimir Panteleev
Aug 11, 2011
bearophile
Aug 11, 2011
Vladimir Panteleev
Aug 11, 2011
Vladimir Panteleev
Aug 11, 2011
simendsjo
Aug 11, 2011
Jonathan M Davis
Aug 11, 2011
Vladimir Panteleev
Aug 11, 2011
bearophile
Aug 11, 2011
kennytm
Aug 11, 2011
Jonathan M Davis
Aug 11, 2011
Sean Kelly
Aug 11, 2011
Jonathan M Davis
Aug 11, 2011
Sean Kelly
Aug 11, 2011
bearophile
Aug 11, 2011
Timon Gehr
Aug 11, 2011
Timon Gehr
Aug 11, 2011
bearophile
August 11, 2011
Is it possible, and is it a good/wise idea to modify D a bit so that in release mode this:

assert(0);

becomes a HLT, while in release mode this

assert(0, "message");

Becomes the same thing as:

core.stdc.stdlib.puts("message");
HTL

?

What I asking here is support for optional messages in assert(0) too, and if it's a good idea.

Note: writing puts before an assert(0) in D code is not the same thing, because you are not supposed to be able to use puts in a pure function:

void foo() pure {
    puts("message");
    assert(0);
}

Bye,
bearophile
August 11, 2011
On Thu, 11 Aug 2011 14:00:03 +0300, bearophile <bearophileHUGS@lycos.com> wrote:

> Is it possible, and is it a good/wise idea to modify D a bit so that in release mode this:

Assert reasons should never be in release executables. Release executables are often meant for redistribution and shouldn't contain messages intended for debugging. A simple function would be better suited for this, I think.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
August 11, 2011
Vladimir Panteleev:

> Assert reasons should never be in release executables. Release executables are often meant for redistribution and shouldn't contain messages intended for debugging.

Contracts contain asserts, sometimes asserts are kept in the released binaries too (dmd has many asserts active) and those asserts hopefully contain an error message for debugging. How do you remove those error messages? I don't think that removing them improves the program and its usage in any way.

Also, here we are discussing about assert(0), it's a different kind of assert, that is kept in release mode too. If the program prints a debugging message and the user tells me the error message (this is right what has just happened to me), I am able to know what assert(0) has fired even if the user is not using a debugger. So I don't think you are right.


A simple function would be better suited for this, I think.

puts() is not pure, so if you add a puts() in a function, the function can't be pure. So the function that calls this function can't be pure...

Bye,
bearophile
August 11, 2011
On Thu, 11 Aug 2011 14:20:46 +0300, bearophile <bearophileHUGS@lycos.com> wrote:

> Contracts contain asserts,

But contracts are removed in release executables too, no?

> sometimes asserts are kept in the released binaries too (dmd has many asserts active) and those asserts hopefully contain an error message for debugging.

Consider: regular asserts are removed from release executables. assert(0) compiles to a HLT instead of nothing merely because it has practically no overhead (only one byte of machine code)!

I think you're confusing the purpose of asserts with something else again. Besides, there are some who think that the special case of assert(0) is confusing/inconsistent with regular asserts enough, why do you want to enlarge that distinction even more?

> I don't think that removing them improves the program and its usage in any way.

If I'm writing a commercial, closed-source program meant for redistribution, including any unnecessary information that helps reversers to understand how the program works is just stupid.

> Also, here we are discussing about assert(0), it's a different kind of assert, that is kept in release mode too. If the program prints a debugging message and the user tells me the error message (this is right what has just happened to me), I am able to know what assert(0) has fired even if the user is not using a debugger. So I don't think you are right.

You're not supposed to use -release if you want to know what happened. Failed asserts in release executables should never happen, unless your program is buggy. If your program is buggy, don't use -release until you've debugged it.

> puts() is not pure, so if you add a puts() in a function, the function can't be pure. So the function that calls this function can't be pure...

This is the least of my concern.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
August 11, 2011
Vladimir Panteleev:

> Besides, there are some who think that the special case of assert(0) is confusing/inconsistent with regular asserts enough,

The discussion ended with no changes in D because I think for Walter it's a problem not large enough to be worth a change in D.


> If I'm writing a commercial, closed-source program meant for redistribution, including any unnecessary information that helps reversers to understand how the program works is just stupid.

Then you don't add a message to assert(0), so it keeps being translated with just an efficient HLT.

The purpose of D programs is varied, there are not just closed source programs to sell. The user of a small D program I have recently written was sitting in a room near mine. He has hit an assert, he has told me what the message is, and I have fixed the code and sent him the fixed binary. The program is now working, it seems.


> Failed asserts in release executables should never happen, unless your program is buggy. If your program is buggy, don't use -release until you've debugged it.

Sometimes I think it's not buggy, but it contains one or more bugs :-(


> This is the least of my concern.

I'm trying to use purity more and more :-) It helps me avoid some troubles. As more and more stuff in Phobos becomes pure, I suggest you to use this attribute more in your code.

The purpose of this thread was not just to ask for a feature (I use Bugzilla for that), but also to know if this is first of all a good idea. Thank you for your answers, I am seeing the situation a bit better now.

Bye,
bearophile
August 11, 2011
On Thu, 11 Aug 2011 14:55:29 +0300, bearophile <bearophileHUGS@lycos.com> wrote:

>> If I'm writing a commercial, closed-source program meant for
>> redistribution, including any unnecessary information that helps reversers
>> to understand how the program works is just stupid.
>
> Then you don't add a message to assert(0), so it keeps being translated with just an efficient HLT.

But I want a message in debug mode! Are you saying that your use case is so much more common than messages meant only for the debug development stage?

> The purpose of D programs is varied, there are not just closed source programs to sell. The user of a small D program I have recently written was sitting in a room near mine. He has hit an assert, he has told me what the message is, and I have fixed the code and sent him the fixed binary. The program is now working, it seems.

I don't see what the problem is. Is your program buggy? Don't use -release. Are you done fixing bugs? Use -release to remove pointless clutter. Is the program segfaulting on a user's PC? Send him a debug build!

>> Failed asserts in release executables should never happen, unless your
>> program is buggy. If your program is buggy, don't use -release until
>> you've debugged it.
>
> Sometimes I think it's not buggy, but it contains one or more bugs :-(

That's YOUR problem. :)

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
August 11, 2011
On Thu, 11 Aug 2011 14:59:03 +0300, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:

> I don't see what the problem is. Is your program buggy? Don't use -release. Are you done fixing bugs? Use -release to remove pointless clutter. Is the program segfaulting on a user's PC? Send him a debug build!

By the way, I'd like to add some thoughts on how wrong I think it is to rely on a single debugging feature like this in release builds. Asserts (both conditional and unconditional), contracts, invariants and native language features such as array bounds checking all work together to find bugs as soon as possible. If you get an error message on an assert(0) and you attempt to debug it from that, you may be led on a wild goose chase, because the program might have actually failed much earlier and ran for a while in an undetermined state, corrupting memory left and right or spreading internal state inconsistencies uncaught by invariants. I know about this all too well from my experience of debugging memory corruption - the garbage collector is compiled with no invariants as its performance is critical, but recompiling my program with a version of Phobos with contracts enabled would have saved me tracing a few steps to find the source of corruption.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
August 11, 2011
bearophile wrote:
> Is it possible, and is it a good/wise idea to modify D a bit so that in release mode this:
>
> assert(0);
>
> becomes a HLT, while in release mode this
>
> assert(0, "message");
>
> Becomes the same thing as:
>
> core.stdc.stdlib.puts("message");
> HTL
>
> ?
>
> What I asking here is support for optional messages in assert(0) too, and
> if it's a good idea.
>
> Note: writing puts before an assert(0) in D code is not the same thing, because you are not supposed to be able to use puts in a pure function:
>
> void foo() pure {
>     puts("message");
>     assert(0);
> }
>
> Bye,
> bearophile

I don't think it is a very common need to still have a message for assert(0) when turning off other assertions.

But you can solve your problem by circumventing the type system:

void assert0impl(string msg){
    writeln(msg);
    assert(0);
}
void assert0(string msg)pure nothrow @trusted{
    (cast(void function(string)pure nothrow @trusted)&assert0impl)(msg);
}

Maybe a better solution would be to have @noreturn functions in the language. (or, prettier, a type of which no values exist).

Cheers,
-Timon


August 11, 2011
bearophile wrote:
> void foo() pure {
>     puts("message");
>     assert(0);
> }

BTW, that that function is any less pure than

void foo() pure {
    assert(0);
}

Is imho just a QOI issue.
August 11, 2011
On 11.08.2011 14:56, Vladimir Panteleev wrote:
> On Thu, 11 Aug 2011 14:59:03 +0300, Vladimir Panteleev
> <vladimir@thecybershadow.net> wrote:
>
>> I don't see what the problem is. Is your program buggy? Don't use
>> -release. Are you done fixing bugs? Use -release to remove pointless
>> clutter. Is the program segfaulting on a user's PC? Send him a debug
>> build!
>
> By the way, I'd like to add some thoughts on how wrong I think it is to
> rely on a single debugging feature like this in release builds. Asserts
> (both conditional and unconditional), contracts, invariants and native
> language features such as array bounds checking all work together to
> find bugs as soon as possible. If you get an error message on an
> assert(0) and you attempt to debug it from that, you may be led on a
> wild goose chase, because the program might have actually failed much
> earlier and ran for a while in an undetermined state, corrupting memory
> left and right or spreading internal state inconsistencies uncaught by
> invariants. I know about this all too well from my experience of
> debugging memory corruption - the garbage collector is compiled with no
> invariants as its performance is critical, but recompiling my program
> with a version of Phobos with contracts enabled would have saved me
> tracing a few steps to find the source of corruption.
>

Which reminds me.. Why isn't a phobos shipped with a precompiled version containing contracts?
« First   ‹ Prev
1 2