Repository navigation
Implement PEP 626 -- Precise line numbers for debugging #86412
Description
Activity
Implementation of PEP-626 requires:
- Implementation of the new line number table and associated APIs.
- Removal of BEGIN_DO_NOT_EMIT_BYTECODE and END_DO_NOT_EMIT_BYTECODE from the compiler as they do not understand line numbers and may remove lines from the bytecode that they shouldn't.
- Enhance compiler front-end and CFG optimizer to avoid the negative performance impact of PEP.
a) Duplicate the tests in while blocks to avoid the extra jump instruction at the end of the loop.
b) Duplicate and renumber terminator blocks that have no line numbers.
Guaranteeing that f_lineno is correct without hurting performance
-----------------------------------------------------------------PEP-626 mandates that the f_lineno attribute of a frame is always correct, even after a return or raise, but we don't want to hurt performance.
Since the interpreter ensures that the f_lasti attribute of a frame is always correct, we can ensure correctness of f_lineno at zero cost, by ensuring that all RETURN_VALUE, RAISE_VARARGS and RERAISE instruction have a non-negative line number. Then f_lineno can always be lazily computed from f_lasti.The front-end generates artificial RERAISEs and RETURN_VALUE that have no line number. To give these instructions a valid line number we can take advantage of the fact that such terminator blocks (blocks with no successors) can be freely duplicated. Once duplicated, each terminator block will have only one predecessor and can acquire the line number of the preceding block, without causing false line events.
- addedtype-featureA feature request or enhancementA feature request or enhancement3.10 (EOL)end of lifeend of life
on Nov 2, 2020 - addedtype-featureA feature request or enhancementA feature request or enhancement
on Nov 2, 2020 I'm happy that we are removing BEGIN_DO_NOT_EMIT_BYTECODE and END_DO_NOT_EMIT_BYTECODE but could you elaborate how this is related? These macros protect the compiler from emitting bytecode that corresponds to deaf code and by definition, unreachable. Could you give an example of a situation in which they create something that messes up the line numbers? Is this something to be with cleanup blocks in dead code or something similar?
The following code is completely eliminated by the macros.
- if 0:
-
secret_debugging_code()
PEP-626 says that all executed lines of code must generate trace events,
so we need to emit an instruction for line 1.Dead code elimination will remove the
secret_debugging_code(), but leave the test. The peephole optimiser can then reduce it to a NOP, but won't eliminate it as it is the only instruction for line 1.Dead code elimination will remove the
secret_debugging_code(), but leave the test. The peephole optimiser can then reduce it to a NOP, but won't eliminate it as it is the only instruction for line 1.Gotcha. I am pretty sure that this will have a similar problem as the coverage people were claiming when we were not properly removing all dead code (slightly less coverage percentage). This is not a problem of course, but we should ping the coverage folks so they are aware of this.
New changeset 877df85 by Mark Shannon in branch 'master':
bpo-42246: Partial implementation of PEP-626. (GH-23113)This change introduced reference leaks:
https://buildbot.python.org/all/#builders/384/builds/1005 tests failed:
test_asyncgen test_builtin test_coroutines test_exceptions
test_syntaxFor example:
$ ./python -m test test_syntax -R 3:3 -m test.test_syntax.SyntaxTestCase.test_no_indent 0:00:00 load avg: 1.59 Run tests sequentially 0:00:00 load avg: 1.59 [1/1] test_syntax beginning 6 repetitions 123456 ...... test_syntax leaked [27, 27, 27] references, sum=81 test_syntax leaked [20, 20, 20] memory blocks, sum=60 test_syntax failed== Tests result: FAILURE ==
1 test failed:
test_syntaxTotal duration: 955 ms
Tests result: FAILURE9 remaining items
- changed the title
[-]Implement PEP 626[/-][+]Implement PEP 626 -- Precise line numbers for debugging[/+]on Dec 11, 2020 Mark, I'm categorizing and characterizing the test failures. Here's the start of it: https://gist.github.com/nedbat/6c5dedde9df8d2de13de8a6a39a5f112 Let me know what other information would be useful.
Thanks Ned, that's really helpful. I'll go through those points:
Code after break/continue is no longer compiled.
ExpectedFirst line number of modules
ExpectedExcept clause when no exception
https://bugs.python.org/issue42634Double loops (this also covers End-of-loop jumps, I think)
https://bugs.python.org/issue42635I want to merge #23743 before I fix any of the others, but here is a summary of what I think are the root causes.
if-break
Exit block duplication does not preserve line number of jump to final blockFinally handling
Combination of two things. Not preserving line numbers when performing jump-to-jump elimination and not marking try cleanup code as artificial.#23780 fixes the finally handling.
The if-break case was fixed by earlier changes.All done :)
Is there a reason PEP-626 isn't yet mentioned in https://docs.python.org/3.10/whatsnew/3.10.html ?
No. We should add it.
PEP-626 deprecates co_lnotab, co_lnotab:
https://www.python.org/dev/peps/pep-0626/#id15
This doesn't seem to be mentioned in the What's new document and is quite important. Mark, do you mind creating a PR for this? I could do it and add you as a reviewer if you wish
f_lasti, and thusf_lineno, is set correctly after raising or reraising an exception #23803Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields: