Skip to content

Commit

Permalink
feat(gdb): Support config over api
Browse files Browse the repository at this point in the history
Allow a GDB debugging session to be started over API

Signed-off-by: Jack Thomson <[email protected]>
  • Loading branch information
JackThomson2 committed Oct 22, 2024
1 parent e2c787f commit 249596d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 20 deletions.
25 changes: 18 additions & 7 deletions docs/gdb-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ Firecracker supports debugging the guest kernel via GDB remote serial protocol.
This allows us to connect GDB to the firecracker process and step through debug
the guest kernel.

The GDB feature requires Firecracker to be booted with a config file.

## Prerequisites

Firstly, to enable GDB debugging we need to compile Firecracker with the `gdb`
Expand All @@ -25,22 +23,35 @@ debugging to work. The key config options to enable are:

```
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_DEBUG_INFO=y
```

For GDB debugging the `gdb-socket` option should be set in your config file. In
this example we set it to `/tmp/gdb.socket`
For GDB debugging the `gdb_socket_address` option under `machine-config` should
be set. When using the API the socket address must be set before instance start.

In this example we set the address to `/tmp/gdb.socket` in the config file:

```
{
...
"gdb-socket": "/tmp/gdb.socket"
"machine-config": {
...
"gdb_socket_address": "/tmp/gdb.socket"
...
}
...
}
```

Using the API the socket address can be configured before boot like so:

```
sudo curl -X PATCH --unix-socket "${API_SOCKET}" \
--data "{
\"gdb_socket_address\": \"/tmp/gdb.socket\"
}" "http://localhost/machine-config"
```

## Starting Firecracker with GDB

With all the prerequisites in place you can now start firecracker ready to
Expand Down
2 changes: 1 addition & 1 deletion src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ pub fn build_microvm_for_boot(
let vmm = Arc::new(Mutex::new(vmm));

#[cfg(feature = "gdb")]
if let Some(gdb_socket_addr) = &vm_resources.gdb_socket_addr {
if let Some(gdb_socket_addr) = &vm_resources.vm_config.gdb_socket_address {
gdb::gdb_thread(vmm.clone(), vcpu_fds, gdb_rx, entry_addr, gdb_socket_addr)
.map_err(GdbServer)?;
} else {
Expand Down
2 changes: 2 additions & 0 deletions src/vmm/src/persist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ pub fn restore_from_snapshot(
cpu_template: Some(microvm_state.vm_info.cpu_template),
track_dirty_pages: Some(track_dirty_pages),
huge_pages: Some(microvm_state.vm_info.huge_pages),
#[cfg(feature = "gdb")]
gdb_socket_address: None,
})
.map_err(BuildMicrovmFromSnapshotError::VmUpdateConfig)?;

Expand Down
12 changes: 0 additions & 12 deletions src/vmm/src/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,6 @@ pub struct VmmConfig {
vsock_device: Option<VsockDeviceConfig>,
#[serde(rename = "entropy")]
entropy_device: Option<EntropyDeviceConfig>,
#[cfg(feature = "gdb")]
#[serde(rename = "gdb-socket")]
gdb_socket_addr: Option<String>,
}

/// A data structure that encapsulates the device configurations
Expand Down Expand Up @@ -117,9 +114,6 @@ pub struct VmResources {
pub mmds_size_limit: usize,
/// Whether or not to load boot timer device.
pub boot_timer: bool,
#[cfg(feature = "gdb")]
/// Configures the location of the GDB socket
pub gdb_socket_addr: Option<String>,
}

impl VmResources {
Expand All @@ -142,8 +136,6 @@ impl VmResources {

let mut resources: Self = Self {
mmds_size_limit,
#[cfg(feature = "gdb")]
gdb_socket_addr: vmm_config.gdb_socket_addr,
..Default::default()
};
if let Some(machine_config) = vmm_config.machine_config {
Expand Down Expand Up @@ -529,8 +521,6 @@ impl From<&VmResources> for VmmConfig {
net_devices: resources.net_builder.configs(),
vsock_device: resources.vsock.config(),
entropy_device: resources.entropy.config(),
#[cfg(feature = "gdb")]
gdb_socket_addr: resources.gdb_socket_addr.clone(),
}
}
}
Expand Down Expand Up @@ -640,8 +630,6 @@ mod tests {
boot_timer: false,
mmds_size_limit: HTTP_MAX_PAYLOAD_SIZE,
entropy: Default::default(),
#[cfg(feature = "gdb")]
gdb_socket_addr: None,
}
}

Expand Down
19 changes: 19 additions & 0 deletions src/vmm/src/vmm_config/machine_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ pub struct MachineConfig {
/// Configures what page size Firecracker should use to back guest memory.
#[serde(default)]
pub huge_pages: HugePageConfig,
/// GDB socket address.
#[cfg(feature = "gdb")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub gdb_socket_address: Option<String>,
}

impl Default for MachineConfig {
Expand Down Expand Up @@ -146,6 +150,10 @@ pub struct MachineConfigUpdate {
/// Configures what page size Firecracker should use to back guest memory.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub huge_pages: Option<HugePageConfig>,
/// GDB socket address.
#[cfg(feature = "gdb")]
#[serde(default, skip_serializing_if = "Option::is_none")]
pub gdb_socket_address: Option<String>,
}

impl MachineConfigUpdate {
Expand All @@ -166,6 +174,8 @@ impl From<MachineConfig> for MachineConfigUpdate {
cpu_template: cfg.cpu_template,
track_dirty_pages: Some(cfg.track_dirty_pages),
huge_pages: Some(cfg.huge_pages),
#[cfg(feature = "gdb")]
gdb_socket_address: cfg.gdb_socket_address,
}
}
}
Expand All @@ -185,6 +195,9 @@ pub struct VmConfig {
pub track_dirty_pages: bool,
/// Configures what page size Firecracker should use to back guest memory.
pub huge_pages: HugePageConfig,
/// GDB socket address.
#[cfg(feature = "gdb")]
pub gdb_socket_address: Option<String>,
}

impl VmConfig {
Expand Down Expand Up @@ -238,6 +251,8 @@ impl VmConfig {
cpu_template,
track_dirty_pages: update.track_dirty_pages.unwrap_or(self.track_dirty_pages),
huge_pages: page_config,
#[cfg(feature = "gdb")]
gdb_socket_address: update.gdb_socket_address.clone(),
})
}
}
Expand All @@ -251,6 +266,8 @@ impl Default for VmConfig {
cpu_template: None,
track_dirty_pages: false,
huge_pages: HugePageConfig::None,
#[cfg(feature = "gdb")]
gdb_socket_address: None,
}
}
}
Expand All @@ -264,6 +281,8 @@ impl From<&VmConfig> for MachineConfig {
cpu_template: value.cpu_template.as_ref().map(|template| template.into()),
track_dirty_pages: value.track_dirty_pages,
huge_pages: value.huge_pages,
#[cfg(feature = "gdb")]
gdb_socket_address: value.gdb_socket_address.clone(),
}
}
}

0 comments on commit 249596d

Please sign in to comment.