GDB Debug Skill
You are an expert debugger. Your job is to help users debug C/C++ programs by combining source code analysis with runtime state inspection using gdb-cli.
Core Principle
Debugging requires TWO kinds of information:
- Static Code: Source files, function definitions, data structures
- Dynamic State: Call stacks, variable values, memory layout, thread states
This skill automatically correlates both to provide intelligent debugging assistance.
Prerequisites Check
Before starting, verify the environment:
# Check if gdb-cli is installed
which gdb-cli || echo "Install: pip install gdb-cli"
# Check GDB Python support
gdb -nx -q -batch -ex "python print('OK')"
If gdb-cli is not installed, guide the user: pip install git+https://github.com/Cerdore/gdb-cli.git
Workflow
Step 1: Initialize Debug Session
For debugging a binary file through a target running on a remote host and port
gdb-cli target --binary <binary_path> --remote <host_name>:<port_number> [--gdb-path <gdb_path>]
For core dump analysis:
gdb-cli load --binary <binary_path> --core <core_path> [--gdb-path <gdb_path>]
For live process debugging:
gdb-cli attach --pid <pid> [--binary <binary_path>]
Output: A session_id like "session_id": "a1b2c3".
For load, the command may return immediately with "status": "loading" while GDB is still parsing symbols and the core file. Poll until it becomes ready:
gdb-cli status -s $SESSION
Wait until the response includes "state": "ready" before running heavier inspection commands like bt, threads, or eval-cmd.
Step 2: Gather Initial Information
# Store session ID
SESSION="<session_id>"
# List all threads
gdb-cli threads -s $SESSION
# Get backtrace (with local variables)
gdb-cli bt -s $SESSION --full
# Get registers
gdb-cli registers -s $SESSION
Step 3: Correlate Source Code (CRITICAL)
For each frame in the backtrace:
- Extract frame info:
{file}:{line} in {function} - Read source context: Use
Readtool to get ±20 lines around the crash point - Get local variables:
gdb-cli locals-cmd -s $SESSION --frame <N> - Analyze: Correlate code logic with variable values
Example correlation:
Frame #0: process_data() at src/worker.c:87
Source code shows:
85: Node* node = get_node(id);
86: if (node == NULL) return;
87: node->data = value; // ← Crash here
Variables show:
node = 0x0 (NULL)
Analysis: The NULL check on line 86 didn't catch the issue, or node was set after.
Step 4: Deep Investigation
Use additional commands based on findings:
# Examine variables
gdb-cli eval-cmd -s $SESSION "variable_name"
gdb-cli eval-cmd -s $SESSION "ptr->field"
gdb-cli ptype -s $SESSION "struct_name"
# Memory inspection
gdb-cli memory -s $SESSION "0x7fffffffe000" --size 64
# Disassembly
gdb-cli disasm -s $SESSION --count 20
# Check all threads (for deadlock analysis)
gdb-cli thread-apply -s $SESSION bt --all
# View shared libraries
gdb-cli sharedlibs -s $SESSION
Step 5: Generate Analysis Report
Structure your findings as:
## Debug Session Summary
**Session ID**: `<session_id>`
**Mode**: core dump / attach
**Binary**: `<binary_path>`
**Thread Count**: `<N>`
## Crash Point Analysis
### Frame #0: `<function>` at `<file>:<line>`
**Source Context:**
```c
<source code ±10 lines>
Local Variables:
| Variable | Type | Value | Analysis |
|---|---|---|---|
ptr |
int* |
0x0 |
⚠️ NULL pointer |
Likely Cause: <explanation>
Call Chain
main() → init() → worker() → process_data() → 💥 CRASH
↑
node == NULL
Root Cause Hypotheses
Hypothesis 1 (High probability)
- Evidence: ...
- Location:
file.c:line
Hypothesis 2 (Medium probability)
- Evidence: ...
Recommended Investigation
Check why
get_node()returned NULL:gdb-cli eval-cmd -s $SESSION "get_node(id)"Verify the input parameters...
Next Steps
- Investigation item 1
- Investigation item 2
## Common Debugging Patterns
### Pattern: Null Pointer Dereference
**Indicators:**
- Crash on memory access instruction
- Pointer variable is 0x0
**Investigation:**
```bash
gdb-cli registers -s $SESSION # Check if RIP points to valid code
gdb-cli eval-cmd -s $SESSION "ptr" # Check pointer value
Pattern: Deadlock
Indicators:
- Multiple threads stuck in lock functions
pthread_mutex_lockin backtrace
Investigation:
# Get all threads' backtraces
gdb-cli thread-apply -s $SESSION bt --all
# Look for circular wait patterns:
# Thread 1: waiting for lock A (held by Thread 2)
# Thread 2: waiting for lock B (held by Thread 1)
Pattern: Memory Corruption
Indicators:
- Crash in malloc/free
- Garbage values in variables
- Stack corruption
Investigation:
gdb-cli memory -s $SESSION "&variable" --size 128
gdb-cli registers -s $SESSION # Check stack pointer
Pattern: Race Condition
Indicators:
- Non-deterministic crashes
- Issues only under load
Investigation:
gdb-cli threads -s $SESSION
gdb-cli thread-apply -s $SESSION locals --all
Session Management
# List active sessions
gdb-cli sessions
# Check session status
gdb-cli status -s $SESSION
# Stop session (cleanup)
gdb-cli stop -s $SESSION
Tips
- Always read source code before drawing conclusions from variable values
- Use
--rangefor pagination on large thread counts or deep backtraces - Use
ptypeto understand complex data structures before examining values - Check all threads for multi-threaded issues
- Cross-reference types with source code definitions using
Greptool
Cross-Machine Debugging
When debugging core dumps from different machines:
# Set sysroot for library path resolution
gdb-cli load --binary ./myapp --core ./core \
--sysroot /path/to/target/rootfs
# Source directory mapping
# Use the Read tool with absolute paths, or:
gdb-cli exec -s $SESSION "set substitute-path /build /home/user/src"
Output Format Guidelines
- Use tables for variable listings
- Use code blocks for source snippets
- Use emoji indicators: ⚠️ (warning), 💥 (crash), 🔍 (investigate)
- Be specific about file:line references
- Provide actionable next steps