-
Notifications
You must be signed in to change notification settings - Fork 294
How to debug the debugger
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.
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 |
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:
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:
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
}
}
}
- Contribution
- Source Code Organization
- Coding Standards
- Profiling
- Coding Guidelines
- Component Governance
- Writing tests
- Kernels
- Intellisense
- Debugging
- IPyWidgets
- Extensibility
- Module Dependencies
- Errors thrown
- Jupyter API
- Variable fetching
- Import / Export
- React Webviews: Variable Viewer, Data Viewer, and Plot Viewer
- FAQ
- Kernel Crashes
- Jupyter issues in the Python Interactive Window or Notebook Editor
- Finding the code that is causing high CPU load in production
- How to install extensions from VSIX when using Remote VS Code
- How to connect to a jupyter server for running code in vscode.dev
- Jupyter Kernels and the Jupyter Extension