#![warn(clippy::all)]
use std::fs;
use std::path::{Path, PathBuf};
use object::Object;
use samply_symbols::object;
use uuid::Uuid;
#[cfg(target_os = "macos")]
pub use crate::moria_mac_spotlight::locate_dsym_using_spotlight;
#[cfg(not(target_os = "macos"))]
pub fn locate_dsym_using_spotlight(_uuid: uuid::Uuid) -> Result<PathBuf, &'static str> {
Err("Could not locate dSYM")
}
pub fn locate_dsym_fastpath(path: &Path, uuid: Uuid) -> Option<PathBuf> {
let path = path.canonicalize().ok()?;
let mut dsym = path.file_name()?.to_owned();
dsym.push(".dSYM");
let dsym_dir = path.with_file_name(&dsym);
if let Some(f) = try_match_dsym(&dsym_dir, uuid) {
return Some(f);
}
let mut target_channel_dir = &*path;
loop {
let parent = target_channel_dir.parent()?;
target_channel_dir = parent;
if target_channel_dir.parent().and_then(Path::file_name)
== Some(std::ffi::OsStr::new("target"))
{
break; }
}
let deps_dir = target_channel_dir.join("deps");
let examples_dir = target_channel_dir.join("examples");
try_match_dsym_in_dir(&deps_dir, uuid).or_else(|| try_match_dsym_in_dir(&examples_dir, uuid))
}
fn try_match_dsym_in_dir(dir: &Path, uuid: Uuid) -> Option<PathBuf> {
for entry in fs::read_dir(dir).ok()? {
let item = entry.ok()?.path();
if item.extension() != Some(std::ffi::OsStr::new("dSYM")) {
continue;
}
if let Some(debug_file_name) = try_match_dsym(&item, uuid) {
return Some(debug_file_name);
}
}
None
}
fn try_match_dsym(dsym_dir: &Path, uuid: Uuid) -> Option<PathBuf> {
let mut dir_iter = fs::read_dir(dsym_dir.join("Contents/Resources/DWARF")).ok()?;
let debug_file_name = dir_iter.next()?.ok()?.path();
if dir_iter.next().is_some() {
return None; }
let file = fs::read(&debug_file_name).ok()?;
let dsym = object::File::parse(&file[..]).ok()?;
if dsym.mach_uuid() == Ok(Some(*uuid.as_bytes())) {
Some(debug_file_name)
} else {
None
}
}