1use crate::Result;
2use color_eyre::eyre::WrapErr;
3use std::{
4 path::Path,
5 process::{Command, ExitStatus},
6};
7
8#[tracing::instrument(level = "debug")]
9pub fn run_gdb(binary: &Path, gdb_port: u16) -> Result<ExitStatus> {
10 let gdb_path = wheres_gdb().context("failed to find gdb executable")?;
11 tracing::info!("Found {}", gdb_path);
12 let mut gdb = Command::new(gdb_path);
13
14 gdb.arg("-ex").arg(format!("file {}", binary.display()));
20 gdb.arg("-ex").arg(format!("target remote :{gdb_port}"));
21
22 gdb.arg("-ex").arg("tbreak mycelium_kernel::kernel_main");
26 gdb.arg("-ex").arg("continue");
27
28 tracing::info!("Running {gdb:?}");
29 let status = gdb.status().context("failed to run gdb")?;
31
32 tracing::debug!("gdb exited with status {:?}", status);
33 Ok(status)
34}
35
36fn wheres_gdb() -> Result<String> {
37 let output = Command::new("which")
38 .arg("rust-gdb")
39 .output()
40 .context("running `which rust-gdb` failed")?;
41 let mut which_gdb =
42 String::from_utf8(output.stdout).context("`which rust-gdb` output was not a string")?;
43 which_gdb.truncate(which_gdb.trim_end().len());
44 if which_gdb.ends_with("not found") {
45 return Ok(String::from("gdb"));
46 }
47
48 Ok(which_gdb)
49}