diff --git a/Cargo.toml b/Cargo.toml index 24b9ff697..1b5300cf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backtrace" -version = "0.3.44" +version = "0.3.45" authors = ["The Rust Project Developers"] license = "MIT/Apache-2.0" readme = "README.md" @@ -21,7 +21,7 @@ exclude = ['crates/without_debuginfo'] [dependencies] cfg-if = "0.1.10" rustc-demangle = "0.1.4" -backtrace-sys = { path = "crates/backtrace-sys", version = "0.1.32", optional = true } +backtrace-sys = { path = "crates/backtrace-sys", version = "0.1.33", optional = true, default_features = false } libc = { version = "0.2.45", default-features = false } core = { version = "1.0.0", optional = true, package = 'rustc-std-workspace-core' } compiler_builtins = { version = '0.1.2', optional = true } @@ -37,7 +37,7 @@ cpp_demangle = { default-features = false, version = "0.2.3", optional = true } addr2line = { version = "0.11.0", optional = true, default-features = false, features = ['std'] } findshlibs = { version = "0.5.0", optional = true } memmap = { version = "0.7.0", optional = true } -goblin = { version = "0.1.3", optional = true, default-features = false, features = ['elf32', 'elf64', 'mach32', 'mach64', 'pe32', 'pe64', 'std'] } +goblin = { version = "0.2", optional = true, default-features = false, features = ['elf32', 'elf64', 'mach32', 'mach64', 'pe32', 'pe64', 'std'] } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.3", optional = true } @@ -94,7 +94,7 @@ kernel32 = [] # the moment, this is only possible when targetting Linux, since macOS # splits DWARF out into a separate object file. Enabling this feature # means one less C dependency. -libbacktrace = ["backtrace-sys"] +libbacktrace = ["backtrace-sys/backtrace-sys"] dladdr = [] coresymbolication = [] gimli-symbolize = ["addr2line", "findshlibs", "memmap", "goblin"] diff --git a/crates/backtrace-sys/Cargo.toml b/crates/backtrace-sys/Cargo.toml index 5245d6b1f..5ed8b1930 100644 --- a/crates/backtrace-sys/Cargo.toml +++ b/crates/backtrace-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "backtrace-sys" -version = "0.1.32" +version = "0.1.33" authors = ["Alex Crichton "] build = "build.rs" license = "MIT/Apache-2.0" @@ -20,4 +20,8 @@ compiler_builtins = { version = '0.1.2', optional = true } cc = "1.0.37" [features] +default = ["backtrace-sys"] + +# Without this feature, this crate does nothing. +backtrace-sys = [] rustc-dep-of-std = ['core', 'compiler_builtins'] diff --git a/crates/backtrace-sys/build.rs b/crates/backtrace-sys/build.rs index 98ab6be05..564f23a91 100644 --- a/crates/backtrace-sys/build.rs +++ b/crates/backtrace-sys/build.rs @@ -7,7 +7,8 @@ use std::path::PathBuf; fn main() { let target = env::var("TARGET").unwrap(); - if target.contains("msvc") || // libbacktrace isn't used on MSVC windows + if !cfg!(feature = "backtrace-sys") || // without this feature, this crate does nothing + target.contains("msvc") || // libbacktrace isn't used on MSVC windows target.contains("emscripten") || // no way this will ever compile for emscripten target.contains("cloudabi") || target.contains("hermit") || @@ -30,10 +31,17 @@ fn main() { .file("src/libbacktrace/dwarf.c") .file("src/libbacktrace/fileline.c") .file("src/libbacktrace/posix.c") - .file("src/libbacktrace/read.c") .file("src/libbacktrace/sort.c") .file("src/libbacktrace/state.c"); + // `mmap` does not exist on Windows, so we use + // the less efficient `read`-based code. + if target.contains("windows") { + build.file("src/libbacktrace/read.c"); + } else { + build.file("src/libbacktrace/mmapio.c"); + } + // No need to have any symbols reexported form shared objects build.flag("-fvisibility=hidden"); diff --git a/src/symbolize/gimli.rs b/src/symbolize/gimli.rs index 1529a90a0..03124a350 100644 --- a/src/symbolize/gimli.rs +++ b/src/symbolize/gimli.rs @@ -158,6 +158,7 @@ cfg_if::cfg_if! { struct Object<'a> { macho: MachO<'a>, dwarf: Option, + syms: Vec<(&'a str, u64)>, } impl<'a> Object<'a> { @@ -171,7 +172,16 @@ cfg_if::cfg_if! { .enumerate() .find(|(_, segment)| segment.name().ok() == Some("__DWARF")) .map(|p| p.0); - Some(Object { macho, dwarf }) + let mut syms = Vec::new(); + if let Some(s) = &macho.symbols { + syms = s.iter() + .filter_map(|e| e.ok()) + .filter(|(name, nlist)| name.len() > 0 && !nlist.is_undefined()) + .map(|(name, nlist)| (name, nlist.n_value)) + .collect(); + } + syms.sort_unstable_by_key(|(_, addr)| *addr); + Some(Object { macho, dwarf, syms }) } fn section(&self, name: &str) -> Option<&'a [u8]> { @@ -194,12 +204,13 @@ cfg_if::cfg_if! { .map(|p| p.1) } - fn search_symtab<'b>(&'b self, _addr: u64) -> Option<&'b [u8]> { - // So far it seems that we don't need to implement this. Maybe - // `dladdr` on OSX has us covered? Maybe there's not much in the - // symbol table? In any case our relevant tests are passing - // without this being implemented, so let's skip it for now. - None + fn search_symtab<'b>(&'b self, addr: u64) -> Option<&'b [u8]> { + let i = match self.syms.binary_search_by_key(&addr, |(_, addr)| *addr) { + Ok(i) => i, + Err(i) => i.checked_sub(1)?, + }; + let (sym, _addr) = self.syms.get(i)?; + Some(sym.as_bytes()) } } } else {