Skip to content

Commit

Permalink
Libify (#356)
Browse files Browse the repository at this point in the history
This PR makes changes so that this crate it can be used as a library (eg rust-minidump/minidump-writer#21 (comment)).

- Replaced `failure` with `anyhow`. `failure` has been [unmaintained](https://rustsec.org/advisories/RUSTSEC-2020-0036.html) for several years, `anyhow` is one of the maintained alternatives. This change is intended as temporary, as IMO the errors in this crate should use `thiserror`, or just manually defined errors, as it makes library usage easier by not using string errors for everything, but made sense for a binary application.
- Places `clap` and `simplelog` behind a `cli` feature flag, these dependencies are only used when used as a binary, crates that depend on this as a library don't need them and thus should not compile them. To preserve backwards compatibility for `cargo install` this feature is made default, so library users will need to explicitly opt-out.
- Places HTTP symbol retrieval behind the `http` feature. This removes several heavy dependencies only used for retrieving symbols from remote symbol stores, in the use case that motivated this PR linked above, this functionality is not needed and only adds compile time for no benefit. Again, this feature is enabled by default for backwards compatibility.
- Replaces `reqwest`'s use of native-tls with `rustls`, simplifying the build when `http` is enabled. I frankly despise OpenSSL and all of the aggravating problems that come with it, `rustls` is a drop-in replacement that completely avoids all of those aggravations. This change is obviously due to my personal bias, I can back it out if requested.

Resolves: #253
  • Loading branch information
Jake-Shadle authored May 3, 2022
1 parent c558ad1 commit 31b9536
Show file tree
Hide file tree
Showing 14 changed files with 398 additions and 442 deletions.
317 changes: 94 additions & 223 deletions Cargo.lock

Large diffs are not rendered by default.

37 changes: 24 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,49 @@ description = "Dump debug symbols into Breakpad ones"
edition = "2018"
license = "MIT/Apache-2.0"

[[bin]]
name = "dump_syms"
required-features = ["cli"]

[features]
default = ["cli", "http"]
# Feature needed when building the dump_syms executable
cli = ["clap", "simplelog"]
# Feature for allowing retrieval of symbols via HTTP
http = ["reqwest", "futures", "tokio"]

[dependencies]
anyhow = "1.0"
bitflags = "1.3"
cab = "0.2"
clap = "2.33"
clap = { version = "2.33", optional = true }
crossbeam = "0.8.1"
dirs = "3.0"
failure = "0.1"
futures = "0.3"
futures = { version = "0.3", optional = true }
goblin = "0.5.1" # Keep in sync with symbolic-debuginfo
hashbrown = { version = "0.11", features = ["serde"] }
lazy_static = "1.4"
log = "0.4"
num_cpus = "1.13"
pdb = "0.7"
regex = "1.4"
reqwest = { version = "0.11", features = ["blocking"] }
reqwest = { version = "0.11", optional = true, default-features = false, features = [
"blocking",
"rustls-tls",
] }
serde = "1.0"
serde_json = "1.0"
sha2 = "0.9"
simplelog = "0.10"
simplelog = { version = "0.10", optional = true }
symbolic = { version = "8", features = ["demangle", "minidump"] }
tokio = "1.8"
tokio = { version = "1.8", optional = true }
url = "2.2"
uuid = "0.8"

[dev-dependencies]
reqwest = { version = "0.11", default-features = false, features = [
"blocking",
"rustls-tls",
] }
fxhash = "0.2"
tempfile = "3"

[features]
vendored-openssl = ["openssl/vendored"]

[dependencies.openssl]
version = "0.10"
optional = true
31 changes: 13 additions & 18 deletions src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@

use std::path::PathBuf;

use crate::common::{self, FileType};
use crate::linux::elf::ElfInfo;
use crate::mac::macho::MachoInfo;
use crate::utils;
use crate::windows::pdb::PDBInfo;
use dump_syms::common::{self, FileType};
use dump_syms::linux::elf::ElfInfo;
use dump_syms::mac::macho::MachoInfo;
use dump_syms::utils;
use dump_syms::windows::pdb::PDBInfo;

use super::dumper::{self, Config};
use dump_syms::dumper::{self, Config};

#[allow(clippy::large_enum_variant)]
pub(crate) enum Action<'a> {
Dump(Config<'a>),
ListArch,
Expand Down Expand Up @@ -82,9 +83,8 @@ mod tests {
copy(basic64, &tmp_file).unwrap();

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.clone().into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down Expand Up @@ -116,9 +116,8 @@ mod tests {
copy(basic64, &tmp_file).unwrap();

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down Expand Up @@ -148,9 +147,8 @@ mod tests {
copy(basic64_dll, &tmp_dll).unwrap();

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.clone().into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down Expand Up @@ -179,9 +177,8 @@ mod tests {
let tmp_out = tmp_dir.path().join("output.sym");

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.clone().into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down Expand Up @@ -214,9 +211,8 @@ mod tests {
let tmp_out = tmp_dir.path().join("output.sym");

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.clone().into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down Expand Up @@ -256,9 +252,8 @@ mod tests {
let tmp_out = tmp_dir.path().join("output.sym");

let action = Action::Dump(Config {
output: tmp_out.to_str().unwrap(),
output: tmp_out.clone().into(),
symbol_server: None,
store: None,
debug_id: None,
code_id: None,
arch: common::get_compile_time_arch(),
Expand Down
30 changes: 2 additions & 28 deletions src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ struct Job {

impl Job {
fn new(cache: Option<PathBuf>, url: String) -> common::Result<Self> {
if Url::parse(&url).is_err() {
return Err(From::from(format!("Invalid url: {}", url)));
}
anyhow::ensure!(Url::parse(&url).is_ok(), "Invalid url: {}", url);
Ok(Self { cache, url })
}
}
Expand Down Expand Up @@ -150,30 +148,6 @@ fn copy_in_cache(path: Option<PathBuf>, data: &[u8]) -> bool {
true
}

fn get_base(file_name: &str) -> PathBuf {
// The file is stored at cache/xul.pdb/DEBUG_ID/xul.pd_
// the xul.pdb represents the base
let path = PathBuf::from(file_name);
if let Some(e) = path.extension() {
let e = e.to_str().unwrap().to_lowercase();
match e.as_str() {
"pd_" => path.with_extension("pdb"),
"ex_" => path.with_extension("exe"),
"dl_" => path.with_extension("dll"),
_ => path.clone(),
}
} else {
path.clone()
}
}

pub fn get_path_for_sym(file_name: &str, id: &str) -> PathBuf {
let base = get_base(file_name);
let file_name = PathBuf::from(file_name);
let file_name = file_name.with_extension("sym");
base.join(id).join(file_name)
}

fn search_in_cache(
servers: &[SymbolServer],
id: &str,
Expand Down Expand Up @@ -295,7 +269,7 @@ pub fn search_file(
_ => return (None, file_name),
};

let base = get_base(&file_name);
let base = utils::get_base(&file_name);

// Start with the caches
if let Some(path) = search_in_cache(servers, id, &base, &file_name) {
Expand Down
26 changes: 14 additions & 12 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@

use regex::Regex;
use std::env::consts::ARCH;
use std::error;
use std::io::Write;
use std::result;
use symbolic::common::{Arch, Name};
use symbolic::debuginfo::{peek, FileFormat};

type Error = Box<dyn error::Error + std::marker::Send + std::marker::Sync>;
pub type Result<T> = result::Result<T, Error>;
pub type Result<T> = result::Result<T, anyhow::Error>;

pub(crate) enum FileType {
pub enum FileType {
Pdb,
Pe,
Elf,
Expand All @@ -23,7 +21,7 @@ pub(crate) enum FileType {
}

impl FileType {
pub(crate) fn from_buf(buf: &[u8]) -> Self {
pub fn from_buf(buf: &[u8]) -> Self {
match peek(buf, true /* check for fat binary */) {
FileFormat::Pdb => Self::Pdb,
FileFormat::Pe => Self::Pe,
Expand All @@ -32,26 +30,30 @@ impl FileType {
_ => Self::Unknown,
}
}
}

impl std::str::FromStr for FileType {
type Err = std::convert::Infallible;

pub(crate) fn from_str(s: &str) -> Self {
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
let s = s.to_lowercase();
match s.as_str() {
Ok(match s.as_str() {
"pdb" => Self::Pdb,
"elf" => Self::Elf,
"macho" => Self::Macho,
_ => Self::Unknown,
}
})
}
}

pub(crate) trait Dumpable {
pub trait Dumpable {
fn dump<W: Write>(&self, writer: W) -> Result<()>;
fn get_name(&self) -> &str;
fn get_debug_id(&self) -> &str;
fn has_stack(&self) -> bool;
}

pub(crate) trait Mergeable {
pub trait Mergeable {
fn merge(left: Self, right: Self) -> Result<Self>
where
Self: Sized;
Expand All @@ -61,7 +63,7 @@ pub(crate) trait LineFinalizer<M> {
fn finalize(&mut self, sym_rva: u32, sym_len: u32, map: &M);
}

pub(crate) fn get_compile_time_arch() -> &'static str {
pub fn get_compile_time_arch() -> &'static str {
use Arch::*;

match ARCH {
Expand All @@ -84,7 +86,7 @@ pub(crate) fn normalize_anonymous_namespace(text: &str) -> String {
}

pub(crate) fn fix_symbol_name<'a>(name: &'a Name<'a>) -> Name<'a> {
lazy_static! {
lazy_static::lazy_static! {
static ref LLVM_NNN: Regex = Regex::new(r"\.llvm\.[0-9]+$").unwrap();
}
let fixed = LLVM_NNN.replace(name.as_str(), "");
Expand Down
Loading

0 comments on commit 31b9536

Please sign in to comment.