Skip to content

Commit

Permalink
feat(debuginfo): Add an Object type for portable pdb (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
loewenheim authored Sep 30, 2022
1 parent 7d10047 commit 282ecce
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# Changelog

## Unreleased

**Features**:

- Added an Object type for Portable PDB files. ([#696](https://github.com/getsentry/symbolic/pull/696))

## 9.2.1

**Fixes**:

- Fixed a bug in Unreal Engine log parsing by updating the `anylog` dependency. ([#695](https://github.com/getsentry/symbolic/pull/695))

## 9.2.0
Expand Down
1 change: 1 addition & 0 deletions symbolic-cfi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ impl<W: Write> AsciiCfiWriter<W> {
Object::Pe(o) => self.process_pe(o),
Object::Wasm(o) => self.process_dwarf(o, false),
Object::SourceBundle(_) => Ok(()),
Object::PortablePdb(_) => Ok(()),
}
}

Expand Down
6 changes: 5 additions & 1 deletion symbolic-debuginfo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ exclude = ["tests/**/*"]
all-features = true

[features]
default = ["breakpad", "elf", "macho", "ms", "sourcebundle", "wasm"]
default = ["breakpad", "elf", "macho", "ms", "ppdb", "sourcebundle", "wasm"]
# Breakpad text format parsing and processing
breakpad = ["nom", "nom-supreme", "regex"]
# DWARF processing.
Expand Down Expand Up @@ -58,6 +58,9 @@ ms = [
"scroll",
"smallvec",
]
ppdb = [
"symbolic-ppdb"
]
# Source bundle creation
sourcebundle = [
"lazy_static",
Expand Down Expand Up @@ -97,6 +100,7 @@ serde = { version = "1.0.94", features = ["derive"] }
serde_json = { version = "1.0.40", optional = true }
smallvec = { version = "1.2.0", optional = true }
symbolic-common = { version = "9.2.1", path = "../symbolic-common" }
symbolic-ppdb = { version = "9.2.1", path = "../symbolic-ppdb", optional = true }
thiserror = "1.0.20"
wasmparser = { version = "0.90.0", optional = true }
zip = { version = "0.6.2", optional = true, default-features = false, features = [
Expand Down
4 changes: 4 additions & 0 deletions symbolic-debuginfo/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ pub enum FileFormat {
SourceBundle,
/// WASM container.
Wasm,
/// Portable PDB
PortablePdb,
}

impl FileFormat {
Expand All @@ -182,6 +184,7 @@ impl FileFormat {
FileFormat::Pe => "pe",
FileFormat::SourceBundle => "sourcebundle",
FileFormat::Wasm => "wasm",
FileFormat::PortablePdb => "portablepdb",
}
}
}
Expand All @@ -204,6 +207,7 @@ impl FromStr for FileFormat {
"pe" => FileFormat::Pe,
"sourcebundle" => FileFormat::SourceBundle,
"wasm" => FileFormat::Wasm,
"portablepdb" => FileFormat::PortablePdb,
_ => return Err(UnknownFileFormatError),
})
}
Expand Down
3 changes: 3 additions & 0 deletions symbolic-debuginfo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ pub mod macho;
pub mod pdb;
#[cfg(feature = "ms")]
pub mod pe;
#[cfg(feature = "ppdb")]
pub mod ppdb;
#[cfg(feature = "sourcebundle")]
pub mod sourcebundle;
#[cfg(feature = "wasm")]
Expand All @@ -75,6 +77,7 @@ pub use crate::base::*;
feature = "elf",
feature = "macho",
feature = "ms",
feature = "ppdb",
feature = "sourcebundle",
feature = "wasm"
))]
Expand Down
51 changes: 51 additions & 0 deletions symbolic-debuginfo/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::error::Error;
use std::fmt;

use symbolic_common::{Arch, AsSelf, CodeId, DebugId};
use symbolic_ppdb::PortablePdb;

use crate::base::*;
use crate::breakpad::*;
Expand All @@ -13,6 +14,7 @@ use crate::elf::*;
use crate::macho::*;
use crate::pdb::*;
use crate::pe::*;
use crate::ppdb::*;
use crate::sourcebundle::*;
use crate::wasm::*;

Expand All @@ -26,6 +28,7 @@ macro_rules! match_inner {
$ty::Pe($pat) => $expr,
$ty::SourceBundle($pat) => $expr,
$ty::Wasm($pat) => $expr,
$ty::PortablePdb($pat) => $expr,
}
};
}
Expand All @@ -40,6 +43,7 @@ macro_rules! map_inner {
$from::Pe($pat) => $to::Pe($expr),
$from::SourceBundle($pat) => $to::SourceBundle($expr),
$from::Wasm($pat) => $to::Wasm($expr),
$from::PortablePdb($pat) => $to::PortablePdb($expr),
}
};
}
Expand All @@ -56,6 +60,9 @@ macro_rules! map_result {
.map($to::SourceBundle)
.map_err(ObjectError::transparent),
$from::Wasm($pat) => $expr.map($to::Wasm).map_err(ObjectError::transparent),
$from::PortablePdb($pat) => $expr
.map($to::PortablePdb)
.map_err(ObjectError::transparent),
}
};
}
Expand Down Expand Up @@ -139,6 +146,8 @@ pub fn peek(data: &[u8], archive: bool) -> FileFormat {
FileFormat::Breakpad
} else if WasmObject::test(data) {
FileFormat::Wasm
} else if PortablePdbObject::test(data) {
FileFormat::PortablePdb
} else {
let magic = goblin::mach::parse_magic_and_ctx(data, 0).map(|(magic, _)| magic);

Expand Down Expand Up @@ -183,6 +192,8 @@ pub enum Object<'data> {
SourceBundle(SourceBundle<'data>),
/// A WASM file.
Wasm(WasmObject<'data>),
/// A Portable PDB, a debug companion format for CLR languages.
PortablePdb(PortablePdbObject<'data>),
}

impl<'data> Object<'data> {
Expand Down Expand Up @@ -212,6 +223,7 @@ impl<'data> Object<'data> {
FileFormat::Pe => parse_object!(Pe, PeObject, data),
FileFormat::SourceBundle => parse_object!(SourceBundle, SourceBundle, data),
FileFormat::Wasm => parse_object!(Wasm, WasmObject, data),
FileFormat::PortablePdb => parse_object!(PortablePdb, PortablePdbObject, data),
FileFormat::Unknown => {
return Err(ObjectError::new(ObjectErrorRepr::UnsupportedObject))
}
Expand All @@ -230,6 +242,7 @@ impl<'data> Object<'data> {
Object::Pe(_) => FileFormat::Pe,
Object::SourceBundle(_) => FileFormat::SourceBundle,
Object::Wasm(_) => FileFormat::Wasm,
Object::PortablePdb(_) => FileFormat::PortablePdb,
}
}

Expand Down Expand Up @@ -328,6 +341,10 @@ impl<'data> Object<'data> {
.debug_session()
.map(ObjectDebugSession::Dwarf)
.map_err(ObjectError::transparent),
Object::PortablePdb(ref o) => o
.debug_session()
.map(ObjectDebugSession::PortablePdb)
.map_err(ObjectError::transparent),
}
}

Expand Down Expand Up @@ -431,6 +448,7 @@ pub enum ObjectDebugSession<'d> {
Pdb(PdbDebugSession<'d>),
Pe(PeDebugSession<'d>),
SourceBundle(SourceBundleDebugSession<'d>),
PortablePdb(PortablePdbDebugSession),
}

impl<'d> ObjectDebugSession<'d> {
Expand All @@ -450,6 +468,9 @@ impl<'d> ObjectDebugSession<'d> {
ObjectDebugSession::SourceBundle(ref s) => {
ObjectFunctionIterator::SourceBundle(s.functions())
}
ObjectDebugSession::PortablePdb(ref s) => {
ObjectFunctionIterator::PortablePdb(s.functions())
}
}
}

Expand All @@ -461,6 +482,7 @@ impl<'d> ObjectDebugSession<'d> {
ObjectDebugSession::Pdb(ref s) => ObjectFileIterator::Pdb(s.files()),
ObjectDebugSession::Pe(ref s) => ObjectFileIterator::Pe(s.files()),
ObjectDebugSession::SourceBundle(ref s) => ObjectFileIterator::SourceBundle(s.files()),
ObjectDebugSession::PortablePdb(ref s) => ObjectFileIterator::PortablePdb(s.files()),
}
}

Expand All @@ -484,6 +506,9 @@ impl<'d> ObjectDebugSession<'d> {
ObjectDebugSession::SourceBundle(ref s) => {
s.source_by_path(path).map_err(ObjectError::transparent)
}
ObjectDebugSession::PortablePdb(ref s) => {
s.source_by_path(path).map_err(ObjectError::transparent)
}
}
}
}
Expand Down Expand Up @@ -514,6 +539,7 @@ pub enum ObjectFunctionIterator<'s> {
Pdb(PdbFunctionIterator<'s>),
Pe(PeFunctionIterator<'s>),
SourceBundle(SourceBundleFunctionIterator<'s>),
PortablePdb(PortablePdbFunctionIterator<'s>),
}

impl<'s> Iterator for ObjectFunctionIterator<'s> {
Expand All @@ -536,6 +562,9 @@ impl<'s> Iterator for ObjectFunctionIterator<'s> {
ObjectFunctionIterator::SourceBundle(ref mut i) => {
Some(i.next()?.map_err(ObjectError::transparent))
}
ObjectFunctionIterator::PortablePdb(ref mut i) => {
Some(i.next()?.map_err(ObjectError::transparent))
}
}
}
}
Expand All @@ -549,6 +578,7 @@ pub enum ObjectFileIterator<'s> {
Pdb(PdbFileIterator<'s>),
Pe(PeFileIterator<'s>),
SourceBundle(SourceBundleFileIterator<'s>),
PortablePdb(PortablePdbFileIterator<'s>),
}

impl<'s> Iterator for ObjectFileIterator<'s> {
Expand All @@ -567,6 +597,9 @@ impl<'s> Iterator for ObjectFileIterator<'s> {
ObjectFileIterator::SourceBundle(ref mut i) => {
Some(i.next()?.map_err(ObjectError::transparent))
}
ObjectFileIterator::PortablePdb(ref mut i) => {
Some(i.next()?.map_err(ObjectError::transparent))
}
}
}
}
Expand All @@ -581,6 +614,7 @@ pub enum SymbolIterator<'data, 'object> {
Pe(PeSymbolIterator<'data, 'object>),
SourceBundle(SourceBundleSymbolIterator<'data>),
Wasm(WasmSymbolIterator<'data, 'object>),
PortablePdb(PortablePdbSymbolIterator<'data>),
}

impl<'data, 'object> Iterator for SymbolIterator<'data, 'object> {
Expand All @@ -591,6 +625,18 @@ impl<'data, 'object> Iterator for SymbolIterator<'data, 'object> {
}
}

impl<'data> crate::base::Parse<'data> for PortablePdb<'data> {
type Error = symbolic_ppdb::FormatError;

fn parse(data: &'data [u8]) -> Result<Self, Self::Error> {
Self::parse(data)
}

fn test(data: &'data [u8]) -> bool {
Self::peek(data)
}
}

#[derive(Debug)]
enum ArchiveInner<'d> {
Breakpad(MonoArchive<'d, BreakpadObject<'d>>),
Expand All @@ -600,6 +646,7 @@ enum ArchiveInner<'d> {
Pe(MonoArchive<'d, PeObject<'d>>),
SourceBundle(MonoArchive<'d, SourceBundle<'d>>),
Wasm(MonoArchive<'d, WasmObject<'d>>),
PortablePdb(MonoArchive<'d, PortablePdbObject<'d>>),
}

/// A generic archive that can contain one or more object files.
Expand Down Expand Up @@ -636,6 +683,7 @@ impl<'d> Archive<'d> {
FileFormat::Pe => Archive(ArchiveInner::Pe(MonoArchive::new(data))),
FileFormat::SourceBundle => Archive(ArchiveInner::SourceBundle(MonoArchive::new(data))),
FileFormat::Wasm => Archive(ArchiveInner::Wasm(MonoArchive::new(data))),
FileFormat::PortablePdb => Archive(ArchiveInner::PortablePdb(MonoArchive::new(data))),
FileFormat::Unknown => {
return Err(ObjectError::new(ObjectErrorRepr::UnsupportedObject))
}
Expand All @@ -654,6 +702,7 @@ impl<'d> Archive<'d> {
ArchiveInner::Pe(_) => FileFormat::Pe,
ArchiveInner::Wasm(_) => FileFormat::Wasm,
ArchiveInner::SourceBundle(_) => FileFormat::SourceBundle,
ArchiveInner::PortablePdb(_) => FileFormat::PortablePdb,
}
}

Expand Down Expand Up @@ -702,6 +751,7 @@ impl<'d> Archive<'d> {
.object_by_index(index)
.map(|opt| opt.map(Object::Wasm))
.map_err(ObjectError::transparent),
ArchiveInner::PortablePdb(_) => Ok(None),
}
}

Expand Down Expand Up @@ -730,6 +780,7 @@ enum ObjectIteratorInner<'d, 'a> {
Pe(MonoArchiveObjects<'d, PeObject<'d>>),
SourceBundle(MonoArchiveObjects<'d, SourceBundle<'d>>),
Wasm(MonoArchiveObjects<'d, WasmObject<'d>>),
PortablePdb(MonoArchiveObjects<'d, PortablePdbObject<'d>>),
}

/// An iterator over [`Object`](enum.Object.html)s in an [`Archive`](struct.Archive.html).
Expand Down
Loading

0 comments on commit 282ecce

Please sign in to comment.