Skip to content

Latest commit

 

History

History
526 lines (398 loc) · 13.1 KB

File metadata and controls

526 lines (398 loc) · 13.1 KB

Autonomous Debugging with IBM BOB

Overview

The Compiler Copilot includes an Autonomous Debugging feature where IBM BOB takes complete control of the debugging session. Instead of manually entering debugging commands, you simply specify your debugging goal, and BOB automatically:

  1. Runs appropriate debugging commands
  2. Analyzes the output from each command
  3. Decides the next debugging step based on findings
  4. Continues until the goal is achieved or maximum steps reached
  5. Generates a comprehensive summary of findings

This enables hands-off debugging where you can focus on understanding the results rather than executing individual commands.

How It Works

Architecture

User Input (Goal)
       ↓
IBM BOB Analyzes Goal
       ↓
┌──────────────────────────────────┐
│  Autonomous Debugging Loop       │
│                                  │
│  1. BOB decides next command     │
│  2. Execute command in debugger  │
│  3. BOB analyzes output          │
│  4. Check if goal achieved       │
│  5. Repeat or complete           │
└──────────────────────────────────┘
       ↓
Generate Summary
       ↓
Present Findings to User

Decision Making Process

IBM BOB uses the following strategy to decide debugging commands:

  1. Initial Phase: Start with basic commands (run, backtrace, info registers)
  2. Investigation Phase: Set breakpoints, examine variables, inspect memory
  3. Analysis Phase: Step through code, analyze stack traces, check register values
  4. Completion Phase: Determine if goal is achieved or if stuck

Usage

Basic Command

autodebug <program> "<debugging_goal>" [--debugger gdb|lldb]

Examples

Example 1: Find Segmentation Fault

copilot> autodebug ./myprogram "Find cause of segmentation fault"

What BOB Does:

  1. Starts the program
  2. Runs until crash
  3. Gets backtrace
  4. Examines registers at crash point
  5. Inspects memory addresses
  6. Identifies null pointer dereference
  7. Provides fix suggestions

Example 2: Debug Memory Leak

copilot> autodebug ./app "Identify memory leak" --debugger gdb

What BOB Does:

  1. Sets breakpoints at malloc/free
  2. Runs program
  3. Tracks allocations
  4. Identifies unfreed memory
  5. Shows allocation stack traces
  6. Suggests where to add free()

Example 3: Infinite Loop

copilot> autodebug ./test "Debug infinite loop"

What BOB Does:

  1. Runs program
  2. Interrupts after timeout
  3. Gets backtrace
  4. Examines loop variables
  5. Identifies loop condition issue
  6. Suggests fix

Example 4: Logic Error

copilot> autodebug ./calculator "Find why division returns wrong result"

What BOB Does:

  1. Sets breakpoint at division function
  2. Runs with test input
  3. Steps through function
  4. Examines variables at each step
  5. Identifies integer division issue
  6. Suggests using float

Session Output

Real-time Output

During autonomous debugging, you'll see:

🤖 AUTONOMOUS DEBUGGING SESSION STARTED
================================================================================
Session ID: debug_1717567890
Program: ./myprogram
Goal: Find cause of segmentation fault
Debugger: GDB
Max Steps: 50
================================================================================

────────────────────────────────────────────────────────────────────────────────
🔍 Step 1/50
────────────────────────────────────────────────────────────────────────────────
💭 BOB's reasoning: Start program execution to trigger the crash
🔧 Executing: run
📤 Output:
Starting program: /path/to/myprogram
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401234 in main () at program.c:15
15          *ptr = 42;
🧠 BOB's analysis: Program crashed with SIGSEGV at line 15 when dereferencing pointer 'ptr'

────────────────────────────────────────────────────────────────────────────────
🔍 Step 2/50
────────────────────────────────────────────────────────────────────────────────
💭 BOB's reasoning: Get full stack trace to understand call chain
🔧 Executing: backtrace
📤 Output:
#0  0x0000000000401234 in main () at program.c:15
🧠 BOB's analysis: Crash occurred in main function, no other functions in call stack

