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 id =
58 twizzler_rt_abi::fd::twz_rt_resolve_name(Default::default(), name).into_diagnostic()?;
59 let mut comp = CompartmentLoader::new(&compname, name, id, NewCompartmentFlags::DEBUG);
60 comp.args(&run_cli.cmdline);
61 let comp = comp.load().into_diagnostic()?;
62
63 tracing::info!(
64 "compartment {} loaded, starting debugging monitor",
65 compname
66 );
67 let (send, recv) = std::sync::mpsc::channel();
68 let gdb = GdbStub::new(TwizzlerConn::new(recv));
69 let mut target = TwizzlerTarget::new(comp, send);
70 let r = gdb
71 .run_blocking::<TwizzlerGdb>(&mut target)
72 .into_diagnostic()?;
73
74 tracing::info!("disconnected {}: {:?}", compname, r);
75 Ok(())
76}
77
78#[test]
79fn test1() {
80 twizzler_abi::klog_println!("IN TEST 1");
81}
82