gdb.rs

  1use std::ffi::OsStr;
  2
  3use anyhow::{Result, bail};
  4use async_trait::async_trait;
  5use gpui::AsyncApp;
  6use task::{DebugAdapterConfig, DebugRequestType, DebugTaskDefinition};
  7
  8use crate::*;
  9
 10#[derive(Default)]
 11pub(crate) struct GdbDebugAdapter;
 12
 13impl GdbDebugAdapter {
 14    const ADAPTER_NAME: &'static str = "GDB";
 15}
 16
 17#[async_trait(?Send)]
 18impl DebugAdapter for GdbDebugAdapter {
 19    fn name(&self) -> DebugAdapterName {
 20        DebugAdapterName(Self::ADAPTER_NAME.into())
 21    }
 22
 23    async fn get_binary(
 24        &self,
 25        delegate: &dyn DapDelegate,
 26        _: &DebugAdapterConfig,
 27        user_installed_path: Option<std::path::PathBuf>,
 28        _: &mut AsyncApp,
 29    ) -> Result<DebugAdapterBinary> {
 30        let user_setting_path = user_installed_path
 31            .filter(|p| p.exists())
 32            .and_then(|p| p.to_str().map(|s| s.to_string()));
 33
 34        let gdb_path = delegate
 35            .which(OsStr::new("gdb"))
 36            .and_then(|p| p.to_str().map(|s| s.to_string()))
 37            .ok_or(anyhow!("Could not find gdb in path"));
 38
 39        if gdb_path.is_err() && user_setting_path.is_none() {
 40            bail!("Could not find gdb path or it's not installed");
 41        }
 42
 43        let gdb_path = user_setting_path.unwrap_or(gdb_path?);
 44
 45        Ok(DebugAdapterBinary {
 46            command: gdb_path,
 47            arguments: Some(vec!["-i=dap".into()]),
 48            envs: None,
 49            cwd: None,
 50            connection: None,
 51        })
 52    }
 53
 54    async fn install_binary(
 55        &self,
 56        _version: AdapterVersion,
 57        _delegate: &dyn DapDelegate,
 58    ) -> Result<()> {
 59        unimplemented!("GDB debug adapter cannot be installed by Zed (yet)")
 60    }
 61
 62    async fn fetch_latest_adapter_version(&self, _: &dyn DapDelegate) -> Result<AdapterVersion> {
 63        unimplemented!("Fetch latest GDB version not implemented (yet)")
 64    }
 65
 66    async fn get_installed_binary(
 67        &self,
 68        _: &dyn DapDelegate,
 69        _: &DebugAdapterConfig,
 70        _: Option<std::path::PathBuf>,
 71        _: &mut AsyncApp,
 72    ) -> Result<DebugAdapterBinary> {
 73        unimplemented!("GDB cannot be installed by Zed (yet)")
 74    }
 75
 76    fn request_args(&self, config: &DebugTaskDefinition) -> Value {
 77        let mut args = json!({
 78            "request": match config.request {
 79                DebugRequestType::Launch(_) => "launch",
 80                DebugRequestType::Attach(_) => "attach",
 81            },
 82        });
 83
 84        let map = args.as_object_mut().unwrap();
 85        match &config.request {
 86            DebugRequestType::Attach(attach) => {
 87                map.insert("pid".into(), attach.process_id.into());
 88            }
 89
 90            DebugRequestType::Launch(launch) => {
 91                map.insert("program".into(), launch.program.clone().into());
 92
 93                if !launch.args.is_empty() {
 94                    map.insert("args".into(), launch.args.clone().into());
 95                }
 96
 97                if let Some(stop_on_entry) = config.stop_on_entry {
 98                    map.insert(
 99                        "stopAtBeginningOfMainSubprogram".into(),
100                        stop_on_entry.into(),
101                    );
102                }
103                if let Some(cwd) = launch.cwd.as_ref() {
104                    map.insert("cwd".into(), cwd.to_string_lossy().into_owned().into());
105                }
106            }
107        }
108        args
109    }
110}