Skip to content
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

Investigate tests_python/test_bytecode_manipulation.py::test_set_pydevd_break_01 in Python 3.10.5 #973

Closed
fabioz opened this issue Jul 7, 2022 · 1 comment

Comments

@fabioz
Copy link
Collaborator

fabioz commented Jul 7, 2022

There's a failing test in the pydevd test suite related to bytecode which is failing only in Python 3.10.5.

This should be investigated (it could be a real error).

@fabioz
Copy link
Collaborator Author

fabioz commented Jul 7, 2022

I did an investigation here and the bytecode seems to be correct. What is happening is that on one run it seems like CPython doesn't report a line event while using the same bytecode (after inserting a programmatic breakpoint) it does.

I haven't really dug into CPython itself to know why it started with this behavior in CPython 3.10.5, but from what I've investigated, everything seems correct (the strange thing is that on the initial case before the programmatic breakpoint that line event isn't reported).

i.e.: Given some code as:

    @staticmethod
    def fun2():
        a = 1
        for i in range(1):
            for j in range(1, 3):
                if i + j >= 1:
                    break

it has some bytecode as:

 57           0 LOAD_CONST               1 (1)
              2 STORE_FAST               0 (a)

 58           4 LOAD_GLOBAL              0 (range)
              6 LOAD_CONST               1 (1)
              8 CALL_FUNCTION            1
             10 GET_ITER
        >>   12 FOR_ITER                18 (to 50)
             14 STORE_FAST               1 (i)

 59          16 LOAD_GLOBAL              0 (range)
             18 LOAD_CONST               1 (1)
             20 LOAD_CONST               2 (3)
             22 CALL_FUNCTION            2
             24 GET_ITER
        >>   26 FOR_ITER                10 (to 48)
             28 STORE_FAST               2 (j)

 60          30 LOAD_FAST                1 (i)
             32 LOAD_FAST                2 (j)
             34 BINARY_ADD
             36 LOAD_CONST               1 (1)
             38 COMPARE_OP               5 (>=)
             40 POP_JUMP_IF_FALSE       23 (to 46)

 61          42 POP_TOP
             44 JUMP_FORWARD             1 (to 48)

 60     >>   46 JUMP_ABSOLUTE           13 (to 26)
        >>   48 JUMP_ABSOLUTE            6 (to 12)

 58     >>   50 LOAD_CONST               0 (None)
             52 RETURN_VALUE

Now, when on line 61, in the bytecode: 44 JUMP_FORWARD 1 (to 48), it should report a line event from line 61 to line 60, but this line event is NOT reported in the initial case, but after doing bytecode manipulation it is reported. My guess is that this is some optimization that CPython is doing when the file is loaded from disk the first time, whereas this isn't applied when we modify the bytecode directly on memory (I didn't really dig further in the CPython codebase to know the exact cause as I'm convinced already that the bytecode that the debugger generates is correct in this case).

Given that, I'll just use this issue to fix the test where this happens.

fabioz added a commit to fabioz/debugpy that referenced this issue Jul 8, 2022
@fabioz fabioz closed this as completed in b5072f3 Jul 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants