Skip to content

Commit

Permalink
no_std support
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron Power committed Oct 5, 2018
1 parent a73a623 commit 13371ce
Show file tree
Hide file tree
Showing 15 changed files with 134 additions and 43 deletions.
30 changes: 28 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ documentation = "https://docs.rs/backtrace"
description = """
A library to acquire a stack trace (backtrace) at runtime in a Rust program.
"""
autoexamples = true
autotests = true

[dependencies]
cfg-if = "0.1"
rustc-demangle = "0.1.4"
Expand Down Expand Up @@ -47,7 +50,10 @@ backtrace-sys = { path = "backtrace-sys", version = "0.1.17", optional = true }
# Note that not all features are available on all platforms, so even though a
# feature is enabled some other feature may be used instead.
[features]
default = ["libunwind", "libbacktrace", "coresymbolication", "dladdr", "dbghelp"]
default = ["std", "libunwind", "libbacktrace", "coresymbolication", "dladdr", "dbghelp"]

# Include std support.
std = []

#=======================================
# Methods of acquiring a backtrace
Expand Down Expand Up @@ -86,7 +92,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", "std"]
dladdr = []
coresymbolication = []
gimli-symbolize = ["addr2line", "findshlibs", "gimli", "memmap", "object" ]
Expand All @@ -97,3 +103,23 @@ gimli-symbolize = ["addr2line", "findshlibs", "gimli", "memmap", "object" ]
# Various features used for enabling rustc-serialize or syntex codegen.
serialize-rustc = ["rustc-serialize"]
serialize-serde = ["serde", "serde_derive"]

[[example]]
name = "backtrace"
required-features = ["std"]

[[example]]
name = "raw"
required-features = ["std"]

[[test]]
name = "skip_inner_frames"
required-features = ["std"]

[[test]]
name = "long_fn_name"
required-features = ["std"]

[[test]]
name = "smoke"
required-features = ["std"]
3 changes: 1 addition & 2 deletions backtrace-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

extern crate libc;

use libc::uintptr_t;
use std::os::raw::{c_void, c_char, c_int};
use libc::{c_void, c_char, c_int, uintptr_t};