... (continues until goal achieved)

✅ BOB determined debugging goal is achieved

================================================================================
📊 GENERATING DEBUGGING SUMMARY
================================================================================

================================================================================
📋 AUTONOMOUS DEBUGGING SESSION SUMMARY
================================================================================

Session ID: debug_1717567890
Program: ./myprogram
Goal: Find cause of segmentation fault
Total Steps: 5
Duration: 0m 12s

## OBJECTIVE
Find the root cause of the segmentation fault in the program.

## APPROACH
1. Executed the program to trigger the crash
2. Analyzed the crash location and stack trace
3. Examined the pointer variable that caused the crash
4. Inspected memory and register values
5. Identified the null pointer dereference

## KEY FINDINGS
- Segmentation fault at line 15 in main()
- Pointer 'ptr' was NULL when dereferenced
- No initialization of 'ptr' before use
- Register analysis confirms NULL pointer (0x0)

## TECHNICAL DETAILS
- Crash address: 0x0000000000401234
- Faulting instruction: mov DWORD PTR [rax], 0x2a
- RAX register: 0x0 (NULL)
- Source line: *ptr = 42;

## CONCLUSION
The segmentation fault is caused by dereferencing an uninitialized pointer 'ptr'
at line 15. The pointer was never assigned a valid memory address before use.

## RECOMMENDATIONS
1. Initialize ptr before use: int *ptr = malloc(sizeof(int));
2. Add NULL check: if (ptr != NULL) { *ptr = 42; }
3. Free allocated memory: free(ptr);
4. Compile with warnings: gcc -Wall -Wextra program.c

================================================================================

💾 Session saved to: /path/to/sessions/autodebug_debug_1717567890.json

Session File

The complete session is saved as JSON:

{
  "session_id": "debug_1717567890",
  "program": "./myprogram",
  "debugger_type": "gdb",
  "initial_goal": "Find cause of segmentation fault",
  "start_time": "2026-06-05T12:00:00",
  "end_time": "2026-06-05T12:00:12",
  "total_steps": 5,
  "findings": [
    "Segmentation fault at line 15",
    "NULL pointer dereference identified",
    "Pointer 'ptr' was never initialized"
  ],
  "summary": "...",
  "steps": [
    {
      "step_number": 1,
      "command": "run",
      "output": "...",
      "analysis": "...",
      "timestamp": "2026-06-05T12:00:01"
    }
    // ... more steps
  ]
}

Configuration

Maximum Steps

By default, autonomous debugging runs for a maximum of 50 steps. This prevents infinite loops. You can modify this in the code:

auto_debugger = AutonomousDebugger(
    debugger_wrapper=debugger_wrapper,
    llm_client=self.ibm_bob,
    max_steps=100  # Increase if needed
)

Debugger Selection

Choose between GDB and LLDB:

# Use GDB (default)
autodebug ./program "goal"

# Use LLDB explicitly
autodebug ./program "goal" --debugger lldb

# Use GDB explicitly
autodebug ./program "goal" --debugger gdb

Best Practices

1. Clear Goals

Provide specific, actionable goals:

Good:

  • "Find cause of segmentation fault"
  • "Identify memory leak in function process_data"
  • "Debug why loop never terminates"
  • "Find why variable x has wrong value"

Bad:

  • "Fix my program"
  • "Make it work"
  • "Debug"

2. Compile with Debug Info

Always compile with -g flag:

gcc -g -O0 program.c -o program

This provides:

  • Line number information
  • Variable names
  • Function names
  • Source code mapping

3. Reproducible Issues

Ensure the issue is reproducible:

  • Use consistent input
  • Set random seeds if applicable
  • Document steps to trigger the issue

4. Review Sessions

After autonomous debugging:

  1. Read the summary carefully
  2. Review the session JSON for details
  3. Understand each step BOB took
  4. Apply suggested fixes
  5. Re-run to verify

Comparison: Manual vs Autonomous

Manual Debugging

