-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
frame.setlineno has serious flaws. #94438
Comments
…nes. (pythonGH-94444) (cherry picked from commit be80db1) Co-authored-by: Mark Shannon <[email protected]>
Moving this back to release blocker because apparently, this could end in many changes. I am missing some context here on what this is affecting so I changed it from deferred blocker to release blocker if we think we can delay this to 3.12, please, say so :) |
…O and POP_EXCEPT cases are no longer reachable
After failing to write a test that will crash on this, I analysed the code and realised that the "exception handling opcode" cases of the switch are no longer reachable - there is nothing that will initialise their stack[] entries, so they get skipped in the I created a PR to use my favourite macro in these cases: #94582 We could backport it, but we don't have to. |
I'm assuming this refers to the mark_stacks loop again, which is where stacks are produced. The good news is that it looks like it just happens to work by accident. There is no case in the switch for the CACHE opcode, so it goes to the default case. Since the stack_effect of CACHE is 0, it just copies We could make it more explicit like this:
thoughts? |
…ACHE opcodes which leaves the stack unchanged
Don't cache entries get populated at specialization time with data that overwrites the CACHE opcode? I don't think we're keeping around 0s in the bytecode that aren't subject to change. If I'm understanding right, the problem comes from misinterpreting that specialized cache data as if it's some bytecode that has a stack effect. It looks like the dis module looks up |
Ah I see! Would you like to try? (I'm signing off for the night soon.) |
I don't think I'm going to have time in the next couple of days to come up with a decent test case and PR and everything, but I am thinking that something vaguely like this could work: @@ -213,12 +213,15 @@ mark_stacks(PyCodeObject *code_obj, int len)
int todo = 1;
while (todo) {
todo = 0;
- for (i = 0; i < len; i++) {
+ int ncaches;
+ for (i = 0; i < len; i += (1 + ncaches)) {
+ ncaches = 0;
int64_t next_stack = stacks[i];
if (next_stack == UNINITIALIZED) {
continue;
}
- opcode = _Py_OPCODE(code[i]);
+ opcode = _PyOpcode_Deopt[_Py_OPCODE(code[i])];
+ ncaches = _PyOpcode_Caches[opcode];
switch (opcode) {
case JUMP_IF_FALSE_OR_POP:
case JUMP_IF_TRUE_OR_POP: |
…POP_EXCEPT cases are no longer reachable (GH-94582)
…EXC_INFO and POP_EXCEPT cases are no longer reachable (pythonGH-94582) (cherry picked from commit 50b9a77) Co-authored-by: Irit Katriel <[email protected]>
…FO and POP_EXCEPT cases are no longer reachable (GH-94582) (GH-94595) (cherry picked from commit 50b9a77) Co-authored-by: Irit Katriel <[email protected]>
…k_stacks (pythonGH-95110) (cherry picked from commit e4d3a96) Co-authored-by: Brandt Bucher <[email protected]>
…ks (GH-95110) (cherry picked from commit e4d3a96) Co-authored-by: Brandt Bucher <[email protected]>
Removing release blocker status since all known crashes are fixed. I'm still going to leave this open, thoough, since the four "is None" jumps aren't handled yet (which just means that we aren't able to jump to some valid locations). |
I just noticed that the switch in mark_stacks doesn't have cases for POP_JUMP_IF_NONE/POP_JUMP_IF_NOT_NONE. |
Yep. See my above comment. :) |
ah yeah :) |
Shall we nevertheless close this, and open a more specific issue? |
Yes. |
) (cherry picked from commit 6640f1d) Co-authored-by: Savannah Ostrowski <[email protected]>
(cherry picked from commit 6640f1d) Co-authored-by: Savannah Ostrowski <[email protected]>
pythonGH-111341) (cherry picked from commit a254120) Co-authored-by: Tian Gao <[email protected]>
…ce (GH-111369) (cherry picked from commit a254120) Co-authored-by: Tian Gao <[email protected]>
The
frame_setlineno
function works in in stages:The first steps is faulty (I think, I haven't demonstrated this) as it might be possible to jump to an instruction involved in frame creation. This should be easy to fix using the new
_co_firsttraceable
field.The second step has (at least) three flaws:
NULL
s on the stack, making it possible to jump from a stack withNULL
s to one that cannot handleNULL
s.PUSH_EXC_INFO
pushes three values. It only pushes one.Setting the line number of a frame is only possible in the debugger, so this isn't as terrible as might appear, but it definitely needs fixing.
Linked PRs
RuntimeWarning
for jump tests intest_sys_settrace
#111341The text was updated successfully, but these errors were encountered: