Skip to content

Commit d3fb904

Browse files
committed
More improvements to gimli support
* Migrate to `goblin` instead of `object` to reduce dependencies * Disable as many features as we can along the way, slimming down dependencies * Add rudimentary support for Windows MinGW * Don't consult symbol tables in files and instead assume `dladdr` does that for us * Add a lifetime parameter to the inner `Symbol` so the gimli bindings can be expressed a bit more safely.
1 parent e600773 commit d3fb904

File tree

9 files changed

+260
-141
lines changed

9 files changed

+260
-141
lines changed

Cargo.toml

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ rustc-serialize = { version = "0.3", optional = true }
3030
cpp_demangle = { default-features = false, version = "0.2.3", optional = true }
3131

3232
# Optional dependencies enabled through the `gimli-symbolize` feature
33-
addr2line = { version = "0.9.0", optional = true, default-features = false, features = ['std', 'std-object'] }
33+
addr2line = { version = "0.9.0", optional = true, default-features = false, features = ['std'] }
3434
findshlibs = { version = "0.5.0", optional = true }
3535
memmap = { version = "0.7.0", optional = true }
36+
goblin = { version = "0.0.22", optional = true, default-features = false, features = ['std'] }
3637

3738
[target.'cfg(windows)'.dependencies]
3839
winapi = { version = "0.3.3", optional = true }
40+
goblin = { version = "0.0.22", optional = true, default-features = false, features = ['pe32', 'pe64'] }
41+
[target.'cfg(target_os = "macos")'.dependencies]
42+
goblin = { version = "0.0.22", optional = true, default-features = false, features = ['mach32', 'mach64'] }
43+
[target.'cfg(not(any(target_os = "macos", windows)))'.dependencies]
44+
goblin = { version = "0.0.22", optional = true, default-features = false, features = ['elf32', 'elf64'] }
3945

4046
# Each feature controls the two phases of finding a backtrace: getting a
4147
# backtrace and then resolving instruction pointers to symbols. The default
@@ -92,7 +98,7 @@ kernel32 = []
9298
libbacktrace = ["backtrace-sys"]
9399
dladdr = []
94100
coresymbolication = []
95-
gimli-symbolize = ["addr2line", "findshlibs", "memmap"]
101+
gimli-symbolize = ["addr2line", "findshlibs", "memmap", "goblin"]
96102

97103
#=======================================
98104
# Methods of serialization

src/symbolize/coresymbolication.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ const CSREF_NULL: CSTypeRef = CSTypeRef {
4848
cpp_obj: 0 as *const c_void,
4949
};
5050

