| name | qemu-debug-session |
| description | Use when setting up comprehensive QEMU debugging for Breenix - investigating interrupt handling bugs, debugging memory management issues, analyzing boot sequence problems, tracing hardware interactions, or inspecting CPU state during failures. |
Breenix QEMU Debug Session
This skill provides comprehensive QEMU debugging capabilities for Breenix kernel development, including live inspection, detailed logging, and monitor access.
Usage
Invoke this skill when:
- Investigating interrupt handling bugs
- Debugging memory management issues
- Analyzing boot sequence problems
- Tracing hardware interactions
- Inspecting CPU state during failures
Debugging Scenarios
1. Interrupt and Timer Debugging
For interrupt-related issues (context switches, timer behavior, IRQ handling):
BREENIX_QEMU_LOG_PATH=/tmp/breenix-debug.log \
BREENIX_QEMU_DEBUG_FLAGS="int,cpu_reset,guest_errors" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio -display none
This enables:
int: Log all interrupts (IRQ delivery, exceptions, traps)cpu_reset: Track CPU resets and initializationguest_errors: Capture guest OS errors (page faults, invalid ops, etc.)
2. Memory and Page Table Debugging
For memory allocation, paging, or MMU issues:
BREENIX_QEMU_LOG_PATH=/tmp/breenix-memory.log \
BREENIX_QEMU_DEBUG_FLAGS="mmu,guest_errors,page" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio -display none
This enables:
mmu: Memory Management Unit operationspage: Page table walks and TLB operationsguest_errors: Page faults and access violations
3. Boot Sequence Analysis
For boot hangs, firmware issues, or early initialization problems:
BREENIX_QEMU_DEBUGCON_FILE=/tmp/ovmf-debug.log \
BREENIX_QEMU_LOG_PATH=/tmp/breenix-boot.log \
BREENIX_QEMU_DEBUG_FLAGS="guest_errors,cpu_reset" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio -display none
This captures:
- OVMF firmware debug output to separate file
- CPU reset events
- Guest errors during boot
4. CPU State Inspection
For register corruption, flag issues, or instruction tracing:
BREENIX_QEMU_LOG_PATH=/tmp/breenix-cpu.log \
BREENIX_QEMU_DEBUG_FLAGS="cpu,in_asm,int,guest_errors" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio -display none
WARNING: This generates MASSIVE logs (100+ MB/second). Use only for targeted debugging:
cpu: Dump CPU state after each instructionin_asm: Show instruction disassembly- Only run for short durations!
QEMU Monitor Access
The monitor allows live inspection of the running kernel without stopping execution.
TCP Monitor (Recommended for Development)
BREENIX_QEMU_MONITOR=tcp cargo run --release --bin qemu-uefi
Then in another terminal:
telnet localhost 4444
Stdio Monitor (Interactive)
BREENIX_QEMU_MONITOR=stdio cargo run --release --bin qemu-uefi
WARNING: Stdio monitor mixes with kernel output. Use TCP for cleaner separation.
Monitor Commands
Once connected to the monitor, useful commands:
CPU and Register Inspection
info registers # Show all CPU registers
info registers -a # Show all registers including hidden state
info cpus # List all virtual CPUs
info fpu # Show FPU registers
info idt # Show Interrupt Descriptor Table
info gdt # Show Global Descriptor Table
Memory Inspection
info mem # Show virtual memory mappings
info tlb # Show TLB entries
x/10i $rip # Disassemble 10 instructions at current RIP
x/32xb 0xdeadbeef # Dump 32 bytes at address in hex
xp/10gx 0xdeadbeef # Dump 10 8-byte values (physical address)
Interrupt and Timer State
info pic # Show PIC (legacy interrupt controller) state
info ioapic # Show I/O APIC state
info lapic # Show Local APIC state
info qtree # Show device tree (find timer devices)
Execution Control
stop # Pause execution
cont # Resume execution
system_reset # Reset the system
quit # Exit QEMU
Available Debug Flags
Set via BREENIX_QEMU_DEBUG_FLAGS (comma-separated):
High-Level Flags
guest_errors: Guest OS errors (page faults, invalid ops) - Start hereunimp: Unimplemented device/feature accessint: Interrupt delivery and exceptionscpu_reset: CPU initialization and resets
Memory Flags
mmu: MMU operations (PT walks, TLB fills)page: Page table operationspcall: Protected mode call gates
CPU Flags (VERY VERBOSE)
cpu: Full CPU state after each instructionin_asm: Disassembly of executed instructionsexec: Basic execution tracenochain: Disable TB chaining
Device Flags
ioport: I/O port access (useful for timer/PIC debugging)pci: PCI configuration space access
Log Analysis Tips
Finding Interrupt Issues
grep -A5 "exception\|interrupt\|IRQ" /tmp/breenix-debug.log
Look for:
- Unexpected exceptions (e.g., GPF, Page Fault during interrupt handling)
- Missing or duplicate interrupts
- Interrupt delivery to wrong CPU
Detecting Timer Problems
grep -E "APIC|timer|IRQ 0|IRQ 32" /tmp/breenix-debug.log
Look for:
- Timer interrupts not firing at expected rate
- Spurious interrupts
- APIC timer configuration changes
Memory Issues
grep -E "page fault|#PF|CR3|MMU" /tmp/breenix-memory.log
Look for:
- Page faults in kernel space (usually bugs)
- CR3 changes (context switches)
- Invalid page table entries
Boot Hangs
tail -f /tmp/ovmf-debug.log # Watch firmware output
grep "cpu_reset\|triple fault" /tmp/breenix-boot.log
Look for:
- Triple faults (usually bad IDT or bad interrupt handler)
- Hangs after specific firmware phase
- Repeated resets
Example Debugging Workflow
Scenario: Timer interrupt not firing
- Start with basic interrupt logging:
BREENIX_QEMU_LOG_PATH=/tmp/debug.log \
BREENIX_QEMU_DEBUG_FLAGS="int,guest_errors" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio
- In another terminal, connect to monitor:
telnet localhost 4444
- Check APIC state:
info lapic
Look for:
- Timer mode (one-shot vs periodic)
- Initial count vs current count
- Whether timer interrupt is masked
- Check interrupt delivery:
info pic
info ioapic
Verify IRQ 0 (PIT) or IRQ 32 (APIC timer) is not masked.
- Grep log for interrupt activity:
grep "IRQ.*timer\|exception 32" /tmp/debug.log | less
- If no interrupts appear, check IDT: In monitor:
info idt
Verify entry 32 (or appropriate vector) has valid handler address.
Environment Variables Reference
| Variable | Values | Purpose |
|---|---|---|
BREENIX_QEMU_LOG_PATH |
File path | Destination for QEMU debug logs |
BREENIX_QEMU_DEBUG_FLAGS |
Comma-separated flags | Enable specific QEMU logging (see flags above) |
BREENIX_QEMU_MONITOR |
none/stdio/tcp |
Monitor interface (default: none) |
BREENIX_QEMU_DEBUGCON_FILE |
File path | Capture firmware debug console (0x402) |
BREENIX_QEMU_DEBUGCON |
1 |
Route debug console to stdio |
BREENIX_VISUAL_TEST |
1 |
Show QEMU window (for visual debugging) |
BREENIX_QEMU_STORAGE |
ide/virtio |
Storage controller type |
BREENIX_GDB |
1 |
Enable GDB server on localhost:1234 |
Common Pitfalls
- Stdio monitor + serial output = chaos: Always use
BREENIX_QEMU_MONITOR=tcp - Forgetting -serial stdio: Monitor doesn't show kernel output; you need both
- Too much logging: Start with
guest_errors,int, notcpu,in_asm - Log file grows huge: Check log size;
cpuflag can fill GB in seconds - Monitor commands fail: Ensure QEMU is still running (kernel panic exits QEMU)
Quick Reference Card
# Start debugging session (interrupt focus)
BREENIX_QEMU_LOG_PATH=/tmp/debug.log \
BREENIX_QEMU_DEBUG_FLAGS="int,guest_errors" \
BREENIX_QEMU_MONITOR=tcp \
cargo run --release --bin qemu-uefi -- -serial stdio
# Connect to monitor
telnet localhost 4444
# Essential monitor commands
info registers # CPU state
info lapic # Timer and interrupts
x/10i $rip # Disassemble at current position
info mem # Virtual memory map
# Analyze logs
grep -A5 "exception\|IRQ" /tmp/debug.log
Notes
- Debug logging adds overhead; execution will be slower
- TCP monitor allows inspection without pausing execution
- Most bugs are visible with just
guest_errors,intlogging - Save logs before QEMU exits; they're not persistent across runs
- GDB stub (
BREENIX_GDB=1) is complementary; use for source-level debugging