Skip to content

Commit dd4555a

Browse files
committed
fix(gdb): remove wrong ordering and double locking
With the vcpu refactoring gdb support got broken. While we have a test to verify it builds, we still don't have one to verify it works. In particular, the gdb thread was created too early, and the vmm was locked twice leading to a deadlock. This change fixes both issues and adds a little bit more logging for the errors in GDB which were helpful to debug the issue. Signed-off-by: Riccardo Mancini <[email protected]>
1 parent fe0679e commit dd4555a

File tree

3 files changed

+19
-20
lines changed

3 files changed

+19
-20
lines changed

src/vmm/src/builder.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ pub enum StartMicrovmError {
115115
CreateEntropyDevice(crate::devices::virtio::rng::EntropyError),
116116
/// Failed to allocate guest resource: {0}
117117
AllocateResources(#[from] vm_allocator::Error),
118-
/// Error starting GDB debug session
118+
/// Error starting GDB debug session: {0}
119119
#[cfg(feature = "gdb")]
120120
GdbServer(gdb::target::GdbTargetError),
121121
/// Error cloning Vcpu fds
@@ -292,19 +292,12 @@ pub fn build_microvm_for_boot(
292292
let vmm = Arc::new(Mutex::new(vmm));
293293

294294
#[cfg(feature = "gdb")]
295-
{
296-
let (gdb_tx, gdb_rx) = mpsc::channel();
297-
vcpus
298-
.iter_mut()
299-
.for_each(|vcpu| vcpu.attach_debug_info(gdb_tx.clone()));
300-
301-
if let Some(gdb_socket_path) = &vm_resources.machine_config.gdb_socket_path {
302-
gdb::gdb_thread(vmm.clone(), gdb_rx, entry_point.entry_addr, gdb_socket_path)
303-
.map_err(StartMicrovmError::GdbServer)?;
304-
} else {
305-
debug!("No GDB socket provided not starting gdb server.");
306-
}
307-
}
295+
let (gdb_tx, gdb_rx) = mpsc::channel();
296+
297+
#[cfg(feature = "gdb")]
298+
vcpus
299+
.iter_mut()
300+
.for_each(|vcpu| vcpu.attach_debug_info(gdb_tx.clone()));
308301

309302
// Move vcpus to their own threads and start their state machine in the 'Paused' state.
310303
vmm.lock()
@@ -318,6 +311,14 @@ pub fn build_microvm_for_boot(
318311
)
319312
.map_err(VmmError::VcpuStart)?;
320313

314+
#[cfg(feature = "gdb")]
315+
if let Some(gdb_socket_path) = &vm_resources.machine_config.gdb_socket_path {
316+
gdb::gdb_thread(vmm.clone(), gdb_rx, entry_point.entry_addr, gdb_socket_path)
317+
.map_err(StartMicrovmError::GdbServer)?;
318+
} else {
319+
debug!("No GDB socket provided not starting gdb server.");
320+
}
321+
321322
// Load seccomp filters for the VMM thread.
322323
// Execution panics if filters cannot be loaded, use --no-seccomp if skipping filters
323324
// altogether is the desired behaviour.

src/vmm/src/gdb/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,11 @@ pub fn gdb_thread(
5151
}
5252

5353
let path = Path::new(socket_addr);
54-
let listener = UnixListener::bind(path).map_err(|_| GdbTargetError::ServerSocketError)?;
54+
let listener = UnixListener::bind(path).map_err(GdbTargetError::ServerSocketError)?;
5555
trace!("Waiting for GDB server connection on {}...", path.display());
5656
let (connection, _addr) = listener
5757
.accept()
58-
.map_err(|_| GdbTargetError::ServerSocketError)?;
58+
.map_err(GdbTargetError::ServerSocketError)?;
5959

6060
std::thread::Builder::new()
6161
.name("gdb".into())

src/vmm/src/gdb/target.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ pub enum GdbTargetError {
6565
NoPausedVcpu,
6666
/// Error when setting Vcpu debug flags
6767
VcpuKvmError,
68-
/// Server socket Error
69-
ServerSocketError,
68+
/// Server socket Error: {0}
69+
ServerSocketError(std::io::Error),
7070
/// Error with creating GDB thread
7171
GdbThreadError,
7272
/// VMM locking error
@@ -394,8 +394,6 @@ impl MultiThreadBase for FirecrackerTarget {
394394
let vcpu_idx = tid_to_vcpuid(tid);
395395
let vcpu_fd = &vmm.vcpus_handles[vcpu_idx].vcpu_fd;
396396

397-
let vmm = &self.vmm.lock().expect("Error locking vmm in read addr");
398-
399397
while !data.is_empty() {
400398
let gpa = arch::translate_gva(vcpu_fd, gva, &vmm).map_err(|e| {
401399
error!("Error {e:?} translating gva on read address: {gva:#X}");

0 commit comments

Comments
 (0)