51-
pub enum Symbol {
51+
pub enum Symbol<'a> {
5252
Core {
5353
path: *const c_char,
5454
lineno: u32,
5555
name: *const c_char,
5656
addr: *mut c_void,
5757
},
58-
Dladdr(dladdr::Symbol),
58+
Dladdr(dladdr::Symbol<'a>),
5959
}
6060

61-
impl Symbol {
61+
impl Symbol<'_> {
6262
pub fn name(&self) -> Option<SymbolName> {
6363
let name = match *self {
6464
Symbol::Core { name, .. } => name,

src/symbolize/dbghelp.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,12 @@ use crate::windows::*;
3535
use crate::SymbolName;
3636
use core::char;
3737
use core::ffi::c_void;
38+
use core::marker;
3839
use core::mem;
3940
use core::slice;
4041

4142
// Store an OsString on std so we can provide the symbol name and filename.
42-
pub struct Symbol {
43+
pub struct Symbol<'a> {
4344
name: *const [u8],
4445
addr: *mut c_void,
4546
line: Option<u32>,
@@ -48,9 +49,10 @@ pub struct Symbol {
4849
_filename_cache: Option<::std::ffi::OsString>,
4950
#[cfg(not(feature = "std"))]
5051
_filename_cache: (),
52+
_marker: marker::PhantomData<&'a i32>,
5153
}
5254

53-
impl Symbol {
55+
impl Symbol<'_> {
5456
pub fn name(&self) -> Option<SymbolName> {
5557
Some(SymbolName::new(unsafe { &*self.name }))
5658
}
@@ -209,6 +211,7 @@ unsafe fn do_resolve(
209211
line: lineno,
210212
filename,
211213
_filename_cache: cache(filename),
214+
_marker: marker::PhantomData,
212215
},
213216
})
214217
}

src/symbolize/dladdr.rs

+23-15
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@
1515

1616
cfg_if::cfg_if! {
1717
if #[cfg(all(unix, not(target_os = "emscripten"), feature = "dladdr"))] {
18+
use core::ffi::c_void;
19+
use core::marker;
1820
use core::{mem, slice};
21+
use crate::SymbolName;
1922
use crate::types::BytesOrWideString;
20-
use core::ffi::c_void;
2123
use libc::{self, Dl_info};
2224

23-
use crate::SymbolName;
24-
25-
pub struct Symbol {
25+
pub struct Symbol<'a> {
2626
inner: Dl_info,
27+
_marker: marker::PhantomData<&'a i32>,
2728
}
2829

29-
impl Symbol {
30+
impl Symbol<'_> {
3031
pub fn name(&self) -> Option<SymbolName> {
3132
if self.inner.dli_sname.is_null() {
3233
None
@@ -57,45 +58,52 @@ cfg_if::cfg_if! {
5758
}
5859
}
5960

60-
pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol)) {
61+
pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol<'static>)) {
6162
let mut info = Symbol {
6263
inner: mem::zeroed(),
64+
_marker: marker::PhantomData,
6365
};
6466
if libc::dladdr(addr as *mut _, &mut info.inner) != 0 {
6567
cb(info)
6668
}
6769
}
6870
} else {
6971
use core::ffi::c_void;
70-
use crate::types::BytesOrWideString;
72+
use core::marker;
7173
use crate::symbolize::SymbolName;
74+
use crate::types::BytesOrWideString;
75+
76+
pub struct Symbol<'a> {
77+
a: Void,
78+
_b: marker::PhantomData<&'a i32>,
79+
}
7280

73-
pub enum Symbol {}
81+
enum Void {}
7482

75-
impl Symbol {
83+
impl Symbol<'_> {
7684
pub fn name(&self) -> Option<SymbolName> {
77-
match *self {}
85+
match self.a {}
7886
}
7987

8088
pub fn addr(&self) -> Option<*mut c_void> {
81-
match *self {}
89+
match self.a {}
8290
}
8391

8492
pub fn filename_raw(&self) -> Option<BytesOrWideString> {
85-
match *self {}
93+
match self.a {}
8694
}
8795

8896
#[cfg(feature = "std")]
8997
pub fn filename(&self) -> Option<&::std::path::Path> {
90-
match *self {}
98+
match self.a {}
9199
}
92100

93101
pub fn lineno(&self) -> Option<u32> {
94-
match *self {}
102+
match self.a {}
95103
}
96104
}
97105

98-
pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol)) {
106+
pub unsafe fn resolve(addr: *mut c_void, cb: &mut FnMut(Symbol<'static>)) {
99107
drop((addr, cb));
100108
}
101109
}

src/symbolize/dladdr_resolve.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414
//! basic, not handling inline frame information at all. Since it's so prevalent
1515
//! though we have an option to use it!
1616
17-
use core::ffi::c_void;
17+
use crate::symbolize::{dladdr, ResolveWhat, SymbolName};
1818
use crate::types::BytesOrWideString;
19-
use crate::symbolize::{dladdr, SymbolName, ResolveWhat};
19+
use core::ffi::c_void;
2020

21-
pub struct Symbol(dladdr::Symbol);
21+
pub struct Symbol<'a>(dladdr::Symbol<'a>);
2222

23-
impl Symbol {
23+
impl Symbol<'_> {
2424
pub fn name(&self) -> Option<SymbolName> {
2525
self.0.name()
2626
}
@@ -45,8 +45,6 @@ impl Symbol {
4545

4646
pub unsafe fn resolve(what: ResolveWhat, cb: &mut FnMut(&super::Symbol)) {
4747
dladdr::resolve(what.address_or_ip(), &mut |sym| {
48-
cb(&super::Symbol {
49-
inner: Symbol(sym),
50-
})
48+
cb(&super::Symbol { inner: Symbol(sym) })
5149
});
5250
}

0 commit comments

Comments
 (0)