PDB does not allow jumping to first statement?

Duncan Booth duncan.booth at invalid.invalid
Tue Mar 27 11:39:19 CEST 2007


Peter Otten <__peter__ at web.de> wrote:

>> Which version of Python, and what happens when you try it?
>> 
>> It works fine for me with Python 2.5 on Windows:
>> 
>> C:\Temp>\python25\python -m pdb t.py
>>> c:\temp\t.py(3)<module>()
>> -> a = 1
>> (Pdb) s
>>> c:\temp\t.py(4)<module>()
>> -> b = 2
>> (Pdb) j 3
>>> c:\temp\t.py(3)<module>()
>> -> a = 1
>> (Pdb)
> 
> It looks like you successfully jumped to the first line, but it will 
be
> skipped if you try to execute it:
> 

That's why I asked what actually happened. Yes, you and the OP seem to 
be correct, jumping to the first executable line in a module appears not 
to execute the line.

I verified (with a print statement in pdb) that assigning to 
self.curframe.f_lineno sets self.curframe.f_lineno and 
sel.curframe.f_lasti incorrectly:

C:\Temp>\python25\python -m pdb t.py
> c:\temp\t.py(3)<module>()
-> a = 1
(Pdb) s
> c:\temp\t.py(4)<module>()
-> b = 2
(Pdb) s
> c:\temp\t.py(5)<module>()
-> a = 3
(Pdb) l
  1     #!/usr/bin/env python
  2
  3     a = 1
  4     b = 2
  5  -> a = 3
  6     c = a + b
  7     import dis, sys
  8     dis.dis(sys._getframe().f_code)
  9     print c
[EOF]
(Pdb) j 4
f_lineno 4 f_lasti 6
> c:\temp\t.py(4)<module>()
-> b = 2
(Pdb) j 3
f_lineno 4 f_lasti 6
> c:\temp\t.py(3)<module>()
-> a = 1
(Pdb) j 5
f_lineno 5 f_lasti 12
> c:\temp\t.py(5)<module>()
-> a = 3
(Pdb) j 3
f_lineno 4 f_lasti 6
> c:\temp\t.py(3)<module>()
-> a = 1
(Pdb)

The problem looks to be in frameobject.c:

	addr = 0;
	line = f->f_code->co_firstlineno;
	new_lasti = -1;
	for (offset = 0; offset < lnotab_len; offset += 2) {
		addr += lnotab[offset];
		line += lnotab[offset+1];
		if (line >= new_lineno) {
			new_lasti = addr;
			new_lineno = line;
			break;
		}
	}

The first bytes in lnotab are the length and line increment for line 3 
(i.e. 6, 1). If line==f->f_code->co_firstlineno it should set new_lasti=
0, new_lineno=line but the loop still executes once which increments 
new_lasti and new_lineno to the next line (6, 4).





More information about the Python-list mailing list