May 27, 2004
"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93lar$119p$1@digitaldaemon.com...
> But then you need to go to the code, add the printf, and try to repeat the same error. Then afterwoods removed the printf, or put in another test that occurs at debug time.

Yes, that's life debugging programs. The skill comes in developing test cases that trigger the fault, and in putting in just the right printf to pin down where things go wrong.


May 27, 2004
I would agree that adding a string that describes the error is probably unnecessary.  But if you throw an exception, as I believe assert currently does, you lose valuable context info (stack backtrace and variables) that would be useful in debugging the problem.

I think that the current assert() is a good, basic default.  But I want to be able to write a program that does this:

function()
->assert(...)
  ->assertFailed(...)
    ->takeCoreDump()
    ->crash()

What is the best way to implement this?

Walter wrote:
> "Mike Hearn" <mike@navi.cx> wrote in message
> news:pan.2004.04.16.22.38.14.275716@navi.cx...
> 
>>Hi,
>>
>>Why does assert() not allow you to add a textual string identifying the
>>problem?
>>
>>Otherwise you get the problem alsalib has, where you get useless messages
>>like:
>>
>>snd_pcm.c: assertion "err < 0" failed
>>
>>which tells you nothing about what the assert *actually tested* in the
>>semantic sense, rather than the expression sense.
>>
>>Is there a reason we can't have an extension that lets you write?
>>
>>   assert( err < 0, "Could not negotiate hardware parameters" );
>>
>>or something to that effect?
> 
> 
> Asserts are only for debugging purposes by the programmer who wrote the
> code, and the first thing the programmer will do is bring up the
> corresponding file/line in the editor. Presumably there will be some comment
> there explaining it. I don't see how adding a redundant string in the assert
> message itself adds value to this.
> 
> If you're writing code that will be seen by the user, instead use something
> like:
> 
>     if (!expression) throw new Exception("we failed because ...");

May 27, 2004
In article <c939g8$h6d$1@digitaldaemon.com>, Sean Kelly says...
>
>In article <pan.2004.05.26.23.06.25.423500@swieton.net>, Mike Swieton says...
>>
>>On Wed, 26 May 2004 21:10:08 +0000, Sean Kelly wrote:
>>
>>> And new assert functions can always be written if special information is desired.
>>
>>This is not strictly true. If a user replaces the built-in assert with a custom one, a custom one cannot report the line number of a failed assertion, while the builtin one can.
>
>Oops!  I forgot about the lack of macros in D.  It would be nice to have assert be extensible or at least to have module and line number information availble in another way.  Can't say I use them myself, but I've seen versions of assert that launch dialog windows and do debugger magic, and I'd have to lose line info in the process.
>
>Sean

In a debugger, you can trace the stack back.  If there was an interface to do this from inside the program, you would not need the "file, line, module, class" pseudo variables of the c preprocessor.

For any function, current_function_name(uint i) and current_line_number(uint i) would return the information, with i=0 being the current function and i = 1 being the calling function.  They would return empty data for the non-debug case.

This would open doors to the development of a great deal of debugging-assistance development, which for the first time would be portable.  It would only need to be available in Debug mode, unless a special compiler option was used.

(In debug mode) this would insert code in the begin (end) of functions, which
would add (remove) the function name and line number to a stack.  Alternately,
the system could take advantage of existing debugging symbols stored in the
object code.

The release version of the (retrieval) functions would just return nothing,
likewise if the index (i) was too high (off the stack).

Kevin



May 27, 2004
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:c93v0g$1g48$1@digitaldaemon.com...
> I would agree that adding a string that describes the error is probably unnecessary.  But if you throw an exception, as I believe assert currently does, you lose valuable context info (stack backtrace and variables) that would be useful in debugging the problem.

But a decent debugger gives you that already. Why put it in the language?


May 28, 2004
In article <c93q92$18q9$1@digitaldaemon.com>,
 "Walter" <newshound@digitalmars.com> wrote:

> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93ll4$120a$1@digitaldaemon.com...
> > Walter wrote:
> > >My normal practice is to put some debugging printf's before the assert,
> and
> > >rerun the program.
> > But your working on a compiler.  The conditions are easily re-produced in that type of program.
> 
> Compilers aren't the only programs I've written. For GUI programs, I'd have the printf's write to a log file. As for reproducing the error, that can be tricky in, for example, multithreaded programs, but you cannot fix it and verify the fix anyway until you can find a way to reproduce it.

For anyone who wasn't aware, there's an interesting article in the June 2004 CUJ: "Debugging Real-Time Production Software".

Basically it's about creating a special (low-priority) debugging thread that not only buffers and writes out log messages (sent to it from other threads) but also can be used to set, enable, and disable breakpoints while the program runs.

When those breakpoints are enabled and reached, the process does not stop; instead, special breakpoint functions are called and execution continues, so the app behaves more like it would in the wild.

That might help MT coders more than just string literals in asserts.

And it probably won't involve any language changes to set that up in D -- though it would be pretty sweet if a development environment came with a debugging API and IDE integration so as to ease the use of a technique like that.
May 28, 2004
I like that breakpoint notion! Especially so 'cos I've been looking at porting/binding Log4C ...

- Kris

