Skip to content

Commit

Permalink
Merge branch 'firecracker-microvm:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
kanpov authored Nov 1, 2024
2 parents 70e70c0 + 3d0421f commit 525ea0d
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 21 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ and this project adheres to
- [#4869](https://github.com/firecracker-microvm/firecracker/pull/4869): Added
support for Aarch64 systems which feature CPU caches with a number of sets
higher than `u16::MAX`.
- [#4797](https://github.com/firecracker-microvm/firecracker/pull/4797),
[#4854](https://github.com/firecracker-microvm/firecracker/pull/4854): Added
GDB debugging support for a microVM guest kernel. Please see our
[GDB debugging documentation](docs/gdb-debugging.md) for more information.

### Changed

Expand Down
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_path` 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_path": "/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_path\": \"/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
3 changes: 3 additions & 0 deletions src/firecracker/swagger/firecracker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,9 @@ definitions:
properties:
cpu_template:
$ref: "#/definitions/CpuTemplate"
# gdb_socket_path:
# type: string
# description: Path to the GDB socket. Requires the gdb feature to be enabled.
smt:
type: boolean
description: Flag for enabling/disabling simultaneous multithreading. Can be enabled only on x86.
Expand Down
4 changes: 2 additions & 2 deletions src/vmm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ 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 {
gdb::gdb_thread(vmm.clone(), vcpu_fds, gdb_rx, entry_addr, gdb_socket_addr)
if let Some(gdb_socket_path) = &vm_resources.vm_config.gdb_socket_path {
gdb::gdb_thread(vmm.clone(), vcpu_fds, gdb_rx, entry_addr, gdb_socket_path)
.map_err(GdbServer)?;
} else {
debug!("No GDB socket provided not starting gdb server.");
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_path: 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_path: 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_path: 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_path: cfg.gdb_socket_path,
}
}
}
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_path: 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_path: update.gdb_socket_path.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_path: 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_path: value.gdb_socket_path.clone(),
}
}
}

0 comments on commit 525ea0d

Please sign in to comment.