[m-dev.] logging proposal

Mark Brown mark at cs.mu.OZ.AU
Tue Feb 28 01:06:16 AEDT 2006


I've recently been thinking of a similar mechanism to support domain
specific debugging.  The concept I came up with is much the same as your
proposal, but the rationale is a bit different.

I need to use such a feature in the tight inner loop of an execution
engine which I wish to trace.  I would like to be able to call an I/O
closure when the appropriate option is given at compile time, but if it
isn't then it is crucial that the compiler optimize the call away.

My current solution is to define a function as follows:

	:- func trace_engine = (bool::out(bound(no))).
	trace_engine = no.

and use the function at appropriate points as follows:

	( trace_engine = yes ->
		impure do_trace_event(...)

Providing the inst `bound(no)' gives the compiler the information it
needs to optimize the if-then-else away.  To turn this tracing code on,
I have to change each `no' to `yes' and recompile.

This solution is not satisfactory.  The code is intended to be distributed
as a library -- possibly in binary form -- and asking people to edit the
code (or even putting it through a preprocessor) is not feasible.

What I'd like to be able to do is have the code included in debug grades,
but completely optimized away otherwise.  Binary versions of the library
are likely to be distributed in both debugging and non-debugging grades
anyway, and people who use the library in their application will be able
to provide the debugging facility to _their_ users by offering multiple

On 27-Feb-2006, Ian MacLarty <maclarty at cs.mu.OZ.AU> wrote:
> As a result of the recent discussion about how to trick Mercury into not
> optimising away logging calls, I am proposing the following simple
> solution:
> We add a special procedure `log' to the builtin module.  The new
> procedure takes a string as input (or possibly an I/O closure).

Definitely make it an I/O closure.  And the procedure has many more uses
than just logging (you could just about implement all of mdb in Mercury
with a feature like this!), so call it something more generic like
`debugging_event'.  (Admittedly, my do_trace_event currently just logs some
information on stdout, but I would like to expand it to be a fully
interactive, mdb-style debugger.)

> The
> compiler is then modified to treat calls to log as being the same as
> true, unless an "--enable-logging" options is given.  If this option is
> given then the logging predicates write their output somewhere

I'd suggest using the mdb technique of both a compile-time and a run-time
option.  The run-time option would be via the MERCURY_OPTIONS environment
variable -- if the procedure is activated with the compile-time option,
then the first thing it does is check a global flag in the runtime system
to see if the run-time option was given.  This way you can easily turn off
the events without recompiling, and without too much overhead.

And I think the right compile-time option is `--debug' and its equivalents,
but more on that below.

> (where they write their output could be given by another mmc option).

There could be lots of different kinds of information you may want to
communicate to this subsystem, and we won't be able to anticipate all of
it.  You also might prefer to specify the output location at run-time
rather than compile time.  Hence I think it would be better to communicate
via environment variables.

Furthermore, an application may link to two different libraries that use
this feature and you might therefore want to send the logs to separate
places, but you couldn't do that with either a compile-time or a run-time

> What are the feelings on introducing such a scheme?

Nasty, dirty and kludgy as it is, I think it's absolutely necessary.

> Clearly some kind
> of logging feature is necessary, especially for very long running
> programs that would be too slow in debugging grades.

I'm not so sure I agree with this line of reasoning.  If your debugging
events are going to be fairly frequently doing I/O, then surely the cost
of the I/O is going to outweigh the cost of debugging anyway (particularly
with --trace-optimized).

If it is only rarely called, or only rarely doing output, then I don't
see this feature as being necessary -- using impure code and testing the
current value of a mutable to decide whether to have the event or not
would seem to be an acceptable solution.

Because of this, and because of the situation I outlined at the start,
I think it would be best to tie the feature to the debugging grades.
This would also effectively stop people from trying to use the feature
in production code, which they really shouldn't do.

> Also it would be
> better that user's could add a logging mechanism to their code without
> tricking and/or lying to the compiler.

Oho, I'm afraid this technique is still very much stretching the truth.
You can backtrack over this tracing code, remember, but the side effects
are obviously not undone and the compiler is in no way informed of this
fact.  This is definitely still an experts only feature, IMHO.

> We could also have different levels of logging.

That's another thing that could be communicated via environment variables.


mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au

More information about the developers mailing list