Skip to main content
This guide covers debugging techniques and tools for Redox OS development, including GDB debugging, QEMU options, and network analysis.

GDB Debugging

Kernel Debugging

Debug the Redox kernel using GDB with QEMU’s remote debugging protocol.
1

Start QEMU with GDB support

In one terminal, start QEMU with GDB enabled:
make qemu gdb=yes
This starts QEMU with the flags -d cpu_reset -s -S, which:
  • Logs CPU resets
  • Opens a GDB server on port 1234
  • Waits for GDB to connect before starting
2

Connect GDB

In another terminal, connect GDB to the kernel:
make gdb
This runs:
rust-gdb recipes/core/kernel/target/<TARGET>/build/kernel.sym \
  --eval-command="target remote :1234"
3

Debug

Use standard GDB commands to debug:
# Set a breakpoint
break kernel::main

# Continue execution
continue

# Step through code
step
next

# Examine variables
print variable_name

# View backtrace
backtrace
Non-blocking GDB mode: Use gdb=nonblock to allow attaching GDB without blocking QEMU startup:
make qemu gdb=nonblock

Userspace Debugging

Use gdbserver when possible! The userspace debugging target stops the entire VM, not just the application. Only use this when:
  • The application runs early during boot before the network stack starts
  • You need to debug the interaction between the application and kernel

Advanced GDB Debugging

Enable debug symbols and use gdbgui for a web-based debugging interface:
1

Build with debug symbols

REPO_DEBUG=1 make cr.recipe rebuild
Verify debug symbols:
file binary-path  # Should output "debug_info, not stripped"
2

Start QEMU with GDB

make qemu kvm=no QEMU_SMP=1 gdb=yes
3

Launch gdbgui

make debug.recipe-name DEBUG_BIN=binary-name
Open http://localhost:5000/dashboard in your browser.
This is experimental and may not work if ARCH differs from the host architecture.
For debugging architectures different from your host:
export RUST_GDB=gdb-multiarch
make gdb
This is set automatically in the Makefile:
export RUST_GDB=gdb-multiarch

QEMU Debugging Options

Serial Output and Debugging Console

By default, serial output is enabled:
make qemu
This uses:
-chardev stdio,id=debug,signal=off,mux=on
-serial chardev:debug
-mon chardev=debug

Graphics and Display Options

make qemu gpu=no

CPU and Performance Options

Enable KVM for faster execution (default on matching host arch):
make qemu kvm=yes
Disable KVM:
make qemu kvm=no
On Linux with matching architecture, this uses -enable-kvm -cpu host. On macOS with ARM, this uses -accel hvf -cpu max.

Disk and Storage Options

make qemu disk=nvme

Network Debugging

By default, network traffic is captured to a pcap file:
make qemu
This creates build/<arch>/<config>/network.pcap.View with Wireshark:
make wireshark
Or directly:
wireshark build/<arch>/<config>/network.pcap

Logging and Error Collection

Capture All Output

Capture both stdout and stderr to a log file:
make qemu 2>&1 | tee redox-debug.log

Build System Logging

Enable verbose logging during builds:
# Verbose cookbook output
COOKBOOK_VERBOSE=true make r.recipe-name

# Build with debug symbols
REPO_DEBUG=1 make cr.recipe-name

# Combine both
COOKBOOK_VERBOSE=true REPO_DEBUG=1 make cr.recipe-name 2>&1 | tee build.log

Architecture-Specific Debugging

Default configuration:
make qemu ARCH=x86_64 QEMU_SMP=4 QEMU_MEM=2048
Debug exit codes (for redoxer):
make qemu redoxer=yes
Uses -device isa-debug-exit (exit code: 51 = success, 53 = failure).

Common Debugging Scenarios

1

Use serial console

make qemu serial=yes qemu_serial_logfile=boot.log
2

Check bootloader

For UEFI boot issues, verify firmware path:
# x86_64
ls /usr/share/OVMF/OVMF_CODE.fd

# aarch64
ls /usr/share/AAVMF/AAVMF_CODE.fd

# riscv64gc
ls /usr/share/qemu-efi-riscv64/RISCV_VIRT_CODE.fd
3

Try different boot methods

# Try legacy BIOS (x86_64)
make qemu uefi=no

# Try live ISO
make qemu live=yes
1

Enable packet capture

make qemu net=default
This creates build/network.pcap.
2

Analyze with Wireshark

make wireshark
3

Test connectivity

Use port forwarding to test services:
make qemu net=redir

# From host
ssh -p 8022 user@localhost
curl http://localhost:8080
1

Build driver with debug symbols

REPO_DEBUG=1 make cr.driver-name
2

Update initfs

3

Run with serial logging

make qemu serial=yes qemu_serial_logfile=driver-debug.log
4

Debug with GDB

make qemu gdb=yes
# In another terminal
make gdb
1

Mount the filesystem

make mount
Inspect at build/<arch>/<config>/filesystem/.
2

Check disk image

# Check image integrity
file build/<arch>/<config>/harddrive.img
3

Unmount when done

make unmount

Performance Profiling

QEMU Performance Options

# Maximize performance
make qemu kvm=yes QEMU_SMP=8 QEMU_MEM=4096 disk=virtio net=virtio

# Profile mode (slower but more accurate)
make qemu kvm=no QEMU_SMP=1

Benchmarking

Run benchmarks on Redox:
# Build with benchmarks included
make all CONFIG_NAME=tests

# Run the system
make qemu CONFIG_NAME=tests
The tests.toml configuration includes:
  • redox-tests package
  • benchmarks package

Troubleshooting

1

Check QEMU is waiting

Ensure you see the GDB server message:
waiting for gdb connection on port 1234
2

Verify port availability

netstat -an | grep 1234
3

Try manual connection

gdb-multiarch
(gdb) target remote :1234
  • Try serial=yes explicitly
  • Check if output is going to a logfile
  • Verify QEMU version compatibility
  • Enable KVM: make qemu kvm=yes
  • Reduce SMP: make qemu QEMU_SMP=1
  • Use lighter GPU: make qemu gpu=no
  • Disable audio: make qemu audio=no

Additional Resources

Developer FAQ

Common debugging questions

Build System Reference

Complete build system documentation

Testing Guide

Learn how to test your changes

Kernel Documentation

Kernel API documentation

Build docs developers (and LLMs) love