Re: [Python-Dev] seeing off SET_LINENO
"Mark Hammond" <mhammond@skippinet.com.au> writes:
"Mark Hammond" <mhammond@skippinet.com.au> writes:
IMO, the Python debugger "interface" should include function entry.
There goes the time machine: it does. I just think everyone ignores 'call' messages because they're a bit redundant today (because of the matter under discussion).
Yes, I should have said "continue to include function entry".
I understood that a patch under discussion may have *removed* this facility from the debugger.
Nononononononono. No. No. Currently a trace function can be called for four reasons: 'call', 'line', 'return' and 'raise'. 'call' is called high up in eval_frame, on entry to the code object (I suspect it is also called on resumption of generators, but also suspect that this is accidental). 'return' is called when the main loop finished with why == WHY_RETURN or WHY_YIELD, 'raise' ditto but why == WHY_EXCEPTION. None of these are affected by my patch. At the moment 'line' is called by the SET_LINENO opcode. My patch changes it to be called when the co_lnotab indicates execution has moved onto a different line. The reason this changes behaviour is that currently a SET_LINENO opcode is emitted for the def line of every function (I guess this is to cope with def functions_like_this(): return 1 ). After my patch there are no SET_LINENO opcodes, so execution is never on the def line[*], so no 'line' trace event is generated for the def line, so a debugger that only listens to the 'line' events and ignores the 'call' events will not stop on that line. If my patch goes in, I'll probably change pdb to catch 'call' events, and nag authors of other debuggers that they should do the same. It is possible to generate an extra 'line' trace event to mimic the old behaviour, but it's gross.
While I agree it is redundant and most debuggers will choose to ignore it, I believe removing it from the low level debugger hooks would be a mistake.
Now I've spent some minutes explaining myself, you can explain to me where you got the idea that I was even considering doing so from! Cheers, M. [*] For a typical function which has no code on the def line. -- 34. The string is a stark data structure and everywhere it is passed there is much duplication of process. It is a perfect vehicle for hiding information. -- Alan Perlis, http://www.cs.yale.edu/homes/perlis-alan/quotes.html
[Michael]
At the moment 'line' is called by the SET_LINENO opcode. My patch changes it to be called when the co_lnotab indicates execution has moved onto a different line.
The reason this changes behaviour is that currently a SET_LINENO opcode is emitted for the def line of every function (I guess this is to cope with
def functions_like_this(): return 1
Right - sorry - my misunderstanding.
If my patch goes in, I'll probably change pdb to catch 'call' events, and nag authors of other debuggers that they should do the same.
Yes, I agree this should not be necessary. You may even find debugger implementers already hack around this :) And yes, I agree that if debugger implementers really want to hook something on function entry, they should use the facility explicity designed for that purpose ;)
It is possible to generate an extra 'line' trace event to mimic the old behaviour, but it's gross.
Agreed.
Now I've spent some minutes explaining myself, you can explain to me where you got the idea that I was even considering doing so from!
Sorry, I just didn't re-read the thread well enough. Jumping to conclusions seems to be one of my strong points ;) Mark.
After my patch there are no SET_LINENO opcodes, so execution is never on the def line[*], so no 'line' trace event is generated for the def line, so a debugger that only listens to the 'line' events and ignores the 'call' events will not stop on that line.
If the argument list contains embedded tuples, there's code executed to unpack those before the first line of the function. Example:
def f(a, (b, c), d): ... print a, b, c, d ... f(1, (2, 3), 4) 1 2 3 4 f(1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 1, in f TypeError: unpack non-sequence
I hope the debugger will stop *before* this unpacking happens! It does now:
import pdb pdb.run("f(1, 2, 3)") <string>(0)?() (Pdb) s <string>(1)?() (Pdb) <stdin>(1)f() (Pdb) TypeError: 'unpack non-sequence' <stdin>(1)f() (Pdb) q
--Guido van Rossum (home page: http://www.python.org/~guido/)
participants (3)
-
Guido van Rossum
-
Mark Hammond
-
Michael Hudson