Coverage Report

Created: 2026-03-28 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/error-chain-0.12.4/src/backtrace.rs
Line
Count
Source
1
pub use self::imp::{Backtrace, InternalBacktrace};
2
3
#[cfg(feature = "backtrace")]
4
mod imp {
5
    extern crate backtrace;
6
7
    use std::cell::UnsafeCell;
8
    use std::env;
9
    use std::fmt;
10
    use std::sync::atomic::{AtomicUsize, Ordering};
11
    use std::sync::{Arc, Mutex};
12
13
    /// Internal representation of a backtrace
14
    #[doc(hidden)]
15
    #[derive(Clone)]
16
    pub struct InternalBacktrace {
17
        backtrace: Option<Arc<MaybeResolved>>,
18
    }
19
20
    struct MaybeResolved {
21
        resolved: Mutex<bool>,
22
        backtrace: UnsafeCell<Backtrace>,
23
    }
24
25
    unsafe impl Send for MaybeResolved {}
26
    unsafe impl Sync for MaybeResolved {}
27
28
    pub use self::backtrace::Backtrace;
29
30
    impl InternalBacktrace {
31
        /// Returns a backtrace of the current call stack if `RUST_BACKTRACE`
32
        /// is set to anything but ``0``, and `None` otherwise.  This is used
33
        /// in the generated error implementations.
34
        #[doc(hidden)]
35
        pub fn new() -> InternalBacktrace {
36
            static ENABLED: AtomicUsize = AtomicUsize::new(0);
37
38
            match ENABLED.load(Ordering::SeqCst) {
39
                0 => {
40
                    let enabled = match env::var_os("RUST_BACKTRACE") {
41
                        Some(ref val) if val != "0" => true,
42
                        _ => false,
43
                    };
44
                    ENABLED.store(enabled as usize + 1, Ordering::SeqCst);
45
                    if !enabled {
46
                        return InternalBacktrace { backtrace: None };
47
                    }
48
                }
49
                1 => return InternalBacktrace { backtrace: None },
50
                _ => {}
51
            }
52
53
            InternalBacktrace {
54
                backtrace: Some(Arc::new(MaybeResolved {
55
                    resolved: Mutex::new(false),
56
                    backtrace: UnsafeCell::new(Backtrace::new_unresolved()),
57
                })),
58
            }
59
        }
60
61
        /// Acquire the internal backtrace
62
        #[doc(hidden)]
63
        pub fn as_backtrace(&self) -> Option<&Backtrace> {
64
            let bt = match self.backtrace {
65
                Some(ref bt) => bt,
66
                None => return None,
67
            };
68
            let mut resolved = bt.resolved.lock().unwrap();
69
            unsafe {
70
                if !*resolved {
71
                    (*bt.backtrace.get()).resolve();
72
                    *resolved = true;
73
                }
74
                Some(&*bt.backtrace.get())
75
            }
76
        }
77
    }
78
79
    impl fmt::Debug for InternalBacktrace {
80
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81
            f.debug_struct("InternalBacktrace")
82
                .field("backtrace", &self.as_backtrace())
83
                .finish()
84
        }
85
    }
86
}
87
88
#[cfg(not(feature = "backtrace"))]
89
mod imp {
90
    /// Dummy type used when the `backtrace` feature is disabled.
91
    pub type Backtrace = ();
92
93
    /// Internal representation of a backtrace
94
    #[doc(hidden)]
95
    #[derive(Clone, Debug)]
96
    pub struct InternalBacktrace {}
97
98
    impl InternalBacktrace {
99
        /// Returns a new backtrace
100
        #[doc(hidden)]
101
0
        pub fn new() -> InternalBacktrace {
102
0
            InternalBacktrace {}
103
0
        }
104
105
        /// Returns the internal backtrace
106
        #[doc(hidden)]
107
0
        pub fn as_backtrace(&self) -> Option<&Backtrace> {
108
0
            None
109
0
        }
110
    }
111
}