"James Widman" <james@jwidman.com> wrote in message news:james-D2EFAE.20495627052004@digitalmars.com...
> In article <c93q92$18q9$1@digitaldaemon.com>,
>  "Walter" <newshound@digitalmars.com> wrote:
>
> > "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93ll4$120a$1@digitaldaemon.com...
> > > Walter wrote:
> > > >My normal practice is to put some debugging printf's before the
assert,
> > and
> > > >rerun the program.
> > > But your working on a compiler.  The conditions are easily re-produced in that type of program.
> >
> > Compilers aren't the only programs I've written. For GUI programs, I'd
have
> > the printf's write to a log file. As for reproducing the error, that can
be
> > tricky in, for example, multithreaded programs, but you cannot fix it
and
> > verify the fix anyway until you can find a way to reproduce it.
>
> For anyone who wasn't aware, there's an interesting article in the June 2004 CUJ: "Debugging Real-Time Production Software".
>
> Basically it's about creating a special (low-priority) debugging thread that not only buffers and writes out log messages (sent to it from other threads) but also can be used to set, enable, and disable breakpoints while the program runs.
>
> When those breakpoints are enabled and reached, the process does not stop; instead, special breakpoint functions are called and execution continues, so the app behaves more like it would in the wild.
>
> That might help MT coders more than just string literals in asserts.
>
> And it probably won't involve any language changes to set that up in D -- though it would be pretty sweet if a development environment came with a debugging API and IDE integration so as to ease the use of a technique like that.


May 28, 2004
In article <c959fd$17un$2@digitaldaemon.com>, Walter says...
>
>
>"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:c93v0g$1g48$1@digitaldaemon.com...
>> I would agree that adding a string that describes the error is probably unnecessary.  But if you throw an exception, as I believe assert currently does, you lose valuable context info (stack backtrace and variables) that would be useful in debugging the problem.
>
>But a decent debugger gives you that already. Why put it in the language?

interface DebugModule {
void at_line(uint line, char[] function, char[] module);
void enter_function(uint line, char[] function, char[] module);
void exit_function(uint line,  char[] function, char[] module);
void modify_variable(uint var_line, char[] varname,
uint mod_line, char[] modname);
}

If I could write a handler matching an interface like the one above, and the compiler knew how to put hooks in the language for it, I could create a debugger that was written in D.  If I had access to a portable D GUI library it could run on any platform.

Instead of zero or one good debuggers being available (ie does GDB count as good?, opinion varies), I would have anything I can write.  Currently, I can't write a portable debugger without a lot of knowledge about assembler and object file format; consequently there is about one debugger per compiler.

I could write a module that does debugging via a GUI pop-up widget; it wouldn't have all the down-on-the-metal knowledge that GDB has, but I could have it pop into debug mode based on arbitrary decisions in the code.  There used to be a way to do this, known as "dropping into a monitor" or similar, although monitors were very primitive.

The code that I am suggesting to insert in functions at various points would be something like:

if (global_debugger() !== null)
line_number_hook(__FUNCTION__, __LINE__, __MODULE__);

To attach a user created "diagnostics" module, there would be a similar call:

global_debugger(new GtkDebugModule);

or:

global_debugger(null); // return to non-calling-hooks mode.

Kevin




June 01, 2004
If it helps at all, there's now a Log4J clone underneath the Mango Tree at dsource.org, and if one were to hook up a set of servlet-based forms (via mango.servlet of course) for displaying and configuring the Log4J attributes in one's running application ...

- Kris


"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93lar$119p$1@digitaldaemon.com...
> Walter wrote:
>
> >My normal practice is to put some debugging printf's before the assert,
and
> >rerun the program.
> >
> >
>
> But then you need to go to the code, add the printf, and try to repeat the same error. Then afterwoods removed the printf, or put in another test that occurs at debug time.  In many cases repeating the same error can be very difficult without knowledge of what the data was at that time.  I think it would be better to have the assert print out some of the data at that time.   A lot of effort to get one variable when the code could be written much easier into an assert.
>
> ie compare:
>
> debug
> {
>   if (!condition)
>   {
>        printf("", ...);
>    }
> }
> assert(condition);
>
> to
>
> assert(condition, "", ...);
>
>
>
> --
> -Anderson: http://badmama.com.au/~anderson/


June 04, 2004
Agree

"J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93lar$119p$1@digitaldaemon.com...
> Walter wrote:
>
> >My normal practice is to put some debugging printf's before the assert, and rerun the program.
> >
> >
>
> But then you need to go to the code, add the printf, and try to repeat the same error. Then afterwoods removed the printf, or put in another test that occurs at debug time.  In many cases repeating the same error can be very difficult without knowledge of what the data was at that time.  I think it would be better to have the assert print out some of the data at that time.   A lot of effort to get one variable when the code could be written much easier into an assert.
>
> ie compare:
>
> debug
> {
>   if (!condition)
>   {
>        printf("", ...);
>    }
> }
> assert(condition);
>
> to
>
> assert(condition, "", ...);
>
>
>
> -- 
> -Anderson: http://badmama.com.au/~anderson/


June 04, 2004
"Walter" <newshound@digitalmars.com> wrote in message news:c93q92$18q9$1@digitaldaemon.com...
>
> "J Anderson" <REMOVEanderson@badmama.com.au> wrote in message news:c93ll4$120a$1@digitaldaemon.com...
> > Walter wrote:
> > >My normal practice is to put some debugging printf's before the assert,
> and
> > >rerun the program.
> > But your working on a compiler.  The conditions are easily re-produced in that type of program.
>
> Compilers aren't the only programs I've written. For GUI programs, I'd have the printf's write to a log file. As for reproducing the error, that can be tricky in, for example, multithreaded programs, but you cannot fix it and verify the fix anyway until you can find a way to reproduce it.

Good point, but there are times when what's been asked for is useful.

> Just printing out the value of the assert variable rarely is sufficient anyway, as it is usually the tail end of a problem that started sometimes much earlier.

Depends how much assertion you have. If (near-)full coverage is there, the first trigger will be very close to the error source.