copilot> debug ./program
copilot> run
copilot> backtrace
copilot> info registers
copilot> print ptr
copilot> x/10x ptr
# ... many more commands

Pros:

  • Full control
  • Can explore freely
  • Learn debugging techniques

Cons:

  • Time-consuming
  • Requires debugging expertise
  • Easy to miss important details

Autonomous Debugging

copilot> autodebug ./program "Find the bug"
# BOB handles everything

Pros:

  • Fast and efficient
  • No debugging expertise needed
  • Comprehensive analysis
  • Automatic summary generation
  • Consistent methodology

Cons:

  • Less control
  • May not explore all paths
  • Limited by max steps

Advanced Usage

Combining with Other Features

1. After Autonomous Debugging

# Run autonomous debugging
copilot> autodebug ./program "Find segfault"

# Then analyze the code
copilot> generate ir program.c
copilot> analyze ir program.c

# Get fix suggestions
copilot> suggest fix program.c

2. Multiple Debugging Goals

# First goal
copilot> autodebug ./program "Find memory leak"

# Second goal (after fixing first issue)
copilot> autodebug ./program "Optimize performance"

Session History Integration

All autonomous debugging sessions are logged to your session history:

# View session history
cat sessions/session_20260605_120000.md

# View specific autodebug session
cat sessions/autodebug_debug_1717567890.json

Troubleshooting

BOB Gets Stuck

If BOB reports "STUCK":

  1. Check the reason in the output
  2. Review last few steps to understand what happened
  3. Try a more specific goal
  4. Manually debug the specific area BOB identified

Maximum Steps Reached

If debugging hits max steps:

  1. Review the session to see progress
  2. Increase max_steps if needed
  3. Break down the goal into smaller sub-goals
  4. Use manual debugging for complex issues

Debugger Errors

If debugger commands fail:

  1. Check program is compiled with debug info
  2. Verify debugger is installed (gdb/lldb)
  3. Check program permissions
  4. Review error messages in session log

Examples by Issue Type

Segmentation Fault

autodebug ./program "Find segmentation fault cause"

BOB will:

  • Run until crash
  • Get backtrace
  • Examine crash location
  • Check pointer values
  • Identify null/invalid pointer

Memory Leak

autodebug ./program "Find memory leak"

BOB will:

  • Track allocations
  • Monitor free() calls
  • Identify unfreed memory
  • Show allocation points

Infinite Loop

autodebug ./program "Debug infinite loop"

BOB will:

  • Run with timeout
  • Interrupt execution
  • Examine loop variables
  • Check loop conditions
  • Identify why loop doesn't exit

Wrong Output

autodebug ./calculator "Find why 5/2 returns 2 instead of 2.5"

BOB will:

  • Set breakpoints
  • Step through calculation
  • Examine variable types
  • Identify integer division
  • Suggest float usage

Integration with CI/CD

You can use autonomous debugging in automated testing:

#!/bin/bash
# test_script.sh

# Run tests
./run_tests.sh

# If crash detected, auto-debug
if [ $? -ne 0 ]; then
    ./compiler-copilot.sh -c "autodebug ./test_program 'Find test failure cause'"
fi

Limitations

  1. Max Steps: Limited to configured maximum (default 50)
  2. Complex Issues: May not solve highly complex bugs
  3. Non-Deterministic: Results may vary between runs
  4. Debugger Dependent: Limited by GDB/LLDB capabilities
  5. AI Limitations: Subject to IBM BOB's understanding

Future Enhancements

Planned features:

  • Interactive mode (pause and ask user)
  • Custom debugging strategies
  • Multi-threaded debugging support
  • Performance profiling integration
  • Automatic fix application
  • Regression test generation

Conclusion

Autonomous debugging with IBM BOB provides a powerful, hands-off approach to finding and understanding bugs. By letting BOB handle the debugging commands and analysis, you can focus on understanding the root cause and applying fixes.

For best results:

  • Provide clear, specific goals
  • Compile with debug information
  • Review the generated summaries
  • Combine with other Compiler Copilot features
  • Use manual debugging for complex cases

Happy debugging! 🐛🔍