8.2 KiB
Debugging Guide
This guide covers debugging with DAP (Debug Adapter Protocol) for TypeScript, Python, and Go.
Overview
DAP provides IDE-like debugging:
- Breakpoints (line, conditional, logpoints)
- Step through code (into, over, out)
- Variable inspection
- Call stack navigation
- Expression evaluation
Quick Start
Basic Debugging Flow
- Set breakpoint:
<leader>db - Start debugger:
<leader>dc - Step through:
<leader>di(into),<leader>do(over) - Inspect:
<leader>du(toggle UI) - Stop:
<leader>dt
Key Bindings
Breakpoints
| Key | Action |
|---|---|
<leader>db |
Toggle breakpoint |
<leader>dB |
Conditional breakpoint |
<leader>dl |
Log point (print without stopping) |
Execution Control
| Key | Action |
|---|---|
<leader>dc |
Continue (or start) |
<leader>di |
Step into |
<leader>do |
Step over |
<leader>dO |
Step out |
<leader>dC |
Run to cursor |
<leader>dp |
Pause |
<leader>dt |
Terminate |
<leader>dr |
Toggle REPL |
UI & Inspection
| Key | Action |
|---|---|
<leader>du |
Toggle DAP UI |
<leader>de |
Evaluate expression |
<leader>dw |
Add to watch |
<leader>ds |
View scopes |
DAP UI Layout
When you press <leader>du, the UI shows:
┌─────────────┬─────────────────────┐
│ Scopes │ │
│ (variables) │ Source Code │
├─────────────┤ (your file) │
│ Breakpoints │ │
├─────────────┤ │
│ Call Stack │ │
├─────────────┼─────────────────────┤
│ Watch │ Console/REPL │
└─────────────┴─────────────────────┘
Scopes Panel
Shows variables in current scope:
- Local variables
- Function arguments
- Global variables
- Expand objects/arrays with
<cr>
Call Stack Panel
Shows function call hierarchy:
- Current function at top
- Click to jump to that frame
- See where you came from
Breakpoints Panel
Lists all breakpoints:
- Toggle enable/disable
- Delete breakpoints
- See conditions
Watch Panel
Add expressions to monitor:
<leader>dwto add- Updates as you step
Debugging by Language
TypeScript/JavaScript
Prerequisites
npm install -g @vscode/js-debug
Debug Current File
- Open your
.tsor.jsfile <leader>db- Set breakpoint<leader>dc- Start debugging- Select "Node.js: Launch" or similar
Debug Tests
<leader>td Debug test at cursor
This automatically sets up the test runner with debugging.
launch.json Example
{
"version": "0.2.0",
"configurations": [
{
"type": "pwa-node",
"request": "launch",
"name": "Debug Current File",
"program": "${file}",
"cwd": "${workspaceFolder}",
"sourceMaps": true
},
{
"type": "pwa-node",
"request": "launch",
"name": "Debug Server",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build",
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]
}
Python
Prerequisites
pip install debugpy
Debug Current File
- Open your
.pyfile <leader>db- Set breakpoint<leader>dc- Start debugging- Select "Python: Current File"
Debug Tests
<leader>td Debug test at cursor
launch.json Example
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"args": ["run", "--debug"],
"env": {
"FLASK_APP": "app.py"
}
},
{
"name": "Python: Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver", "--noreload"]
}
]
}
Go
Prerequisites
go install github.com/go-delve/delve/cmd/dlv@latest
Debug Current File
- Open your
.gofile <leader>db- Set breakpoint<leader>dc- Start debugging- Select "Go: Debug Package"
Debug Tests
<leader>td Debug test at cursor
Works with table-driven tests too!
launch.json Example
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Package",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${fileDirname}"
},
{
"name": "Debug Main",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceFolder}/cmd/server"
},
{
"name": "Attach to Process",
"type": "go",
"request": "attach",
"mode": "local",
"processId": "${command:pickProcess}"
}
]
}
Breakpoint Types
Line Breakpoint
Standard breakpoint - stops when line is reached:
<leader>db Toggle on current line
Conditional Breakpoint
Only stops when condition is true:
<leader>dB Prompts for condition
Example conditions:
x > 10user.name == "test"items.length > 0
Log Point
Prints message without stopping:
<leader>dl Prompts for log message
Use {} for interpolation:
Value of x: {x}User: {user.name}
Hit Count Breakpoint
Stop after N hits (set via conditional):
<leader>dB Enter: hitCount > 5
Debugging Strategies
Step Through Unknown Code
- Set breakpoint at entry point
<leader>dc- Start<leader>di- Step into functions to understand them<leader>do- Step over when you understand<leader>dO- Step out when done with function
Find Where Value Changes
- Set breakpoint where value is used
<leader>dw- Add variable to watch- Step through, watching for changes
- Or use conditional breakpoint:
x != expectedValue
Debug Loops
- Set conditional breakpoint:
i == problematicIndex - Or use hit count: stop after N iterations
- Check variables at specific iteration
Remote Debugging
For processes running elsewhere:
- Start process with debug flag
- Use "attach" configuration
- Connect to debug port
Common Workflows
Finding a Bug
- Reproduce the bug path
- Set breakpoint before bug occurs
<leader>dc- Start debugging- Step through, inspecting variables
- Find where actual != expected
- Fix and re-test
Understanding New Code
- Set breakpoint at function entry
<leader>dc- Start with a test case<leader>di- Step into each function- Use watch to track key variables
- Build mental model of flow
Performance Investigation
Use log points to trace without stopping:
<leader>dlat key points- Log timing:
Start: {Date.now()} - Run normally
- Check console for timing
Tips
Quick Variable Inspection
Hover over variable with cursor - shows value in float.
REPL Usage
<leader>dr opens REPL where you can:
- Evaluate expressions
- Call functions
- Modify variables (sometimes)
Restart Debugging
If you need to start over:
<leader>dt Terminate
<leader>dc Start again
Breakpoint Persistence
Breakpoints are saved per session. They'll be there when you reopen the file.
Troubleshooting
Debugger Won't Start
- Check adapter is installed
:DapShowLogfor errors- Verify launch configuration
Breakpoints Not Hit
- Verify file paths match
- Check source maps (TypeScript)
- Ensure code is actually executed
Variables Not Showing
- Might be optimized out (Go)
- Check scope (local vs global)
- Try evaluating directly:
<leader>de
Source Maps Issues (TypeScript)
- Ensure
sourceMaps: truein launch.json - Check tsconfig has
sourceMap: true - Verify outFiles pattern matches
Slow Debugging
- Reduce number of breakpoints
- Use conditional breakpoints
- Disable logging breakpoints when not needed