firecracker-microvm/firecracker · error
GDB requires KVM
Error message
GDB requires KVM
What it means
`expect("GDB requires KVM")` at the top of `gdb_thread` (mod.rs:47): before serving any GDB connection, the stub locks the Vmm and calls `vmm.vm.as_kvm()` to obtain vcpu fds for installing the entry hardware breakpoint. If the VM is not KVM-backed, as_kvm() is None and the thread panics.
Source
Thrown at src/vmm/src/gdb/mod.rs:47
///
/// This will then create the GDB socket which will be used for communication to the GDB process.
/// After creating this, the function will block while waiting for GDB to connect.
///
/// After the connection has been established the function will start a new thread for handling
/// communcation to the GDB server
pub fn gdb_thread(
vmm: Arc<Mutex<Vmm>>,
gdb_event_receiver: Receiver<usize>,
entry_addr: GuestAddress,
socket_addr: &str,
) -> Result<(), GdbTargetError> {
// We register a hw breakpoint at the entry point as GDB expects the application
// to be stopped as it connects. This also allows us to set breakpoints before kernel starts.
// This entry adddress is automatically used as it is not tracked inside the target state, so
// when resumed will be removed
{
let vmm = vmm.lock().unwrap();
let kvm_vm = vmm.vm.as_kvm().expect("GDB requires KVM");
let handles = kvm_vm.vcpus_handles();
vcpu_set_debug(&handles[0].vcpu_fd, &[entry_addr], false)?;
for handle in &handles[1..] {
vcpu_set_debug(&handle.vcpu_fd, &[], false)?;
}
}
let path = Path::new(socket_addr);
let listener = UnixListener::bind(path).map_err(GdbTargetError::ServerSocketError)?;
trace!("Waiting for GDB server connection on {}...", path.display());
let (connection, _addr) = listener
.accept()
.map_err(GdbTargetError::ServerSocketError)?;
std::thread::Builder::new()
.name("gdb".into())
.spawn(move || event_loop(connection, vmm, gdb_event_receiver, entry_addr))
.map_err(|_| GdbTargetError::GdbThreadError)?;View on GitHub (pinned to 0a745def42)
Solutions
- Verify KVM is available and used before spawning the gdb thread: check `vmm.vm.as_kvm().is_some()` and return an error like RequiresKvm otherwise
- Ensure /dev/kvm is present and the user has rw access (kvm group)
- Skip enabling the GDB feature on non-KVM deployments
Example fix
// before
let kvm_vm = vmm.vm.as_kvm().expect("GDB requires KVM");
// after
let kvm_vm = vmm
.vm
.as_kvm()
.ok_or(GdbTargetError::RequiresKvm)?; Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight the gdb thread
let kvm_ok = vmm.lock().unwrap().vm.as_kvm().is_some();
if !kvm_ok {
return Err(GdbTargetError::RequiresKvm); // instead of spawning gdb_thread
} Type guard
fn gdb_supported(vmm: &Arc<Mutex<Vmm>>) -> bool {
vmm.lock().unwrap().vm.as_kvm().is_some()
} Prevention
- Gate the --gdb flag on KVM detection at CLI parsing time
- Keep gdb and non-KVM backend features mutually exclusive in the build matrix
- Surface RequiresKvm as a config validation error, not a runtime panic
When it happens
Trigger: Starting the GDB thread (`gdb_thread(...)`) against a Vmm constructed with a non-KVM backend — the breakpoint-install step `vcpu_set_debug(&handles[0].vcpu_fd, &[entry_addr], false)` needs real KVM vcpu fds and there is no fallback.
Common situations: GDB/debug feature enabled in a build or test environment where the VM runs without KVM (mock vm in tests, alternate hypervisor backend, /dev/kvm absent so a degraded config was picked).
Related errors
- GDB requires KVM
- Error getting initial gdb event
- GDB requires KVM
- Error converting cpu id to Tid
- error unlocking vmm
AI-assisted analysis of firecracker-microvm/firecracker@0a745def42 (2026-08-19).
Data as JSON: /api/errors/1c4f87d64a76eb03.
Report an issue: GitHub.