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

Code work well but debugger returns a mistake. #348

Closed
asukaminato0721 opened this issue Jul 25, 2020 · 5 comments
Closed

Code work well but debugger returns a mistake. #348

asukaminato0721 opened this issue Jul 25, 2020 · 5 comments

Comments

@asukaminato0721
Copy link

Environment data

  • VS Code version: 1.47.2
  • Extension version (available under the Extensions sidebar): v2020.7.96456
  • OS and version: windows10 1803
  • Python version (& distribution if applicable, e.g. Anaconda): 3.7.0 32-bit
  • Type of virtual environment used (N/A | venv | virtualenv | conda | ...): N/A
  • Relevant/affected Python packages and their versions: N/A
  • Relevant/affected Python-related VS Code extensions and their versions: N/A
  • Value of the python.languageServer setting: "Microsoft"

Expected behaviour

This code below is worked properly.

a = [1, 2]
def b():
    yield from [j for j in a if j % 2 == 0]
for j in b():
    print(j)

Actual behaviour

I add break points at each line,and debug it, then it returns

image

Steps to reproduce:

[NOTE: Self-contained, minimal reproducing code samples are extremely helpful and will expedite addressing your issue]

  1. Add break points at each line and then debug.

I guess the reason is

image

this list_iterator object is vanished at the last time. But debugger tried to visit it, and throw out a mistake.

Logs

Output for Python in the Output panel (ViewOutput, change the drop-down the upper-right of the Output panel to Python)

XXX

@asukaminato0721 asukaminato0721 changed the title yield from with 'list_iterator' object is not callable. Code work well but debugger returns a mistake. Jul 25, 2020
@brettcannon brettcannon transferred this issue from microsoft/vscode-python Jul 27, 2020
@int19h
Copy link
Contributor

int19h commented Jul 27, 2020

@fabioz, this might be another manifestation of the root cause #346 - repros in VSCode on 3.7 (i.e. with native bits), but not on 3.8.

Furthermore, repro does depend on where exactly breakpoints are set - in my experiments, it requires breakpoints on lines 2 and 3, but having it on 3 alone works fine. So I think there's some interaction between those two that causes the conditional logic behind the iterator to take a wrong path somewhere.

@int19h
Copy link
Contributor

int19h commented Jul 27, 2020

@wuyudi, please try the workaround in #346 (comment) while we investigate.

@fabioz
Copy link
Collaborator

fabioz commented Jul 28, 2020

I'll investigate this one too (along with #346).

@fabioz
Copy link
Collaborator

fabioz commented Jul 30, 2020

I believe I found the culprit here... the problem is that in frame evaluation mode a generator creates a new frame each time it's suspended and then later resumed but keeps on reusing the same code.

There's a provision so that the same code is returned, but in this particular case it doesn't seem to work properly (it uses the lines in the function for the breakpoints, but when adding the breakpoint itself it adds a new line prior to the needed line and this ends up confusing this cache on a subsequent invocation).

I'm already working on a fix (as a note, the same issue could happen when breakpoints are changed for generators, so, the fix should also cover that).

Note: given that this is related to generators, this is probably a different issue from #346 (although I still haven't investigated nor reproduced that one).

@Felk
Copy link

Felk commented Aug 1, 2020

I encountered a similar issue which seems to be fixed with fabioz@ef4245f

print("before loop")
async def hundredFramesPassed():
    while memory.read_u32(0x8063fc2c) < 100:
        await event.frameadvance()

foo = hundredFramesPassed()
await hundredFramesPassed()
print("I lived!")

I consistently reproduced the issue by

  • starting with a breakpoints on await hundredFramesPassed()
  • once that got hit, add a breakpoint to await event.frameadvance() and resume
  • once that got hit, remove the breakpoint on await event.frameadvance() and resume

On the current master this exception is thrown:

Traceback (most recent call last):
  File "D:\Projekte\git\dolphinFelk\Binary\x64\.\testscript2.py", line 24, in <module>
    await hundredFramesPassed()
  File "D:\Projekte\git\dolphinFelk\Binary\x64\.\testscript2.py", line 21, in hundredFramesPassed
    await event.frameadvance()
  File "C:\Users\studi\AppData\Roaming\Python\Python38\site-packages\debugpy\_vendored\pydevd\_pydevd_frame_eval\pydevd_frame_tracing.py", line 36, in _pydev_stop_at_break
    if t.additional_info.is_tracing:
AttributeError: '_DummyThread' object has no attribute 'additional_info'

Using https://github.com/fabioz/debugpy/commits/debugpy_348 it doesn't crash and I lived! is printed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants