microsoft / debugpy

An implementation of the Debug Adapter Protocol for Python
https://pypi.org/project/debugpy/
Other
1.81k stars 131 forks source link

Stop at breakpoints during evaluate request (recursive debugging) #510

Open hcostelha opened 3 years ago

hcostelha commented 3 years ago

Environment data

Expected behaviour

Running a function from the debug console should stop in all breakpoints reached due to that call

Actual behaviour

I have done the following:

  1. I am running a debug session and am stopped at a brakpoint.
  2. I changed a function form an imported module.
  3. Added a breakpoint inside that function.
  4. Reloaded the corresponding module (the one with the new function) using importlib.
  5. Called that function from the Debug Console

The debugger did not stop at the breakpoint, as would be expected.

fabioz commented 3 years ago

I can't reproduce this... even reloading the module, the debugger does stop properly for me on the new function.

i.e.: By creating a main module with:

import reload_this
import importlib

def main():
    print('reload_this', reload_this.reload_func())
    reloaded = importlib.reload(reload_this)
    print('reloaded', reloaded.reload_func())

if __name__ == '__main__':
    main()

and a reload_this.py module with:

def reload_func():
    return 1  # break here

and putting a breakpoint at break here in the reload_func, running the function, waiting for it to hit the breakpoint the first time and then changing it to return 2, the function new function is reloaded and the breakpoint stops there the 2nd time too.

So, I'm not sure... can you give more information on how are you doing this?

Some things to check: are you adding a new breakpoint afterwards or a breakpoint in a different line?

-- one thing that could be an issue is that we may use linecache.getlines to validate the breakpoint if a new breakpoint is added, so, if it wasn't valid on the original file it's possible that the breakpoint won't be properly applied afterwards, so, you may want to call:

import linecache
linecache.clearcache()

after the module is reloaded and then reapply the breakpoint in the related file.

hcostelha commented 3 years ago

@fabioz , thanks for the reply. I have tried as you suggested and, indeed if I press "Play" to continue, it stops at the break point the second time. The problem here is that it stops at the breakpoint only if I choose "continue/play" in the debug menu, that is, it I call the function from the "Debug console" command line, it does not stop at the breakpoint, but immediately returns the result, even the first time, without changing the function. What I did to reproduce this was:

  1. Start the debug session stopping in the first line in the main() function;
  2. Place a breakpoint inside the the function "reolad_func()";
  3. Run the command "reload_this.reload_func()" in the Debug Console command line.

I would expect it to stop at the breakpoint inside the "reload_func()" within the "reload_this.py" file, but it immediately returned the function result. It seems that it does not stop at breakpoints at all when running from the "Debug console" command line. Is this the expected behavior?

fabioz commented 3 years ago

Is this the expected behavior?

Yes, this is currently expected. I'll change the title to reflect the feature request.

tbrodbeck commented 3 years ago

Hi. I think I experience the same issue. Only difference is that I am not using importlib: For some reason in some imported files/classes of my application breakpoints are not found. Strangely it does break on points in other imported files/classes, though.

In case this is a same issue: @fabioz I do not understand why this is expected behaviour, maybe you could help me understand that. In case this is not the same issue then I can open another issue!

fabioz commented 3 years ago

Hi. I think I experience the same issue. Only difference is that I am not using importlib: For some reason in some imported files/classes of my application breakpoints are not found. Strangely it does break on points in other imported files/classes, though.

In case this is a same issue: @fabioz I do not understand why this is expected behavior, maybe you could help me understand that. In case this is not the same issue then I can open another issue!

@tbrodbeck yours is a different issue (this issue is related to hitting breakpoints inside an evaluate request, not in general).

Please create a new issue for that (along with the logs on the case where it's not able to hit).

i.e.:

{
    "name": "Python: Current File (Integrated Terminal)",
    "type": "python",
    "request": "launch",
    "program": "${file}",
    "console": "integratedTerminal",
    "logToFile": true
}
tbrodbeck commented 3 years ago

@fabioz Thanks for the suggestion. I created this issue: https://github.com/microsoft/debugpy/issues/679

hk132435 commented 1 year ago

Hi,

This feature would be very helpful as often it may take a long time to reach particular point in program (load data, etc) to debug some function and being able to rerun it multiple times from console may save a lot of time.

Could anyone please comment whether there are plans to implement this feature for VSCode and/or whether there are limitations in python/pdb that prevent implementation of this feature.

fabioz commented 1 year ago

@hk132435 there are plans to implement it in debugpy but there's still no due date (best thing right now is voting this issue up so that it has more votes when it's time to decide which issues will be tackled).