[Python-Dev] about line numbers

Vladimir Marangozov Vladimir.Marangozov@inrialpes.fr
Sat, 21 Aug 1999 16:34:32 +0100 (NFT)


[me]
> 
> Guido van Rossum wrote:
> > 
> > 
> > I'm a little anxious about modifying the code, and was thinking myself
> > of a way to specify a bitvector of addresses where to break.  But that
> > would still cause some overhead for code without breakpoints, so I
> > guess you're right (and it's certainly a long-standing tradition in
> > breakpoint-setting!)
> > 
> 
> Hm. You're probably right, especially if someone wants to inspect
> a code object from the debugger or something. But I belive, that
> we can manage to redirect the instruction pointer in the beginning
> of eval_code2 to the *copy* of co_code, and modify the copy with
> CALL_TRACE, preserving the original intact.
> 

I wrote a very rough first implementation of this idea. The files are at:

http://sirac.inrialpes.fr/~marangoz/python/lineno/


Basically, what I did is:

1) what I said :-)
2) No more SET_LINENO
3) In tracing mode, a copy of the original code is put in an additional
   slot (co_tracecode) of the code object. Then it's overwritten with
   CALL_TRACE opcodes at the locations returned by PyCode_Line2Addr.

   The VM is routed to execute this code, and not the original one.

4) When tracing is off (i.e. sys_tracefunc is NULL) the VM fallbacks to
   normal execution of the original code.


A couple of things that need finalization:

a) how to deallocate the modified code string when tracing is off
b) the value of CALL_TRACE (I almost randomly picked 76)
c) I don't handle the cases where sys_tracefunc is enabled or disabled
   within the same code object. Tracing or not is determined before
   the main loop.
d) update pdb, so that it does not allow setting breakpoints on lines with
   no code. To achieve this, I think that python versions of PyCode_Addr2Line
   & PyCode_Line2Addr have to be integrated into pdb as helper functions.
e) correct bugs and design flaws
f) something else?


And here's the sample session of my lousy function f with this
'proof of concept' code:

>>> from test import f
>>> import dis, pdb
>>> dis.dis(f)
          0 LOAD_CONST          1 (1)
          3 STORE_FAST          0 (a)
          6 LOAD_CONST          2 (None)
          9 RETURN_VALUE   
>>> pdb.runcall(f)
> test.py(5)f()
-> a = 1
(Pdb) list 1, 10
  1     def f():
  2             """Comment about f"""
  3             """Another one"""
  4             """A third one"""
  5  ->         a = 1
  6             """Forth"""
  7             "and pdb can set a breakpoint on this one (simple quotes)"
  8             """but it's intelligent about triple quotes..."""
[EOF]
(Pdb) step
> test.py(8)f()
-> """but it's intelligent about triple quotes..."""
(Pdb) step
--Return--
> test.py(8)f()->None
-> """but it's intelligent about triple quotes..."""
(Pdb) 
>>>

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