Skip to main content

bootstrap/core/debuggers/
cdb.rs

1use std::path::PathBuf;
2
3use crate::core::config::TargetSelection;
4
5pub(crate) struct Cdb {
6    pub(crate) cdb: PathBuf,
7}
8
9/// We consult the registry to find the installed cdb.exe and try "Program Files" if that fails.
10#[cfg(windows)]
11pub(crate) fn discover_cdb(target: TargetSelection) -> Option<Cdb> {
12    if !target.ends_with("-pc-windows-msvc") {
13        return None;
14    }
15
16    let cdb_arch = if target.starts_with("i686") {
17        "x86"
18    } else if target.starts_with("x86_64") {
19        "x64"
20    } else if target.starts_with("aarch64") || target.starts_with("arm64") {
21        "arm64"
22    } else if target.starts_with("arm") || target.starts_with("thumb") {
23        "arm"
24    } else {
25        return None; // No compatible CDB.exe in the Windows 10 SDK
26    };
27
28    let path = discover_cdb_registry(cdb_arch).or_else(|| discover_cdb_program_files(cdb_arch))?;
29    Some(Cdb { cdb: path })
30}
31
32#[cfg(not(windows))]
33pub(crate) fn discover_cdb(_target: TargetSelection) -> Option<Cdb> {
34    None
35}
36
37#[cfg(windows)]
38fn discover_cdb_registry(cdb_arch: &'static str) -> Option<PathBuf> {
39    use windows_registry::LOCAL_MACHINE;
40    let roots = LOCAL_MACHINE.open(r"SOFTWARE\Microsoft\Windows Kits\Installed Roots").ok()?;
41    // "KitsRoot10" is used by both the Windows 10 and 11 SDKs.
42    let mut path: PathBuf = roots.get_string("KitsRoot10").ok()?.into();
43    path.extend([r"Debuggers", cdb_arch, r"cdb.exe"]);
44    path.exists().then_some(path)
45}
46
47#[cfg(windows)]
48fn discover_cdb_program_files(cdb_arch: &'static str) -> Option<PathBuf> {
49    let mut path = PathBuf::from(
50        std::env::var_os("ProgramFiles(x86)").or_else(|| std::env::var_os("ProgramFiles"))?,
51    );
52    path.extend([r"Windows Kits\10\Debuggers", cdb_arch, r"cdb.exe"]);
53    path.exists().then_some(path)
54}