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