Debugging Strategies
Master systematic debugging to track down bugs efficiently across any stack
✨ The solution you've been looking for
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.
See It In Action
Interactive preview & real-world examples
AI Conversation Simulator
See how users interact with this skill
User Prompt
My web app is running slow in production but works fine locally. Help me debug this performance issue systematically.
Skill Processing
Analyzing request...
Agent Response
A structured debugging plan with profiling tools, performance measurement techniques, and step-by-step investigation process to identify the root cause
Quick Start (3 Steps)
Get up and running in minutes
Install
claude-code skill install debugging-strategies
claude-code skill install debugging-strategiesConfig
First Trigger
@debugging-strategies helpCommands
| Command | Description | Required Args |
|---|---|---|
| @debugging-strategies investigating-production-performance-issues | Track down performance bottlenecks affecting users in production using profiling and systematic analysis | None |
| @debugging-strategies debugging-intermittent-bugs | Apply proven strategies to catch elusive bugs that only appear sometimes or under specific conditions | None |
| @debugging-strategies memory-leak-investigation | Use scientific debugging methods to identify and resolve memory leaks across different programming languages | None |
Typical Use Cases
Investigating Production Performance Issues
Track down performance bottlenecks affecting users in production using profiling and systematic analysis
Debugging Intermittent Bugs
Apply proven strategies to catch elusive bugs that only appear sometimes or under specific conditions
Memory Leak Investigation
Use scientific debugging methods to identify and resolve memory leaks across different programming languages
Overview
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
1## Reproduction Checklist
2
31. **Can you reproduce it?**
4 - Always? Sometimes? Randomly?
5 - Specific conditions needed?
6 - Can others reproduce it?
7
82. **Create minimal reproduction**
9 - Simplify to smallest example
10 - Remove unrelated code
11 - Isolate the problem
12
133. **Document steps**
14 - Write down exact steps
15 - Note environment details
16 - Capture error messages
Phase 2: Gather Information
1## Information Collection
2
31. **Error Messages**
4 - Full stack trace
5 - Error codes
6 - Console/log output
7
82. **Environment**
9 - OS version
10 - Language/runtime version
11 - Dependencies versions
12 - Environment variables
13
143. **Recent Changes**
15 - Git history
16 - Deployment timeline
17 - Configuration changes
18
194. **Scope**
20 - Affects all users or specific ones?
21 - All browsers or specific ones?
22 - Production only or also dev?
Phase 3: Form Hypothesis
1## Hypothesis Formation
2
3Based on gathered info, ask:
4
51. **What changed?**
6 - Recent code changes
7 - Dependency updates
8 - Infrastructure changes
9
102. **What's different?**
11 - Working vs broken environment
12 - Working vs broken user
13 - Before vs after
14
153. **Where could this fail?**
16 - Input validation
17 - Business logic
18 - Data layer
19 - External services
Phase 4: Test & Verify
1## Testing Strategies
2
31. **Binary Search**
4 - Comment out half the code
5 - Narrow down problematic section
6 - Repeat until found
7
82. **Add Logging**
9 - Strategic console.log/print
10 - Track variable values
11 - Trace execution flow
12
133. **Isolate Components**
14 - Test each piece separately
15 - Mock dependencies
16 - Remove complexity
17
184. **Compare Working vs Broken**
19 - Diff configurations
20 - Diff environments
21 - Diff data
Debugging Tools
JavaScript/TypeScript Debugging
1// Chrome DevTools Debugger
2function processOrder(order: Order) {
3 debugger; // Execution pauses here
4
5 const total = calculateTotal(order);
6 console.log("Total:", total);
7
8 // Conditional breakpoint
9 if (order.items.length > 10) {
10 debugger; // Only breaks if condition true
11 }
12
13 return total;
14}
15
16// Console debugging techniques
17console.log("Value:", value); // Basic
18console.table(arrayOfObjects); // Table format
19console.time("operation");
20/* code */ console.timeEnd("operation"); // Timing
21console.trace(); // Stack trace
22console.assert(value > 0, "Value must be positive"); // Assertion
23
24// Performance profiling
25performance.mark("start-operation");
26// ... operation code
27performance.mark("end-operation");
28performance.measure("operation", "start-operation", "end-operation");
29console.log(performance.getEntriesByType("measure"));
VS Code Debugger Configuration:
1// .vscode/launch.json
2{
3 "version": "0.2.0",
4 "configurations": [
5 {
6 "type": "node",
7 "request": "launch",
8 "name": "Debug Program",
9 "program": "${workspaceFolder}/src/index.ts",
10 "preLaunchTask": "tsc: build - tsconfig.json",
11 "outFiles": ["${workspaceFolder}/dist/**/*.js"],
12 "skipFiles": ["<node_internals>/**"]
13 },
14 {
15 "type": "node",
16 "request": "launch",
17 "name": "Debug Tests",
18 "program": "${workspaceFolder}/node_modules/jest/bin/jest",
19 "args": ["--runInBand", "--no-cache"],
20 "console": "integratedTerminal"
21 }
22 ]
23}
Python Debugging
1# Built-in debugger (pdb)
2import pdb
3
4def calculate_total(items):
5 total = 0
6 pdb.set_trace() # Debugger starts here
7
8 for item in items:
9 total += item.price * item.quantity
10
11 return total
12
13# Breakpoint (Python 3.7+)
14def process_order(order):
15 breakpoint() # More convenient than pdb.set_trace()
16 # ... code
17
18# Post-mortem debugging
19try:
20 risky_operation()
21except Exception:
22 import pdb
23 pdb.post_mortem() # Debug at exception point
24
25# IPython debugging (ipdb)
26from ipdb import set_trace
27set_trace() # Better interface than pdb
28
29# Logging for debugging
30import logging
31logging.basicConfig(level=logging.DEBUG)
32logger = logging.getLogger(__name__)
33
34def fetch_user(user_id):
35 logger.debug(f'Fetching user: {user_id}')
36 user = db.query(User).get(user_id)
37 logger.debug(f'Found user: {user}')
38 return user
39
40# Profile performance
41import cProfile
42import pstats
43
44cProfile.run('slow_function()', 'profile_stats')
45stats = pstats.Stats('profile_stats')
46stats.sort_stats('cumulative')
47stats.print_stats(10) # Top 10 slowest
Go Debugging
1// Delve debugger
2// Install: go install github.com/go-delve/delve/cmd/dlv@latest
3// Run: dlv debug main.go
4
5import (
6 "fmt"
7 "runtime"
8 "runtime/debug"
9)
10
11// Print stack trace
12func debugStack() {
13 debug.PrintStack()
14}
15
16// Panic recovery with debugging
17func processRequest() {
18 defer func() {
19 if r := recover(); r != nil {
20 fmt.Println("Panic:", r)
21 debug.PrintStack()
22 }
23 }()
24
25 // ... code that might panic
26}
27
28// Memory profiling
29import _ "net/http/pprof"
30// Visit http://localhost:6060/debug/pprof/
31
32// CPU profiling
33import (
34 "os"
35 "runtime/pprof"
36)
37
38f, _ := os.Create("cpu.prof")
39pprof.StartCPUProfile(f)
40defer pprof.StopCPUProfile()
41// ... code to profile
Advanced Debugging Techniques
Technique 1: Binary Search Debugging
1# Git bisect for finding regression
2git bisect start
3git bisect bad # Current commit is bad
4git bisect good v1.0.0 # v1.0.0 was good
5
6# Git checks out middle commit
7# Test it, then:
8git bisect good # if it works
9git bisect bad # if it's broken
10
11# Continue until bug found
12git bisect reset # when done
Technique 2: Differential Debugging
Compare working vs broken:
1## What's Different?
2
3| Aspect | Working | Broken |
4| ------------ | ----------- | -------------- |
5| Environment | Development | Production |
6| Node version | 18.16.0 | 18.15.0 |
7| Data | Empty DB | 1M records |
8| User | Admin | Regular user |
9| Browser | Chrome | Safari |
10| Time | During day | After midnight |
11
12Hypothesis: Time-based issue? Check timezone handling.
Technique 3: Trace Debugging
1// Function call tracing
2function trace(
3 target: any,
4 propertyKey: string,
5 descriptor: PropertyDescriptor,
6) {
7 const originalMethod = descriptor.value;
8
9 descriptor.value = function (...args: any[]) {
10 console.log(`Calling ${propertyKey} with args:`, args);
11 const result = originalMethod.apply(this, args);
12 console.log(`${propertyKey} returned:`, result);
13 return result;
14 };
15
16 return descriptor;
17}
18
19class OrderService {
20 @trace
21 calculateTotal(items: Item[]): number {
22 return items.reduce((sum, item) => sum + item.price, 0);
23 }
24}
Technique 4: Memory Leak Detection
1// Chrome DevTools Memory Profiler
2// 1. Take heap snapshot
3// 2. Perform action
4// 3. Take another snapshot
5// 4. Compare snapshots
6
7// Node.js memory debugging
8if (process.memoryUsage().heapUsed > 500 * 1024 * 1024) {
9 console.warn("High memory usage:", process.memoryUsage());
10
11 // Generate heap dump
12 require("v8").writeHeapSnapshot();
13}
14
15// Find memory leaks in tests
16let beforeMemory: number;
17
18beforeEach(() => {
19 beforeMemory = process.memoryUsage().heapUsed;
20});
21
22afterEach(() => {
23 const afterMemory = process.memoryUsage().heapUsed;
24 const diff = afterMemory - beforeMemory;
25
26 if (diff > 10 * 1024 * 1024) {
27 // 10MB threshold
28 console.warn(`Possible memory leak: ${diff / 1024 / 1024}MB`);
29 }
30});
Debugging Patterns by Issue Type
Pattern 1: Intermittent Bugs
1## Strategies for Flaky Bugs
2
31. **Add extensive logging**
4 - Log timing information
5 - Log all state transitions
6 - Log external interactions
7
82. **Look for race conditions**
9 - Concurrent access to shared state
10 - Async operations completing out of order
11 - Missing synchronization
12
133. **Check timing dependencies**
14 - setTimeout/setInterval
15 - Promise resolution order
16 - Animation frame timing
17
184. **Stress test**
19 - Run many times
20 - Vary timing
21 - Simulate load
Pattern 2: Performance Issues
1## Performance Debugging
2
31. **Profile first**
4 - Don't optimize blindly
5 - Measure before and after
6 - Find bottlenecks
7
82. **Common culprits**
9 - N+1 queries
10 - Unnecessary re-renders
11 - Large data processing
12 - Synchronous I/O
13
143. **Tools**
15 - Browser DevTools Performance tab
16 - Lighthouse
17 - Python: cProfile, line_profiler
18 - Node: clinic.js, 0x
Pattern 3: Production Bugs
1## Production Debugging
2
31. **Gather evidence**
4 - Error tracking (Sentry, Bugsnag)
5 - Application logs
6 - User reports
7 - Metrics/monitoring
8
92. **Reproduce locally**
10 - Use production data (anonymized)
11 - Match environment
12 - Follow exact steps
13
143. **Safe investigation**
15 - Don't change production
16 - Use feature flags
17 - Add monitoring/logging
18 - Test fixes in staging
Best Practices
- Reproduce First: Can’t fix what you can’t reproduce
- Isolate the Problem: Remove complexity until minimal case
- Read Error Messages: They’re usually helpful
- Check Recent Changes: Most bugs are recent
- Use Version Control: Git bisect, blame, history
- Take Breaks: Fresh eyes see better
- Document Findings: Help future you
- 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
1## When Stuck, Check:
2
3- [ ] Spelling errors (typos in variable names)
4- [ ] Case sensitivity (fileName vs filename)
5- [ ] Null/undefined values
6- [ ] Array index off-by-one
7- [ ] Async timing (race conditions)
8- [ ] Scope issues (closure, hoisting)
9- [ ] Type mismatches
10- [ ] Missing dependencies
11- [ ] Environment variables
12- [ ] File paths (absolute vs relative)
13- [ ] Cache issues (clear cache)
14- [ ] 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
What Users Are Saying
Real feedback from the community
Environment Matrix
Dependencies
Framework Support
Context Window
Security & Privacy
Information
- Author
- wshobson
- Updated
- 2026-01-30
- Category
- debugging
Related Skills
Debugging Strategies
Master systematic debugging techniques, profiling tools, and root cause analysis to efficiently …
View Details →Error Resolver
Systematic error diagnosis and resolution using first-principle analysis. Use when encountering any …
View Details →Error Resolver
Systematic error diagnosis and resolution using first-principle analysis. Use when encountering any …
View Details →