lldb.rs

  1use std::{collections::HashMap, ffi::OsStr, path::PathBuf};
  2
  3use anyhow::Result;
  4use async_trait::async_trait;
  5use gpui::AsyncApp;
  6use sysinfo::{Pid, Process};
  7use task::{DebugAdapterConfig, DebugRequestType};
  8
  9use crate::*;
 10
 11pub(crate) struct LldbDebugAdapter {}
 12
 13impl LldbDebugAdapter {
 14    const ADAPTER_NAME: &'static str = "lldb";
 15
 16    pub(crate) fn new() -> Self {
 17        LldbDebugAdapter {}
 18    }
 19
 20    pub fn attach_processes(processes: &HashMap<Pid, Process>) -> Vec<(&Pid, &Process)> {
 21        processes.iter().collect::<Vec<_>>()
 22    }
 23}
 24
 25#[async_trait(?Send)]
 26impl DebugAdapter for LldbDebugAdapter {
 27    fn name(&self) -> DebugAdapterName {
 28        DebugAdapterName(Self::ADAPTER_NAME.into())
 29    }
 30
 31    async fn get_binary(
 32        &self,
 33        delegate: &dyn DapDelegate,
 34        config: &DebugAdapterConfig,
 35        user_installed_path: Option<PathBuf>,
 36        _: &mut AsyncApp,
 37    ) -> Result<DebugAdapterBinary> {
 38        let lldb_dap_path = if let Some(user_installed_path) = user_installed_path {
 39            user_installed_path.to_string_lossy().into()
 40        } else if cfg!(target_os = "macos") {
 41            util::command::new_smol_command("xcrun")
 42                .args(&["-f", "lldb-dap"])
 43                .output()
 44                .await
 45                .ok()
 46                .and_then(|output| String::from_utf8(output.stdout).ok())
 47                .map(|path| path.trim().to_string())
 48                .ok_or(anyhow!("Failed to find lldb-dap in user's path"))?
 49        } else {
 50            delegate
 51                .which(OsStr::new("lldb-dap"))
 52                .and_then(|p| p.to_str().map(|s| s.to_string()))
 53                .ok_or(anyhow!("Could not find lldb-dap in path"))?
 54        };
 55
 56        Ok(DebugAdapterBinary {
 57            command: lldb_dap_path,
 58            arguments: None,
 59            envs: None,
 60            cwd: config.cwd.clone(),
 61            connection: None,
 62        })
 63    }
 64
 65    async fn install_binary(
 66        &self,
 67        _version: AdapterVersion,
 68        _delegate: &dyn DapDelegate,
 69    ) -> Result<()> {
 70        unimplemented!("LLDB debug adapter cannot be installed by Zed (yet)")
 71    }
 72
 73    async fn fetch_latest_adapter_version(&self, _: &dyn DapDelegate) -> Result<AdapterVersion> {
 74        unimplemented!("Fetch latest adapter version not implemented for lldb (yet)")
 75    }
 76
 77    async fn get_installed_binary(
 78        &self,
 79        _: &dyn DapDelegate,
 80        _: &DebugAdapterConfig,
 81        _: Option<PathBuf>,
 82        _: &mut AsyncApp,
 83    ) -> Result<DebugAdapterBinary> {
 84        unimplemented!("LLDB debug adapter cannot be installed by Zed (yet)")
 85    }
 86
 87    fn request_args(&self, config: &DebugAdapterConfig) -> Value {
 88        let pid = if let DebugRequestType::Attach(attach_config) = &config.request {
 89            attach_config.process_id
 90        } else {
 91            None
 92        };
 93
 94        json!({
 95            "program": config.program,
 96            "request": match config.request {
 97                DebugRequestType::Launch => "launch",
 98                DebugRequestType::Attach(_) => "attach",
 99            },
100            "pid": pid,
101            "cwd": config.cwd,
102        })
103    }
104}