Skip to content
Back to skills

324 Debugging Guide 823bbbef

ASecurity

Systematic debugging strategies, tools, and techniques for complex runtime and compilation errors.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentpythongojavabashexpressdebugginggitperformancedocumentation

Works with

  • cli

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 324-debugging_guide_823bbbef --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 324 Debugging Guide 823bbbef?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 324 Debugging Guide 823bbbef
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-324-debugging-guide-823bbbef/badge)](https://www.skillsdirectory.com/skills/tools-only-324-debugging-guide-823bbbef)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Debugging Guide

Systematic debugging strategies, tools, and techniques for complex runtime and compilation errors.

## Table of Contents

1. [Systematic Debugging Process](#systematic-debugging-process)
2. [Python Debugging Tools](#python-debugging-tools)
3. [Java Debugging Tools](#java-debugging-tools)
4. [Common Debugging Techniques](#common-debugging-techniques)
5. [Advanced Strategies](#advanced-strategies)

---

## Systematic Debugging Process

Follow this methodical approach when errors are not immediately obvious:

### 1. Reproduce the Error

**Goal:** Ensure error happens consistently

```
Steps:
1. Document exact steps to trigger error
2. Note any variations (works sometimes, fails sometimes)
3. Identify minimum inputs required to trigger error
4. Test if error occurs in different environments
```

**Questions to ask:**
- Does the error happen every time?
- Does it only happen with specific input?
- Did it work before? What changed?
- Can you reproduce it in a simpler test case?

### 2. Isolate the Problem

**Goal:** Narrow down to the smallest failing code segment

```
Binary search approach:
1. Comment out half the code
2. Does error still occur?
   - YES: Problem is in remaining half
   - NO: Problem is in commented half
3. Repeat until you find the exact line(s)
```

**Techniques:**
- Create minimal reproduction (remove everything unrelated)
- Test individual functions in isolation
- Use print statements to identify last successful operation

### 3. Understand the Error

**Goal:** Comprehend what the error message tells you

```
Read the error message carefully:
1. Error type (AttributeError, NullPointerException, etc.)
2. Line number where error occurred
3. Stack trace (call chain leading to error)
4. Expected vs actual values (if provided)
```

**Don't skip the stack trace!** It shows:
- Where error originated
- How execution got there
- Whether error is in your code or library code

### 4. Form Hypothesis

**Goal:** Develop theory about root cause

```
Based on error and context, hypothesize:
1. What might have caused this?
2. Why would this value be null/wrong?
3. What assumptions might be violated?
4. What recent changes could relate?
```

### 5. Test Hypothesis

**Goal:** Verify or disprove your theory

```
Add logging/debugging:
1. Print variable values before error
2. Add assertions to check assumptions
3. Use debugger to inspect state
4. Test edge cases
```

### 6. Fix and Verify

**Goal:** Apply fix and confirm it solves the problem

```
After fixing:
1. Run the code that previously failed
2. Test edge cases
3. Run related tests
4. Verify no new issues introduced
```

---

## Python Debugging Tools

### Built-in pdb Debugger

**Basic Usage:**

```python
import pdb

def calculate(x, y):
    result = x + y
    pdb.set_trace()  # Debugger stops here
    return result

calculate(5, 10)
```

**Common pdb Commands:**

```
n (next)       - Execute next line
s (step)       - Step into function
c (continue)   - Continue execution
l (list)       - Show source code around current line
p var          - Print variable value
pp var         - Pretty-print variable
w (where)      - Show stack trace
q (quit)       - Quit debugger
h (help)       - Show help
```

**Post-mortem Debugging:**

```python
import pdb

try:
    # Code that might fail
    result = risky_operation()
except Exception:
    pdb.post_mortem()  # Start debugger at exception point
```

### breakpoint() (Python 3.7+)

Simpler than import pdb:

```python
def process_data(items):
    total = 0
    for item in items:
        breakpoint()  # Debugger starts here
        total += item['value']
    return total
```

### Logging

**Strategic Logging:**

```python
import logging

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')

def process_user(user_id):
    logging.debug(f"Processing user {user_id}")
    user = get_user(user_id)
    logging.debug(f"Retrieved user: {user}")

    if user is None:
        logging.error(f"User {user_id} not found")
        return None

    logging.info(f"Processing user {user.name}")
    return user
```

### Python Traceback Module

**Get detailed traceback info:**

```python
import traceback
import sys

try:
    risky_operation()
except Exception as e:
    # Print full traceback
    traceback.print_exc()

    # Get traceback as string
    tb_str = ''.join(traceback.format_exception(*sys.exc_info()))
    print(tb_str)

    # Get traceback details
    tb_lines = traceback.format_tb(sys.exc_info()[2])
    for line in tb_lines:
        print(line)
```

### iPython/Jupyter Debugging

```python
# In Jupyter/iPython, automatically start debugger on exception
%pdb on

# Run code - debugger starts if exception occurs
def buggy_function():
    x = None
    return x.upper()  # AttributeError - debugger starts

buggy_function()
```

---

## Java Debugging Tools

### Using jdb (Command-Line Debugger)

**Start debugging:**

```bash
# Compile with debug info
javac -g MyClass.java

# Run with jdb
jdb MyClass

# Common jdb commands:
stop at MyClass:15     # Set breakpoint at line 15
stop in MyClass.myMethod  # Set breakpoint at method
run                    # Start execution
step                   # Step into next line
next                   # Execute next line (don't step into)
cont                   # Continue execution
print variable         # Print variable value
locals                 # List all local variables
where                  # Show stack trace
quit                   # Exit debugger
```

### IDE Debugging (IntelliJ/Eclipse)

**IntelliJ IDEA:**
1. Click left margin to set breakpoint
2. Click "Debug" button (or Shift+F9)
3. When breakpoint hits:
   - F8: Step over
   - F7: Step into
   - Shift+F8: Step out
   - F9: Resume
4. Hover over variables to see values
5. Use "Evaluate Expression" (Alt+F8) to test code

**Eclipse:**
1. Double-click left margin to set breakpoint
2. Right-click → Debug As → Java Application
3. When breakpoint hits:
   - F6: Step over
   - F5: Step into
   - F7: Step out
   - F8: Resume
4. Variables view shows current values
5. Use "Display" to evaluate expressions

### Logging with java.util.logging

```java
import java.util.logging.*;

public class MyClass {
    private static final Logger logger = Logger.getLogger(MyClass.class.getName());

    public void processUser(int userId) {
        logger.info("Processing user " + userId);

        User user = getUser(userId);
        logger.fine("Retrieved user: " + user);

        if (user == null) {
            logger.severe("User " + userId + " not found!");
            return;
        }

        logger.info("Processing user " + user.getName());
    }
}
```

### Logging with SLF4J/Logback (Recommended)

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {
    private static final Logger log = LoggerFactory.getLogger(MyClass.class);

    public void processOrder(int orderId) {
        log.debug("Processing order {}", orderId);

        Order order = getOrder(orderId);
        log.trace("Order details: {}", order);

        if (order == null) {
            log.error("Order {} not found!", orderId);
            return;
        }

        log.info("Order {} processed successfully", orderId);
    }
}
```

### Stack Trace Analysis

```java
try {
    riskyOperation();
} catch (Exception e) {
    // Print stack trace to stderr
    e.printStackTrace();

    // Get stack trace as string
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    String stackTrace = sw.toString();
    System.out.println(stackTrace);

    // Analyze stack trace elements
    for (StackTraceElement element : e.getStackTrace()) {
        System.out.println("Class: " + element.getClassName());
        System.out.println("Method: " + element.getMethodName());
        System.out.println("Line: " + element.getLineNumber());
    }
}
```

---

## Common Debugging Techniques

### 1. Print Debugging (Quickest but not always best)

**Python:**
```python
def calculate_total(items):
    total = 0
    print(f"DEBUG: Processing {len(items)} items")  # Debug print

    for item in items:
        print(f"DEBUG: Item = {item}, Current total = {total}")  # Debug print
        total += item['price']

    print(f"DEBUG: Final total = {total}")  # Debug print
    return total
```

**Java:**
```java
public int calculateTotal(List<Item> items) {
    int total = 0;
    System.out.println("DEBUG: Processing " + items.size() + " items");

    for (Item item : items) {
        System.out.println("DEBUG: Item = " + item + ", Current total = " + total);
        total += item.getPrice();
    }

    System.out.println("DEBUG: Final total = " + total);
    return total;
}
```

**Pros:**
- Quick and easy
- Works anywhere

**Cons:**
- Clutters code
- Easy to forget to remove
- Can affect performance

**Best practice:** Use logging instead of print

### 2. Assertion Debugging

**Python:**
```python
def divide(a, b):
    assert b != 0, "Divisor must not be zero"
    assert isinstance(a, (int, float)), "a must be numeric"
    assert isinstance(b, (int, float)), "b must be numeric"

    return a / b
```

**Java:**
```java
public double divide(double a, double b) {
    assert b != 0 : "Divisor must not be zero";
    return a / b;
}

// Run with: java -ea MyClass (enable assertions)
```

**When to use:**
- Verify assumptions during development
- Check preconditions/postconditions
- Validate internal invariants

### 3. Binary Search Debugging

When code suddenly stops working:

```
1. Identify last known good state (e.g., git commit)
2. Identify first known bad state (current code)
3. Test midpoint:
   git checkout <midpoint-commit>
   Test if bug exists
4. If bug exists: Search between last-good and midpoint
   If bug doesn't exist: Search between midpoint and current
5. Repeat until you find the exact commit that introduced bug
```

**Git bisect automates this:**
```bash
git bisect start
git bisect bad              # Current commit is bad
git bisect good <commit>    # This commit was good
# Git checks out midpoint
# Test and mark as good or bad:
git bisect good  # or git bisect bad
# Repeat until git identifies the problematic commit
git bisect reset  # Return to original state
```

### 4. Rubber Duck Debugging

Explain the code line-by-line to an inanimate object (rubber duck).

**Process:**
1. Start from beginning of function
2. Explain what each line does
3. Explain what you expect to happen
4. Explain what actually happens

**Why it works:**
- Forces you to slow down
- Makes you question assumptions
- Often reveals logic errors

---

## Advanced Strategies

### Debugging Concurrent Code

**Python threading issues:**

```python
import threading
import logging

# Enable thread name in logging
logging.basicConfig(
    format='%(threadName)s - %(message)s',
    level=logging.DEBUG
)

def worker(name, counter):
    logging.debug(f"Worker {name} starting, counter={counter}")
    # ... do work ...
    logging.debug(f"Worker {name} finished")

# Create threads
threads = []
for i in range(5):
    t = threading.Thread(target=worker, args=(f"Thread-{i}", i), name=f"Worker-{i}")
    threads.append(t)
    t.start()
```

**Java threading issues:**

```java
// Use thread dumps to diagnose deadlocks
// Send SIGQUIT to running Java process:
kill -3 <pid>

// Or use jstack
jstack <pid>

// Look for "BLOCKED" threads in output
```

### Memory Leak Debugging

**Python:**

```python
import tracemalloc

# Start tracing
tracemalloc.start()

# Run code that might leak memory
large_list = []
for i in range(1000000):
    large_list.append([i] * 100)

# Take snapshot
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

print("Top 10 memory allocations:")
for stat in top_stats[:10]:
    print(stat)
```

**Java:**

```bash
# Run with verbose GC
java -verbose:gc -XX:+PrintGCDetails MyClass

# Take heap dump
jmap -dump:format=b,file=heap.bin <pid>

# Analyze with tools like VisualVM or Eclipse MAT
```

### Performance Debugging

**Python profiling:**

```python
import cProfile
import pstats

# Profile function
cProfile.run('my_function()', 'profile_stats')

# Analyze results
p = pstats.Stats('profile_stats')
p.sort_stats('cumulative')
p.print_stats(10)  # Top 10 slowest functions
```

**Java profiling:**

```bash
# Use Java Flight Recorder
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder \
     -XX:StartFlightRecording=duration=60s,filename=recording.jfr \
     MyClass

# Or use VisualVM, YourKit, or JProfiler
```

### Debugging Third-Party Libraries

**When error is in library code:**

1. **Check library version** - Is it up to date?
   ```bash
   pip show requests  # Python
   mvn dependency:tree  # Java
   ```

2. **Read library source** - Understand what it's trying to do
   ```python
   import inspect
   print(inspect.getsourcefile(problematic_function))
   ```

3. **Check issue tracker** - Has someone else reported this?
   - GitHub issues
   - Stack Overflow

4. **Try different version** - Downgrade/upgrade to see if bug exists
   ```bash
   pip install requests==2.25.0  # Specific version
   ```

5. **Minimal reproduction** - Create smallest example that triggers bug

### Remote Debugging

**Python remote debugging with pdb:**

```python
import pdb
import sys

# Allow remote connection
pdb.Pdb(stdin=sys.stdin, stdout=sys.stdout).set_trace()
```

**Java remote debugging:**

```bash
# Start Java with debug agent
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 MyClass

# Connect from IDE (IntelliJ/Eclipse) to localhost:5005
```

---

## Debugging Checklist

Before asking for help, have you:

- [ ] Read the full error message and stack trace?
- [ ] Identified the exact line where error occurs?
- [ ] Reproduced the error consistently?
- [ ] Created a minimal reproduction?
- [ ] Checked recent changes (git diff)?
- [ ] Verified assumptions with print statements or debugger?
- [ ] Searched online for the error message?
- [ ] Checked library documentation?
- [ ] Tried simplifying the code?
- [ ] Tested with different inputs?
- [ ] Verified environment (dependencies, versions)?
- [ ] Consulted rubber duck?

---

## When to Ask for Help

Ask for help when:

1. **After reasonable debugging effort** - You've tried the above strategies
2. **With context** - Provide error message, code, what you've tried
3. **With minimal reproduction** - Smallest code that demonstrates problem
4. **On appropriate platform** - Stack Overflow, GitHub issues, forums

**Good help request includes:**
- Full error message and stack trace
- Minimal code that reproduces error
- What you expected vs what happened
- What you've already tried
- Environment details (language version, OS, dependencies)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.