pub type backtrace_syminfo_callback =
extern fn(data: *mut c_void,
Expand Down
4 changes: 2 additions & 2 deletions src/backtrace/libunwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::os::raw::c_void;
use types::c_void;

pub struct Frame {
ctx: *mut uw::_Unwind_Context,
Expand Down Expand Up @@ -84,7 +84,7 @@ mod uw {
pub use self::_Unwind_Reason_Code::*;

use libc;
use std::os::raw::{c_int, c_void};
use types::{c_int, c_void};

#[repr(C)]
pub enum _Unwind_Reason_Code {
Expand Down
6 changes: 3 additions & 3 deletions src/backtrace/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use std::fmt;

use std::os::raw::c_void;
#[cfg(feature = "std")] use std::fmt;
use types::c_void;

/// Inspects the current call-stack, passing all active frames into the closure
/// provided to calculate a stack trace.
Expand Down Expand Up @@ -77,6 +76,7 @@ impl Frame {
}
}

#[cfg(feature = "std")]
impl fmt::Debug for Frame {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Frame")
Expand Down
2 changes: 1 addition & 1 deletion src/backtrace/noop.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::os::raw::c_void;
use types::c_void;

#[inline(always)]
pub fn trace(_cb: &mut FnMut(&super::Frame) -> bool) {}
Expand Down
10 changes: 8 additions & 2 deletions src/backtrace/unix_backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::mem;
use std::os::raw::{c_void, c_int};
cfg_if! {
if #[cfg(feature = "std")] {
use std::mem;
} else {
use core::mem;
}
}
use types::{c_void, c_int};

pub struct Frame {
addr: *mut c_void,
Expand Down
27 changes: 22 additions & 5 deletions src/capture.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
use std::fmt;
use std::mem;
use std::os::raw::c_void;
use std::path::{Path, PathBuf};
cfg_if! {
if #[cfg(feature = "std")] {
use std::fmt;
use std::mem;
use std::path::{Path, PathBuf};

use {trace, resolve, SymbolName};
use {trace, resolve, SymbolName};
}
}

use types::c_void;

/// Representation of an owned and self-contained backtrace.
///
Expand All @@ -12,6 +17,7 @@ use {trace, resolve, SymbolName};
#[derive(Clone)]
#[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable, RustcEncodable))]
#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
#[cfg(feature = "std")]
pub struct Backtrace {
// Frames here are listed from top-to-bottom of the stack
frames: Vec<BacktraceFrame>,
Expand All @@ -30,6 +36,7 @@ pub struct Backtrace {
pub struct BacktraceFrame {
ip: usize,
symbol_address: usize,
#[cfg(feature = "std")]
symbols: Option<Vec<BacktraceSymbol>>,
}

Expand All @@ -41,12 +48,15 @@ pub struct BacktraceFrame {
#[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable, RustcEncodable))]
#[cfg_attr(feature = "serialize-serde", derive(Deserialize, Serialize))]
pub struct BacktraceSymbol {
#[cfg(feature = "std")]
name: Option<Vec<u8>>,
addr: Option<usize>,
#[cfg(feature = "std")]
filename: Option<PathBuf>,
lineno: Option<u32>,
}

#[cfg(feature = "std")]
impl Backtrace {
/// Captures a backtrace at the callsite of this function, returning an
/// owned representation.
Expand Down Expand Up @@ -153,6 +163,7 @@ impl Backtrace {
}
}

#[cfg(feature = "std")]
impl From<Vec<BacktraceFrame>> for Backtrace {
fn from(frames: Vec<BacktraceFrame>) -> Self {
Backtrace {
Expand All @@ -162,6 +173,7 @@ impl From<Vec<BacktraceFrame>> for Backtrace {
}
}

#[cfg(feature = "std")]
impl Into<Vec<BacktraceFrame>> for Backtrace {
fn into(self) -> Vec<BacktraceFrame> {
self.frames
Expand All @@ -188,13 +200,15 @@ impl BacktraceFrame {
///
/// Note that if this frame came from an unresolved backtrace then this will
/// return an empty list.
#[cfg(feature = "std")]
pub fn symbols(&self) -> &[BacktraceSymbol] {
self.symbols.as_ref().map(|s| &s[..]).unwrap_or(&[])
}
}

impl BacktraceSymbol {
/// Same as `Symbol::name`
#[cfg(feature = "std")]
pub fn name(&self) -> Option<SymbolName> {
self.name.as_ref().map(|s| SymbolName::new(s))
}
Expand All @@ -205,6 +219,7 @@ impl BacktraceSymbol {
}

/// Same as `Symbol::filename`
#[cfg(feature = "std")]
pub fn filename(&self) -> Option<&Path> {
self.filename.as_ref().map(|p| &**p)
}
Expand All @@ -215,6 +230,7 @@ impl BacktraceSymbol {
}
}

#[cfg(feature = "std")]
impl fmt::Debug for Backtrace {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let hex_width = mem::size_of::<usize>() * 2 + 2;
Expand Down Expand Up @@ -263,6 +279,7 @@ impl fmt::Debug for Backtrace {
}
}

#[cfg(feature = "std")]
impl Default for Backtrace {
fn default() -> Backtrace {
Backtrace::new()
Expand Down
11 changes: 9 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
//! extern crate backtrace;
//!
//! fn main() {
//! # #[cfg(feature = "std")]
//! backtrace::trace(|frame| {
//! let ip = frame.ip();
//! let symbol_address = frame.symbol_address();
Expand All @@ -67,6 +68,7 @@
#![doc(html_root_url = "https://docs.rs/backtrace")]
#![deny(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(unix)]
extern crate libc;
Expand Down Expand Up @@ -98,7 +100,7 @@ cfg_if! {
}

#[allow(dead_code)] // not used everywhere
#[cfg(unix)]
#[cfg(all(unix, feature = "std"))]
#[macro_use]
mod dylib;

Expand All @@ -108,9 +110,13 @@ mod backtrace;
pub use symbolize::{resolve, Symbol, SymbolName};
mod symbolize;

pub use capture::{Backtrace, BacktraceFrame, BacktraceSymbol};
#[cfg(feature = "std")]
pub use capture::Backtrace;
pub use capture::{BacktraceFrame, BacktraceSymbol};
mod capture;

mod types;

#[allow(dead_code)]
struct Bomb {
enabled: bool,
Expand All @@ -126,6 +132,7 @@ impl Drop for Bomb {
}

#[allow(dead_code)]
#[cfg(feature = "std")]
mod lock {
use std::cell::Cell;
use std::sync::{Once, Mutex, MutexGuard, ONCE_INIT};
Expand Down
2 changes: 1 addition & 1 deletion src/symbolize/coresymbolication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

use std::ffi::{CStr, OsStr};
use std::mem;
use std::os::raw::{c_void, c_char, c_int};
use std::os::unix::prelude::*;
use std::path::Path;
use std::ptr;
Expand All @@ -23,6 +22,7 @@ use libc::{self, Dl_info};
use SymbolName;
use dylib::Dylib;
use dylib::Symbol as DylibSymbol;
use types::{c_void, c_char, c_int};

#[repr(C)]
#[derive(Copy, Clone, PartialEq)]
Expand Down
13 changes: 8 additions & 5 deletions src/symbolize/dladdr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::ffi::CStr;
use std::mem;
use std::os::raw::c_void;
use std::path::Path;
use core::mem;

#[cfg(feature = "std")] use std::ffi::CStr;
#[cfg(feature = "std")] use std::path::Path;

use types::c_void;
use libc::{self, Dl_info};

use SymbolName;
#[cfg(feature = "std")] use SymbolName;

pub struct Symbol {
inner: Dl_info,
}

impl Symbol {
#[cfg(feature = "std")]
pub fn name(&self) -> Option<SymbolName> {
if self.inner.dli_sname.is_null() {
None
Expand All @@ -36,6 +38,7 @@ impl Symbol {
Some(self.inner.dli_saddr as *mut _)
}

#[cfg(feature = "std")]
pub fn filename(&self) -> Option<&Path> {
None
}
Expand Down
2 changes: 1 addition & 1 deletion src/symbolize/gimli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::cell::RefCell;
use std::env;
use std::fs::File;
use std::mem;
use std::os::raw::c_void;
use libc::c_void;
use std::path::{Path, PathBuf};
use std::u32;

Expand Down
4 changes: 2 additions & 2 deletions src/symbolize/libbacktrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

extern crate backtrace_sys as bt;

use libc::uintptr_t;
use std::ffi::{CStr, OsStr};
use std::os::raw::{c_void, c_char, c_int};
use std::os::unix::prelude::*;
use std::path::Path;
use std::ptr;
use std::sync::{ONCE_INIT, Once};

use libc::{c_char, c_int, c_void, uintptr_t};

use SymbolName;

pub enum Symbol {
Expand Down
Loading

0 comments on commit 13371ce

Please sign in to comment.