[Python-bugs-list] [ python-Bugs-708901 ] Lineno calculation sometimes broken

SourceForge.net noreply@sourceforge.net
Tue, 29 Apr 2003 11:41:10 -0700


Bugs item #708901, was opened at 2003-03-24 17:09
Message generated for change (Comment added) made by arigo
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=708901&group_id=5470

Category: Python Interpreter Core
Group: Python 2.3
Status: Closed
Resolution: Fixed
Priority: 5
Submitted By: Greg Chapman (glchapman)
Assigned to: Michael Hudson (mwh)
Summary: Lineno calculation sometimes broken

Initial Comment:
I'm running the win32 version of Python 2.3a2.  I ran into 
this when I got a traceback pointing to a wrong 
linenumber.  It also messes up debugging in 
Pythonwin.  Anyway, you can see from the disassembly 
below that something goes seriously amiss when the 
code reaches the FOR_ITER:


>>> import httplib
>>> import dis
>>> dis.dis(httplib.HTTPConnection.connect)
524           0 LOAD_CONST

              3 STORE_FAST

525           6 SETUP_LOOP
              9 LOAD_GLOBAL
             12 LOAD_ATTR
             15 LOAD_FAST
             18 LOAD_ATTR
             21 LOAD_FAST
             24 LOAD_ATTR
             27 LOAD_CONST

526          30 LOAD_GLOBAL
             33 LOAD_ATTR
             36 CALL_FUNCTION
             39 GET_ITER

781     >>   40 FOR_ITER


----------------------------------------------------------------------

Comment By: Armin Rigo (arigo)
Date: 2003-04-29 18:41

Message:
Logged In: YES 
user_id=4771

Someone motivated could go ahead and allow for ranges of
bytecodes to be mapped to *ranges* of line numbers instead
of to just a single line. The debugger would then display
all the lines in the range. The result would be more natural
when single-stepping through multiline statements.

It would also give a clean fix to several problems beside
the one discussed here, e.g. the final POP_TOP of an
if/then/else being mapped to the last line of the 'else'
part, but being reached when the 'then' branch is taken.
This currently works as expected because the line trace hook
is only fired when we reach the first opcode of a range, not
when we jump in the middle of a range -- which is a hack
because it is the cause of Michael's patch not stopping on
the 'for' after each iteration.

I may be the aforementioned motivated person if the solution
seems worthwhile to try :-)

----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-04-29 17:08

Message:
Logged In: YES 
user_id=6656

Used Tim's idea on compile.c.

Knocked test_dis about a bit to include this case, and make
it *slightly* less rampantly fragile.

Python/compile.c revision 2.282
Lib/test/test_trace.py revision 1.3

----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-04-29 11:40

Message:
Logged In: YES 
user_id=6656

> Well, this one's a mess.

Hadn't noticed that <wink>.

I had become aware that my patch wasn't the right answer. 
I'll try your idea when cvs up finishes...

> Unfortunately, the encoding of lnotab assumes that line 
> numbers and byte offsets are presented in monotonically 
> non-decreasing order.

Presumably this *could* change, if we were sufficiently
motivated.

----------------------------------------------------------------------

Comment By: Tim Peters (tim_one)
Date: 2003-04-28 20:57

Message:
Logged In: YES 
user_id=31435

Well, this one's a mess.  The patch changes debugger 
behavior in that it no longer stops on the 'for' each time 
around the loop.  I had better luck leaving the com_set_lineno
() call where it is now, but changing its second argument 
instead, like so:

	com_set_lineno(c, c->c_last_line);

Then it stops on the "for" each time around the loop, but 
pointing at the last line of the "for" (in your whittled example, 
on the line ending with "10):").  Better than nothing.

Unfortunately, the encoding of lnotab assumes that line 
numbers and byte offsets are presented in monotonically non-
decreasing order.

----------------------------------------------------------------------

Comment By: Neal Norwitz (nnorwitz)
Date: 2003-03-29 23:38

Message:
Logged In: YES 
user_id=33168

The patch worked for me on Linux, after I removed
httplib.pyc. :-)
Does it jump to the right line in the debugger whe iterating
through a loop?

----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-03-24 17:43

Message:
Logged In: YES 
user_id=6656

Stupid minimal testcase:

def f():
    for res in range(1,
                     10):
        pass

Tim, you've looked at compile.c today <wink>, can you check
the attached patch?


----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-03-24 17:36

Message:
Logged In: YES 
user_id=6656

Waddya know, it's not my fault.

For some reason, something is trying to store a negative
line_incr into the c_lnotab which gets masked into a line
increment of 255.  Fun.


----------------------------------------------------------------------

Comment By: Michael Hudson (mwh)
Date: 2003-03-24 17:16

Message:
Logged In: YES 
user_id=6656

yow!  probably my fault.

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=708901&group_id=5470