Debug Python scripts with breakpoints, stepping, variable inspection, and stack navigation.
Quick Reference
# Start debugging
python scripts/debugger.py start script.py [args...]
# Breakpoints
python scripts/debugger.py break -f script.py -l 45 # Line breakpoint
python scripts/debugger.py break -f script.py -l 45 -c "x>10" # Conditional
python scripts/debugger.py break -e ValueError # Exception breakpoint
python scripts/debugger.py breakpoints # List all
Execution
python scripts/debugger.py continue # Run until next breakpoint python scripts/debugger.py step # Step into python scripts/debugger.py next # Step over python scripts/debugger.py finish # Run until return
Inspectionpython scripts/debugger.py locals # Local variables python scripts/debugger.py globals # Global variables python scripts/debugger.py eval "expression" python scripts/debugger.py inspect variable_name
Stackpython scripts/debugger.py stack # View call stack python scripts/debugger.py up # Move up stack python scripts/debugger.py down # Move down stack
Sessionpython scripts/debugger.py status # Check status python scripts/debugger.py quit # End session
## Debugging Methodology
Debug systematically, not randomly. Follow these principles:
1. **Form a hypothesis first** - Before setting breakpoints, have a theory about what's wrong
2. **Reproduce consistently** - Ensure you can trigger the bug reliably
3. **Read error messages carefully** - They often point directly to the problem
4. **Binary search for bugs** - Narrow down by halving the search space
5. **Verify assumptions** - Use `eval` to check values are what you expect
6. **Change one thing at a time** - Isolate variables to identify root cause
## Decision Framework
| Situation | Approach |
|-----------|----------|
| Script crashes with exception | `break -e ExceptionType` → `continue` → inspect `locals` and `stack` |
| Wrong output, unknown cause | Binary search: breakpoint at midpoint, check state, narrow down |
| Loop produces wrong result | `break -l <line> -c "i == <problem_iteration>"` |
| Function returns wrong value | Breakpoint at return, inspect all locals before return |
| Variable has unexpected value | Trace backwards: where was it last assigned? |
| Intermittent bug | `break -e "*"` to catch any exception |
## Python Bug Patterns
| Bug Pattern | Symptoms | How to Debug |
|-------------|----------|--------------|
| `None` propagation | `AttributeError: 'NoneType'` | `eval "var"` at each step to find where it became None |
| Mutable default args | Function "remembers" values | `eval "func.__defaults__"` |
| Off-by-one errors | Missing first/last item | `break -c "i == 0 or i == len(items)-1"` |
| Scope issues | `UnboundLocalError` | Compare `locals` vs `globals` |
| Type coercion | Unexpected concatenation | `eval "type(var)"` |
| Dict key errors | `KeyError` | `eval "key in dict"` before access |
| Mutating while iterating | Missing items | `eval "len(collection)"` each iteration |
## The Debugging Process
- REPRODUCE → Trigger the bug reliably
- HYPOTHESIZE → "I think X is wrong because Y"
- INSTRUMENT → Set strategic breakpoint(s)
- OBSERVE → Run to breakpoint, inspect state
- ANALYZE → Does evidence support hypothesis? YES → Fix it NO → New hypothesis, goto 2
- VERIFY → Run again to confirm fix
## Common Workflows
### Debugging Exceptions
```bash
python scripts/debugger.py start script.py
python scripts/debugger.py break -e ValueError # Or -e "*" for any
python scripts/debugger.py continue
# When exception occurs:
python scripts/debugger.py locals # What values caused this?
python scripts/debugger.py stack # How did we get here?
python scripts/debugger.py up # Check caller's context
Debugging Wrong Output
python scripts/debugger.py start script.py
python scripts/debugger.py break -f script.py -l <output_line>
python scripts/debugger.py continue
python scripts/debugger.py eval "output_var" # Already wrong?
# Binary search: set breakpoint at midpoint, repeat
Debugging Loops
python scripts/debugger.py break -f script.py -l <loop_line> -c "i == 5"
python scripts/debugger.py continue
python scripts/debugger.py locals # Check loop state
python scripts/debugger.py next # Step through iteration
Anti-Patterns (Avoid These)
- Random breakpoint placement - Think first, then place strategically
- Not reading error messages - Python errors are descriptive
- Changing code without understanding - Understand before fixing
- Assuming instead of verifying - Use
evalto check - Skipping reproduction - Can't verify fix without consistent repro
JSON Output Format
All commands return JSON:
{
"status": "paused",
"stop_reason": "line",
"location": {
"file": "/path/to/script.py",
"line": 45,
"function": "process_data",
"code": " result = calculate(item)"
},
"variables": {
"locals": {
"item": {"type": "dict", "value": "{'id': 1}"},
"result": {"type": "NoneType", "value": "None"}
}
}
}
Additional Resources
- Methodology & Best Practices - Detailed debugging methodology
- Command Reference - Complete command documentation
- Troubleshooting - Common issues and solutions
- Examples - Example debugging sessions