debug/
main.rs

1use clap::Parser;
2use gdb::{TwizzlerConn, TwizzlerGdb, TwizzlerTarget};
3use gdbstub::stub::GdbStub;
4use miette::IntoDiagnostic;
5use monitor_api::{CompartmentLoader, NewCompartmentFlags};
6
7mod gdb;
8
9#[derive(clap::Subcommand, Clone, Debug)]
10enum Commands {
11    #[clap(about = "Run a program and debug it.")]
12    Run(RunCli),
13    #[clap(about = "Attach to an existing compartment.")]
14    Attach,
15}
16
17#[derive(clap::Args, Clone, Debug)]
18struct RunCli {
19    #[arg(trailing_var_arg = true, allow_hyphen_values = true, hide = true)]
20    cmdline: Vec<String>,
21}
22
23#[derive(clap::Parser, Clone, Debug)]
24#[clap(name = "debug", author = "Daniel Bittman <danielbittman1@gmail.com>", version = "1.0", about = "Debugger stub for Twizzler", long_about = None)]
25struct Cli {
26    #[clap(subcommand)]
27    cmd: Commands,
28}
29
30fn main() -> miette::Result<()> {
31    tracing::subscriber::set_global_default(
32        tracing_subscriber::fmt::fmt()
33            .with_max_level(tracing::Level::INFO)
34            .without_time()
35            .finish(),
36    )
37    .into_diagnostic()?;
38    tracing_log::LogTracer::init().into_diagnostic()?;
39
40    let cli = Cli::parse();
41
42    unsafe { std::env::set_var("MONDEBUG", "1") };
43    match cli.cmd {
44        Commands::Run(run_cli) => {
45            run_debug_program(&run_cli)?;
46        }
47        Commands::Attach => todo!(),
48    }
49
50    Ok(())
51}
52
53fn run_debug_program(run_cli: &RunCli) -> miette::Result<()> {
54    let name = &run_cli.cmdline[0];
55    let compname = format!("debug-{}", name);
56
57    let mut comp = CompartmentLoader::new(&compname, name, NewCompartmentFlags::DEBUG);
58    comp.args(&run_cli.cmdline);
59    let comp = comp.load().into_diagnostic()?;
60
61    tracing::info!(
62        "compartment {} loaded, starting debugging monitor",
63        compname
64    );
65    let (send, recv) = std::sync::mpsc::channel();
66    let gdb = GdbStub::new(TwizzlerConn::new(recv));
67    let mut target = TwizzlerTarget::new(comp, send);
68    let r = gdb
69        .run_blocking::<TwizzlerGdb>(&mut target)
70        .into_diagnostic()?;
71
72    tracing::info!("disconnected {}: {:?}", compname, r);
73    Ok(())
74}