git:20251024.ed129a8 to git:20260119.5684887

76 added, 67 removed. Audit A to A.

---
name: debugging-strategies
description: Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently track down bugs across any codebase or technology stack. Use when investigating bugs, performance issues, or unexpected behavior.
---
# Debugging Strategies
Transform debugging from frustrating guesswork into systematic problem-solving with proven strategies, powerful tools, and methodical approaches.
## When to Use This Skill
- Tracking down elusive bugs
- Investigating performance issues
- Understanding unfamiliar codebases
- Debugging production issues
- Analyzing crash dumps and stack traces
- Profiling application performance
- Investigating memory leaks
- Debugging distributed systems
## Core Principles
### 1. The Scientific Method
**1. Observe**: What's the actual behavior?
**2. Hypothesize**: What could be causing it?
**3. Experiment**: Test your hypothesis
**4. Analyze**: Did it prove/disprove your theory?
**5. Repeat**: Until you find the root cause
### 2. Debugging Mindset
**Don't Assume:**
+
- "It can't be X" - Yes it can
- "I didn't change Y" - Check anyway
- "It works on my machine" - Find out why
**Do:**
+
- Reproduce consistently
- Isolate the problem
- Keep detailed notes
- Question everything
- Take breaks when stuck
### 3. Rubber Duck Debugging
Explain your code and problem out loud (to a rubber duck, colleague, or yourself). Often reveals the issue.
## Systematic Debugging Process
### Phase 1: Reproduce
```markdown
## Reproduction Checklist
1. **Can you reproduce it?**
- Always? Sometimes? Randomly?
- Specific conditions needed?
- Can others reproduce it?
2. **Create minimal reproduction**
- Simplify to smallest example
- Remove unrelated code
- Isolate the problem
3. **Document steps**
- Write down exact steps
- Note environment details
- Capture error messages
```
### Phase 2: Gather Information
```markdown
## Information Collection
1. **Error Messages**
- Full stack trace
- Error codes
- Console/log output
2. **Environment**
- OS version
- Language/runtime version
- Dependencies versions
- Environment variables
3. **Recent Changes**
- Git history
- Deployment timeline
- Configuration changes
4. **Scope**
- Affects all users or specific ones?
- All browsers or specific ones?
- Production only or also dev?
```
### Phase 3: Form Hypothesis
```markdown
## Hypothesis Formation
Based on gathered info, ask:
1. **What changed?**
- Recent code changes
- Dependency updates
- Infrastructure changes
2. **What's different?**
- Working vs broken environment
- Working vs broken user
- Before vs after
3. **Where could this fail?**
- Input validation
- Business logic
- Data layer
- External services
```
### Phase 4: Test & Verify
```markdown
## Testing Strategies
1. **Binary Search**
- Comment out half the code
- Narrow down problematic section
- Repeat until found
2. **Add Logging**
- Strategic console.log/print
- Track variable values
- Trace execution flow
3. **Isolate Components**
- Test each piece separately
- Mock dependencies
- Remove complexity
4. **Compare Working vs Broken**
- Diff configurations
- Diff environments
- Diff data
```
## Debugging Tools
### JavaScript/TypeScript Debugging
```typescript
// Chrome DevTools Debugger
function processOrder(order: Order) {
- debugger; // Execution pauses here
+ debugger; // Execution pauses here
- const total = calculateTotal(order);
- console.log('Total:', total);
+ const total = calculateTotal(order);
+ console.log("Total:", total);
- // Conditional breakpoint
- if (order.items.length > 10) {
- debugger; // Only breaks if condition true
- }
+ // Conditional breakpoint
+ if (order.items.length > 10) {
+ debugger; // Only breaks if condition true
+ }
- return total;
+ return total;
}
// Console debugging techniques
- console.log('Value:', value); // Basic
- console.table(arrayOfObjects); // Table format
- console.time('operation'); /* code */ console.timeEnd('operation'); // Timing
- console.trace(); // Stack trace
- console.assert(value > 0, 'Value must be positive'); // Assertion
+ console.log("Value:", value); // Basic
+ console.table(arrayOfObjects); // Table format
+ console.time("operation");
+ /* code */ console.timeEnd("operation"); // Timing
+ console.trace(); // Stack trace
+ console.assert(value > 0, "Value must be positive"); // Assertion
// Performance profiling
- performance.mark('start-operation');
+ performance.mark("start-operation");
// ... operation code
- performance.mark('end-operation');
- performance.measure('operation', 'start-operation', 'end-operation');
- console.log(performance.getEntriesByType('measure'));
+ performance.mark("end-operation");
+ performance.measure("operation", "start-operation", "end-operation");
+ console.log(performance.getEntriesByType("measure"));
```
**VS Code Debugger Configuration:**
+
```json
// .vscode/launch.json
{
- "version": "0.2.0",
- "configurations": [
- {
- "type": "node",
- "request": "launch",
- "name": "Debug Program",
- "program": "${workspaceFolder}/src/index.ts",
- "preLaunchTask": "tsc: build - tsconfig.json",
- "outFiles": ["${workspaceFolder}/dist/**/*.js"],
- "skipFiles": ["<node_internals>/**"]
- },
- {
- "type": "node",
- "request": "launch",
- "name": "Debug Tests",
- "program": "${workspaceFolder}/node_modules/jest/bin/jest",
- "args": ["--runInBand", "--no-cache"],
- "console": "integratedTerminal"
- }
- ]
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Debug Program",
+ "program": "${workspaceFolder}/src/index.ts",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "outFiles": ["${workspaceFolder}/dist/**/*.js"],
+ "skipFiles": ["<node_internals>/**"]
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Debug Tests",
+ "program": "${workspaceFolder}/node_modules/jest/bin/jest",
+ "args": ["--runInBand", "--no-cache"],
+ "console": "integratedTerminal"
+ }
+ ]
}
```
### Python Debugging
```python
# Built-in debugger (pdb)
import pdb
def calculate_total(items):
total = 0
pdb.set_trace() # Debugger starts here
for item in items:
total += item.price * item.quantity
return total
# Breakpoint (Python 3.7+)
def process_order(order):
breakpoint() # More convenient than pdb.set_trace()
# ... code
# Post-mortem debugging
try:
risky_operation()
except Exception:
import pdb
pdb.post_mortem() # Debug at exception point
# IPython debugging (ipdb)
from ipdb import set_trace
set_trace() # Better interface than pdb
# Logging for debugging
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def fetch_user(user_id):
logger.debug(f'Fetching user: {user_id}')
user = db.query(User).get(user_id)
logger.debug(f'Found user: {user}')
return user
# Profile performance
import cProfile
import pstats
cProfile.run('slow_function()', 'profile_stats')
stats = pstats.Stats('profile_stats')
stats.sort_stats('cumulative')
stats.print_stats(10) # Top 10 slowest
```
### Go Debugging
```go
// Delve debugger
// Install: go install github.com/go-delve/delve/cmd/dlv@latest
// Run: dlv debug main.go
import (
"fmt"
"runtime"
"runtime/debug"
)
// Print stack trace
func debugStack() {
debug.PrintStack()
}
// Panic recovery with debugging
func processRequest() {
defer func() {
if r := recover(); r != nil {
fmt.Println("Panic:", r)
debug.PrintStack()
}
}()
// ... code that might panic
}
// Memory profiling
import _ "net/http/pprof"
// Visit http://localhost:6060/debug/pprof/
// CPU profiling
import (
"os"
"runtime/pprof"
)
f, _ := os.Create("cpu.prof")
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
// ... code to profile
```
## Advanced Debugging Techniques
### Technique 1: Binary Search Debugging
```bash
# Git bisect for finding regression
git bisect start
git bisect bad # Current commit is bad
git bisect good v1.0.0 # v1.0.0 was good
# Git checks out middle commit
# Test it, then:
git bisect good # if it works
git bisect bad # if it's broken
# Continue until bug found
git bisect reset # when done
```
### Technique 2: Differential Debugging
Compare working vs broken:
```markdown
## What's Different?
- | Aspect | Working | Broken |
- |--------------|-----------------|-----------------|
- | Environment | Development | Production |
- | Node version | 18.16.0 | 18.15.0 |
- | Data | Empty DB | 1M records |
- | User | Admin | Regular user |
- | Browser | Chrome | Safari |
- | Time | During day | After midnight |
+ | Aspect | Working | Broken |
+ | ------------ | ----------- | -------------- |
+ | Environment | Development | Production |
+ | Node version | 18.16.0 | 18.15.0 |
+ | Data | Empty DB | 1M records |
+ | User | Admin | Regular user |
+ | Browser | Chrome | Safari |
+ | Time | During day | After midnight |
Hypothesis: Time-based issue? Check timezone handling.
```
### Technique 3: Trace Debugging
```typescript
// Function call tracing
- function trace(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
- const originalMethod = descriptor.value;
+ function trace(
+ target: any,
+ propertyKey: string,
+ descriptor: PropertyDescriptor,
+ ) {
+ const originalMethod = descriptor.value;
- descriptor.value = function(...args: any[]) {
- console.log(`Calling ${propertyKey} with args:`, args);
- const result = originalMethod.apply(this, args);
- console.log(`${propertyKey} returned:`, result);
- return result;
- };
+ descriptor.value = function (...args: any[]) {
+ console.log(`Calling ${propertyKey} with args:`, args);
+ const result = originalMethod.apply(this, args);
+ console.log(`${propertyKey} returned:`, result);
+ return result;
+ };
- return descriptor;
+ return descriptor;
}
class OrderService {
- @trace
- calculateTotal(items: Item[]): number {
- return items.reduce((sum, item) => sum + item.price, 0);
- }
+ @trace
+ calculateTotal(items: Item[]): number {
+ return items.reduce((sum, item) => sum + item.price, 0);
+ }
}
```
### Technique 4: Memory Leak Detection
```typescript
// Chrome DevTools Memory Profiler
// 1. Take heap snapshot
// 2. Perform action
// 3. Take another snapshot
// 4. Compare snapshots
// Node.js memory debugging
if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {
- console.warn('High memory usage:', process.memoryUsage());
+ console.warn("High memory usage:", process.memoryUsage());
- // Generate heap dump
- require('v8').writeHeapSnapshot();
+ // Generate heap dump
+ require("v8").writeHeapSnapshot();
}
// Find memory leaks in tests
let beforeMemory: number;
beforeEach(() => {
- beforeMemory = process.memoryUsage().heapUsed;
+ beforeMemory = process.memoryUsage().heapUsed;
});
afterEach(() => {
- const afterMemory = process.memoryUsage().heapUsed;
- const diff = afterMemory - beforeMemory;
+ const afterMemory = process.memoryUsage().heapUsed;
+ const diff = afterMemory - beforeMemory;
- if (diff > 10 * 1024 * 1024) { // 10MB threshold
- console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);
- }
+ if (diff > 10 * 1024 * 1024) {
+ // 10MB threshold
+ console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);
+ }
});
```
## Debugging Patterns by Issue Type
### Pattern 1: Intermittent Bugs
```markdown
## Strategies for Flaky Bugs
1. **Add extensive logging**
- Log timing information
- Log all state transitions
- Log external interactions
2. **Look for race conditions**
- Concurrent access to shared state
- Async operations completing out of order
- Missing synchronization
3. **Check timing dependencies**
- setTimeout/setInterval
- Promise resolution order
- Animation frame timing
4. **Stress test**
- Run many times
- Vary timing
- Simulate load
```
### Pattern 2: Performance Issues
```markdown
## Performance Debugging
1. **Profile first**
- Don't optimize blindly
- Measure before and after
- Find bottlenecks
2. **Common culprits**
- N+1 queries
- Unnecessary re-renders
- Large data processing
- Synchronous I/O
3. **Tools**
- Browser DevTools Performance tab
- Lighthouse
- Python: cProfile, line_profiler
- Node: clinic.js, 0x
```
### Pattern 3: Production Bugs
```markdown
## Production Debugging
1. **Gather evidence**
- Error tracking (Sentry, Bugsnag)
- Application logs
- User reports
- Metrics/monitoring
2. **Reproduce locally**
- Use production data (anonymized)
- Match environment
- Follow exact steps
3. **Safe investigation**
- Don't change production
- Use feature flags
- Add monitoring/logging
- Test fixes in staging
```
## Best Practices
1. **Reproduce First**: Can't fix what you can't reproduce
2. **Isolate the Problem**: Remove complexity until minimal case
3. **Read Error Messages**: They're usually helpful
4. **Check Recent Changes**: Most bugs are recent
5. **Use Version Control**: Git bisect, blame, history
6. **Take Breaks**: Fresh eyes see better
7. **Document Findings**: Help future you
8. **Fix Root Cause**: Not just symptoms
## Common Debugging Mistakes
- **Making Multiple Changes**: Change one thing at a time
- **Not Reading Error Messages**: Read the full stack trace
- **Assuming It's Complex**: Often it's simple
- **Debug Logging in Prod**: Remove before shipping
- **Not Using Debugger**: console.log isn't always best
- **Giving Up Too Soon**: Persistence pays off
- **Not Testing the Fix**: Verify it actually works
## Quick Debugging Checklist
```markdown
## When Stuck, Check:
- [ ] Spelling errors (typos in variable names)
- [ ] Case sensitivity (fileName vs filename)
- [ ] Null/undefined values
- [ ] Array index off-by-one
- [ ] Async timing (race conditions)
- [ ] Scope issues (closure, hoisting)
- [ ] Type mismatches
- [ ] Missing dependencies
- [ ] Environment variables
- [ ] File paths (absolute vs relative)
- [ ] Cache issues (clear cache)
- [ ] Stale data (refresh database)
```
## Resources
- **references/debugging-tools-guide.md**: Comprehensive tool documentation
- **references/performance-profiling.md**: Performance debugging guide
- **references/production-debugging.md**: Debugging live systems
- **assets/debugging-checklist.md**: Quick reference checklist
- **assets/common-bugs.md**: Common bug patterns
- **scripts/debug-helper.ts**: Debugging utility functions