jupyter / jupyter_client

Jupyter protocol client APIs
https://jupyter-client.readthedocs.io
BSD 3-Clause "New" or "Revised" License
379 stars 280 forks source link

Supporting the Debug Adapter Protocol #446

Open JohanMabille opened 5 years ago

JohanMabille commented 5 years ago

At QuantStack, we are working on a prototype of debugger for the Jupyter ecosystem. This issue tracks the changes we need to make to get it done; some of them might be integrated independently from the debugger if they are considered as a global improvement.

The idea is to reuse the Debug Adaper Protocol from Microsoft. These messages are wrapped in new Jupyter messages that are sent on the Control channel.

1] Changes in the protocol

2] Changes in the frontends

Frontends should be able to send messages directly on the Control channel, which is currently not exposed at all:

Optional:

3] Changes in the backends

The required changes are specific to the implementations of the different kernels. However a same approach can be used:

As an example, we are using xeus and xeus-python to experiment with PTVSD.

cc @jasongrout @SylvainCorlay @afshin @ivanov @martinRenou @wolfv

EDIT: Actually exposing methods to handle debug messages in the Notebook server is not mandatory if we don't plan to add the debugger to the notebook. Exposing the control channel is enough as long as JupyterLab depends on the Notebook server. Exposing the control channel in the Jupyter server is useful if JupyterLab switches from the Notebook server to the Jupyter server at some point.

dsblank commented 5 years ago

Very nice! Long time needed. Thank you all for working on this and contributing to the project!

JohanMabille commented 5 years ago

The "phase1" of the development in xeus-python is finished. It can now start and stop an instance of ptvsd, many times in the same session, and it can forward messages from ptvsd to the frontend and vice versa.

1] Mapping Notebook cells to files

Now comes the problem of mapping Notebook cells to files. When setting a breakpoint, a path to a file containing the code and a line number must be specified. The file must exist, otherwise ptvsd won't break. This means that the kernel must create a file or several files containing the code of the Notebook cells. Besides, setting a breakpoint in a file actually removes all the breakpoints previously set, so it is mandatory to specify a list of breakpoints when sending a breakpoint request.

Typical usage of the debugger is to set breakpoints before starting the debugging sessions itself. Another use case is when a cell that already contains a breakpoint is modified before being executed again. Considering the constraints on breakpoints previously mentioned, the following sequence should allow to handle all the scenarios:

Since this requires sending additional messages to the kernel, this should be done only when a debug session has started. This means that either the user cannot set breakpoints before he has started the debugger, or that the frontend sends all the cells and the existing breakpoint list upon debugger start.

2] Implementation of the mapping in the kernel

Although this is kernel specific and should not impact the design of the protocol, I think it might be interesting to dicuss it here. Two approaches are possible:

I am not entirely clear with all the potential limitations we might still encounter with ptvsd, so I will play a bit with it and update this accordingly.

3] Stepping into imported files

This is specific to the frontend. When stepping into a function that is defined in an imported file, the frontend should open this file in text mode and allow to set breakpoints in it.