Skip to content

How to debug the debugger

Rich Chiodo edited this page Aug 4, 2022 · 17 revisions

This page describes how to debug the jupyter extension and debugpy when the user is running a 'debug' command. You should probably read all of the debug topics to familiarize yourself with how debugging works before following the steps below.

Debugging Extension side code

When the user clicks Debug Cell in a notebook, there are a number of entrypoints (as shown in the sequence diagram on the other wiki page)

You can debug these entry points just like debugging anything in the extension:

  • Set a breakpoint
  • Launch 'Extension' debugger launch.json entry.
  • Perform the user task to start debugging
Entry Point Why you might start here What the cause might be
Debugging Manager::startDebuggingConfig Debug cell isn't starting the debugger. This is the main entrypoint and it's what tells VS code to start the debugger Debug config may not match, so check the config when starting.
Kernel Debug Adapter::handleMessage Debug cell is starting the debugger (or entering debug mode) but breakpoints don't hit or the cell never looks like it's running. The correct DAP messages are note being sent to the kernel.
Kernel Debug Adapter::onIOPubMessage Debug cell is starting the debugger (or entering debug mode) but breakpoints don't hit or the cell never looks like it's running. The resulting DAP messages from the debugpy are referencing invalid paths or showing an error.
Kernel Debug Adapter::dumpCell Debug cell is starting the debugger and cell seems to run, but breakpoints don't bind or seem to jump around dumpCell may be creating output files not referencable by VS code (like remote paths) or line number translation could be off
Kernel Debug Adapter::translate functions Breakpoints move or don't bind. Wrong files open when stopping File path translation is generating invalid paths for debugpy or there's a line number translation problem

Debugging Debugpy

Okay so what if all of those entry points look good but debugpy just doesn't seem to respond correctly?

There are three things you can do to debug debugpy:

Turn on logging

The easiest thing to do is turn on logging for debugpy with some environment variables:

Environment Variable Value
PYDEVD_DEBUG true
DEBUGPY_LOG_DIR directory that already exists
PYDEVD_DEBUG_FILE directory that already exists - use same as previous variable

Launching VS code with these environment variables set will generate files like so in the directory specified:

image

These files are:

  • debugpy.adapter - messages logged by the adapter process (process that is speaking DAP with VS code)
  • debugpy.pydevd - messages logged by pydevd (generally has more information)
  • debugpy.server - messages logged when debugpy is started in listen mode (more DAP messages)

Opening the adapter log should list out the the DAP messages and their contents. Here's an example:

D+00000.234: Client[1] --> {
                 "seq": 1,
                 "type": "request",
                 "command": "initialize",
                 "arguments": {
                     "clientID": "vscode",
                     "clientName": "Visual Studio Code - Insiders",
                     "adapterID": "Python Interactive Window Debug Adapter",
                     "pathFormat": "path",
                     "linesStartAt1": true,
                     "columnsStartAt1": true,
                     "supportsVariableType": true,
                     "supportsVariablePaging": true,
                     "supportsRunInTerminalRequest": true,
                     "locale": "en",
                     "supportsProgressReporting": true,
                     "supportsInvalidatedEvent": true,
                     "supportsMemoryReferences": true
                 }
             }

This is:

  • a message sent from the client (VS Code) indicated by Client[1] -->
  • an initialize message (first DAP message)

A response from the server would look like:

D+00000.281: Server[1] --> {
                 "pydevd_cmd_id": 502,
                 "seq": 10,
                 "type": "response",
                 "request_seq": 5,
                 "success": true,
                 "command": "initialize",
                 "body": {
                     "supportsConfigurationDoneRequest": true,
                     "supportsFunctionBreakpoints": true,
                     "supportsConditionalBreakpoints": true,
                     "supportsHitConditionalBreakpoints": true,
                     "supportsEvaluateForHovers": true,
                     "exceptionBreakpointFilters": [
                         {
                             "filter": "raised",
                             "label": "Raised Exceptions",
                             "default": false
                         },
                         {
                             "filter": "uncaught",
                             "label": "Uncaught Exceptions",
                             "default": true
                         },
                         {
                             "filter": "userUnhandled",
                             "label": "User Uncaught Exceptions",
                             "default": false
                         }
                     ],
                     "supportsStepBack": false,
                     "supportsSetVariable": true,
                     "supportsRestartFrame": false,
                     "supportsGotoTargetsRequest": true,
                     "supportsStepInTargetsRequest": true,
                     "supportsCompletionsRequest": true,
                     "completionTriggerCharacters": [],
                     "supportsModulesRequest": true,
                     "additionalModuleColumns": [],
                     "supportedChecksumAlgorithms": [],
                     "supportsRestartRequest": false,
                     "supportsExceptionOptions": true,
                     "supportsValueFormattingOptions": true,
                     "supportsExceptionInfoRequest": true,
                     "supportTerminateDebuggee": true,
                     "supportsDelayedStackTraceLoading": true,
                     "supportsLoadedSourcesRequest": false,
                     "supportsLogPoints": true,
                     "supportsTerminateThreadsRequest": false,
                     "supportsSetExpression": true,
                     "supportsTerminateRequest": true,
                     "supportsDataBreakpoints": false,
                     "supportsReadMemoryRequest": false,
                     "supportsDisassembleRequest": false,
                     "supportsClipboardContext": true,
                     "supportsDebuggerProperties": true,
                     "pydevd": {
                         "processId": 21600
                     }
                 }
             }

Debug debugpy's DAP server

Add extra logging to pydevd

Clone this wiki locally