[Python-Dev] Why do we need Traceback Objects?

Vladimir Marangozov Vladimir.Marangozov@inrialpes.fr
Fri, 7 Apr 2000 04:47:15 +0200 (CEST)


Guido van Rossum wrote:
> 
> > What happens is that in tracing mode, a copy of the original code stream
> > is created, a new CALL_TRACE opcode is stored in it at the addresses
> > corresponding to each source line number, then the instruction pointer
> > is redirected to execute the modified code string. Whenever a CALL_TRACE
> > opcode is reached, the callback is triggered. On a successful return, 
> > the original opcode at the current address is fetched from the original
> > code string, then directly goto the dispatch code.
> > 
> > This code string duplication & conditional break-point setting occurs
> > only when a trace function is set; in the "normal case", the interpreter
> > executes a code string without SET_LINENO.
> 
> Ai!  This really sounds like a hack.  It may be a standard trick in
> the repertoire of virtual machine implementers, but it is still a
> hack, and makes my heart cry.

The implementation sounds tricky, yes. But there's nothing hackish
in the principle of setting breakpoints. The modified code string
is in fact the stripped code stream (without LINENO), reverted back
to a standard code stream with LINENO. However, to simplify things,
the LINENO (aka CALL_TRACE) are not inserted between the instructions
for every source line. They overwrite the original opcodes in the copy
whenever a trace function is set (i.e.  we set all conditional
breakpoints (LINENO) at once). And since we overwrite for simplicity,
at runtime, we read the ovewritten opcodes from the original stream,
after the callback returns. All this magic occurs before the main loop,
with finalization on exit of eval_code2.

A tricky implementation of the principle of having a set of conditional
breakpoints for every source line (these cond. bp are currently the
SET_LINENO opcodes, in a more redundant version).

> I really wonder if it makes enough of a difference to warrant all
> that code, and the risk that that code isn't quite correct.

Well, all this business is internal to ceval.c and doesn't seem to affect
the rest of the world. I can see only two benefits (if this idea doesn't
hide other mysteries -- so anyone interested may want check it out):

1) Some tiny speedup -- we'll reach -O in a standard setup
2) The .pyc files become smaller. (Lib/*.pyc is reduced by ~80K for 1.5.2)

No other benefits (hmmm, maybe the pdb code will be simplified wrt linenos)
I originally developped this idea because of the redundant, consecutive
SET_LINENO in a code object.

> (Is it thread-safe?)

I think so.

-- 
       Vladimir MARANGOZOV          | Vladimir.Marangozov@inrialpes.fr
http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252