Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start GDB session with API #4864

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ and this project adheres to
`VIRTIO_NET_F_RX_MRGBUF` support to the `virtio-net` device. When this feature
is negotiated, guest `virtio-net` driver can perform more efficient memory
management which in turn improves RX and TX performance.
- [#4797](https://github.com/firecracker-microvm/firecracker/pull/4797),
JackThomson2 marked this conversation as resolved.
Show resolved Hide resolved
[#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
Comment on lines -28 to -29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these really not needed anymore?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah not required with this setup

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(),
}
}
}
Loading