# 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 1. **Set breakpoint**: `db` 2. **Start debugger**: `dc` 3. **Step through**: `di` (into), `do` (over) 4. **Inspect**: `du` (toggle UI) 5. **Stop**: `dt` ## Key Bindings ### Breakpoints | Key | Action | |-----|--------| | `db` | Toggle breakpoint | | `dB` | Conditional breakpoint | | `dl` | Log point (print without stopping) | ### Execution Control | Key | Action | |-----|--------| | `dc` | Continue (or start) | | `di` | Step into | | `do` | Step over | | `dO` | Step out | | `dC` | Run to cursor | | `dp` | Pause | | `dt` | Terminate | | `dr` | Toggle REPL | ### UI & Inspection | Key | Action | |-----|--------| | `du` | Toggle DAP UI | | `de` | Evaluate expression | | `dw` | Add to watch | | `ds` | View scopes | ## DAP UI Layout When you press `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 `` ### 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: - `dw` to add - Updates as you step ## Debugging by Language ### TypeScript/JavaScript #### Prerequisites ```bash npm install -g @vscode/js-debug ``` #### Debug Current File 1. Open your `.ts` or `.js` file 2. `db` - Set breakpoint 3. `dc` - Start debugging 4. Select "Node.js: Launch" or similar #### Debug Tests ``` td Debug test at cursor ``` This automatically sets up the test runner with debugging. #### launch.json Example ```json { "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 ```bash pip install debugpy ``` #### Debug Current File 1. Open your `.py` file 2. `db` - Set breakpoint 3. `dc` - Start debugging 4. Select "Python: Current File" #### Debug Tests ``` td Debug test at cursor ``` #### launch.json Example ```json { "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 ```bash go install github.com/go-delve/delve/cmd/dlv@latest ``` #### Debug Current File 1. Open your `.go` file 2. `db` - Set breakpoint 3. `dc` - Start debugging 4. Select "Go: Debug Package" #### Debug Tests ``` td Debug test at cursor ``` Works with table-driven tests too! #### launch.json Example ```json { "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: ``` db Toggle on current line ``` ### Conditional Breakpoint Only stops when condition is true: ``` dB Prompts for condition ``` Example conditions: - `x > 10` - `user.name == "test"` - `items.length > 0` ### Log Point Prints message without stopping: ``` 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): ``` dB Enter: hitCount > 5 ``` ## Debugging Strategies ### Step Through Unknown Code 1. Set breakpoint at entry point 2. `dc` - Start 3. `di` - Step into functions to understand them 4. `do` - Step over when you understand 5. `dO` - Step out when done with function ### Find Where Value Changes 1. Set breakpoint where value is used 2. `dw` - Add variable to watch 3. Step through, watching for changes 4. Or use conditional breakpoint: `x != expectedValue` ### Debug Loops 1. Set conditional breakpoint: `i == problematicIndex` 2. Or use hit count: stop after N iterations 3. Check variables at specific iteration ### Remote Debugging For processes running elsewhere: 1. Start process with debug flag 2. Use "attach" configuration 3. Connect to debug port ## Common Workflows ### Finding a Bug 1. Reproduce the bug path 2. Set breakpoint before bug occurs 3. `dc` - Start debugging 4. Step through, inspecting variables 5. Find where actual != expected 6. Fix and re-test ### Understanding New Code 1. Set breakpoint at function entry 2. `dc` - Start with a test case 3. `di` - Step into each function 4. Use watch to track key variables 5. Build mental model of flow ### Performance Investigation Use log points to trace without stopping: 1. `dl` at key points 2. Log timing: `Start: {Date.now()}` 3. Run normally 4. Check console for timing ## Tips ### Quick Variable Inspection Hover over variable with cursor - shows value in float. ### REPL Usage `dr` opens REPL where you can: - Evaluate expressions - Call functions - Modify variables (sometimes) ### Restart Debugging If you need to start over: ``` dt Terminate dc Start again ``` ### Breakpoint Persistence Breakpoints are saved per session. They'll be there when you reopen the file. ## Troubleshooting ### Debugger Won't Start 1. Check adapter is installed 2. `:DapShowLog` for errors 3. Verify launch configuration ### Breakpoints Not Hit 1. Verify file paths match 2. Check source maps (TypeScript) 3. Ensure code is actually executed ### Variables Not Showing 1. Might be optimized out (Go) 2. Check scope (local vs global) 3. Try evaluating directly: `de` ### Source Maps Issues (TypeScript) 1. Ensure `sourceMaps: true` in launch.json 2. Check tsconfig has `sourceMap: true` 3. Verify outFiles pattern matches ### Slow Debugging 1. Reduce number of breakpoints 2. Use conditional breakpoints 3. Disable logging breakpoints when not needed