Debugging¶
Debug configurations and techniques in VS Code.
Overview¶
VS Code provides built-in debugging for:
- JavaScript/TypeScript (Node.js, browser)
- Python
- Go
- C/C++
- Many more via extensions
Debug View¶
Open Debug view:
- Cmd+Shift+D or
- Click Debug icon in Activity Bar
Launch Configuration¶
Creating launch.json¶
- Open Debug view
- Click "create a launch.json file"
- Select debugger type
- Configuration created in
.vscode/launch.json
Basic Structure¶
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug Program",
"type": "python",
"request": "launch",
"program": "${file}"
}
]
}
Configuration Properties¶
| Property | Description |
|---|---|
name | Display name in dropdown |
type | Debugger type |
request | launch or attach |
program | File to debug |
args | Command line arguments |
cwd | Working directory |
env | Environment variables |
preLaunchTask | Task to run before debug |
Python Debugging¶
Basic Configuration¶
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Current File",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
}
]
}
With Arguments¶
{
"name": "Python: With Args",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"args": ["--verbose", "--config", "dev.yaml"],
"console": "integratedTerminal"
}
Module¶
{
"name": "Python: Module",
"type": "debugpy",
"request": "launch",
"module": "mypackage.main",
"console": "integratedTerminal"
}
Django¶
{
"name": "Django",
"type": "debugpy",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": ["runserver", "--noreload"],
"django": true
}
FastAPI¶
{
"name": "FastAPI",
"type": "debugpy",
"request": "launch",
"module": "uvicorn",
"args": ["main:app", "--reload"],
"console": "integratedTerminal"
}
pytest¶
{
"name": "pytest",
"type": "debugpy",
"request": "launch",
"module": "pytest",
"args": ["-v", "tests/"],
"console": "integratedTerminal"
}
JavaScript/Node.js Debugging¶
Node.js¶
{
"name": "Node.js",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/index.js"
}
TypeScript¶
{
"name": "TypeScript",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/index.ts",
"preLaunchTask": "tsc: build",
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
npm Script¶
{
"name": "npm start",
"type": "node",
"request": "launch",
"runtimeExecutable": "npm",
"runtimeArgs": ["start"]
}
Chrome/Edge¶
{
"name": "Chrome",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}/src"
}
Go Debugging¶
{
"name": "Go: Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${fileDirname}"
}
With Arguments¶
{
"name": "Go: With Args",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}",
"args": ["--config", "dev.yaml"]
}
Test¶
{
"name": "Go: Test",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}"
}
Rust Debugging¶
Requires CodeLLDB extension:
{
"name": "Rust: Debug",
"type": "lldb",
"request": "launch",
"program": "${workspaceFolder}/target/debug/${workspaceFolderBasename}",
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "cargo build"
}
Breakpoints¶
Setting Breakpoints¶
- Click left of line number
- F9 to toggle
- Right-click for conditional breakpoints
Breakpoint Types¶
| Type | Description |
|---|---|
| Standard | Pause at line |
| Conditional | Pause when condition is true |
| Logpoint | Log message without pausing |
| Hit count | Pause after N hits |
Conditional Breakpoint¶
Right-click > "Add Conditional Breakpoint":
Logpoint¶
Right-click > "Add Logpoint":
Debug Actions¶
| Key | Action |
|---|---|
| F5 | Start/Continue |
| Shift+F5 | Stop |
| Cmd+Shift+F5 | Restart |
| F10 | Step Over |
| F11 | Step Into |
| Shift+F11 | Step Out |
| F9 | Toggle Breakpoint |
Debug Panels¶
Variables¶
View local and global variables. Expand objects to inspect properties.
Watch¶
Add expressions to watch:
- Right-click variable > "Add to Watch"
- Click + in Watch panel
Call Stack¶
View execution path. Click to jump to frame.
Debug Console¶
Execute code in current context:
Environment Variables¶
In launch.json¶
{
"name": "With Env",
"type": "python",
"request": "launch",
"program": "${file}",
"env": {
"DEBUG": "true",
"DATABASE_URL": "postgres://localhost/dev"
}
}
From .env File¶
{
"name": "With .env",
"type": "python",
"request": "launch",
"program": "${file}",
"envFile": "${workspaceFolder}/.env"
}
Compound Configurations¶
Debug multiple targets together:
{
"version": "0.2.0",
"configurations": [
{
"name": "Server",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/server.py"
},
{
"name": "Client",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
}
],
"compounds": [
{
"name": "Full Stack",
"configurations": ["Server", "Client"]
}
]
}
Attach to Running Process¶
Python¶
{
"name": "Python: Attach",
"type": "debugpy",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
}
}
In your code:
Node.js¶
Start with --inspect:
Tasks Integration¶
Run task before debugging:
{
"name": "Debug with Build",
"type": "python",
"request": "launch",
"program": "${file}",
"preLaunchTask": "build"
}
Define task in .vscode/tasks.json:
Debug Settings¶
{
"debug.console.fontSize": 13,
"debug.internalConsoleOptions": "openOnSessionStart",
"debug.showBreakpointsInOverviewRuler": true,
"debug.toolBarLocation": "docked"
}
Troubleshooting¶
Debugger Not Starting¶
- Check debugger extension installed
- Verify launch.json syntax
- Check program path exists
Breakpoints Not Hit¶
- Verify source maps (JS/TS)
- Check code is being executed
- Try unconditional breakpoint first
Can't Attach¶
- Check port is correct
- Verify process is running
- Check firewall settings