[m-dev.] logging proposal
Ian MacLarty
maclarty at cs.mu.OZ.AU
Tue Feb 28 02:37:15 AEDT 2006
On Tue, Feb 28, 2006 at 01:06:16AM +1100, Mark Brown wrote:
> Hi,
>
> 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(...)
> ;
> true
> ).
>
> 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
> grades.
>
> 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.)
>
Yes I agree. As long as you had logging in the right places in you
library you could make a domain specific 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.
>
I agree.
> 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
> option.
>
So are you saying if you make the argument an I/O closure then you can
implement your debugger to behave however you want? If so then I agree
with you.
> >
> > 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.
>
I see your point and I think I agree (though I'll need to sleep on it
:-).
> > 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.
Your right :-)
We should aim to seperate out the code that defines the behaviour
of the application, and the code that is for observing/debugging the
execution of the program. This proposal doesn't quite get there.
Perhaps a better solution would be to have a `log' (or `debug')
"goal", so in your code you might have a something like:
debug io.format("X = %i\n", [i(X)])
This makes the distinction much clearer.
> 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.
>
I would think this behaviour would be designed, since the logging would
be for observing exactly what your program is doing.
> >
> > We could also have different levels of logging.
>
> That's another thing that could be communicated via environment variables.
>
Of course. I think controlling things via env vars is a good idea.
Ian.
--------------------------------------------------------------------------
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