1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#[derive(Debug, Clone, Copy)]
pub enum BacktwrapCaptureStrategy {
DoNotCapture,
CaptureUnresolved,
CaptureResolved,
}
use BacktwrapCaptureStrategy::*;
lazy_static! {
static ref CAPTURE_STRATEGY: std::sync::Mutex<BacktwrapCaptureStrategy> = {
let out = std::sync::Mutex::new(match std::env::var("BACKTRACE_STRATEGY") {
Ok(s) => match s.as_str() {
"CAPTURE_RESOLVED" => CaptureResolved,
"CAPTURE_UNRESOLVED" => CaptureUnresolved,
_ => DoNotCapture,
},
_ => DoNotCapture,
});
warn!("Using Backtrace Capture Strategy: {:?}", out);
out
};
}
#[derive(Shrinkwrap, Debug, Clone)]
#[shrinkwrap(mutable)]
pub struct Backtwrap(pub Option<backtrace::Backtrace>);
impl Backtwrap {
pub fn new() -> Self {
Self(
match *CAPTURE_STRATEGY.lock().expect("failed to lock mutex") {
CaptureResolved => Some(backtrace::Backtrace::new()),
CaptureUnresolved => Some(backtrace::Backtrace::new_unresolved()),
DoNotCapture => None,
},
)
}
pub fn get_capture_strategy() -> BacktwrapCaptureStrategy {
*CAPTURE_STRATEGY.lock().expect("failed to lock mutex")
}
pub fn set_capture_strategy(strategy: BacktwrapCaptureStrategy) {
*CAPTURE_STRATEGY.lock().expect("failed to lock mutex") = strategy;
}
}
impl PartialEq for Backtwrap {
fn eq(&self, other: &Backtwrap) -> bool {
format!("{:?}", self) == format!("{:?}", other)
}
}
impl Eq for Backtwrap {}
impl std::hash::Hash for Backtwrap {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
format!("{:?}", self).hash(state);
}
}
impl std::convert::From<backtrace::Backtrace> for Backtwrap {
fn from(bt: backtrace::Backtrace) -> Backtwrap {
Self(Some(bt))
}
}
impl std::convert::From<Option<backtrace::Backtrace>> for Backtwrap {
fn from(bt: Option<backtrace::Backtrace>) -> Backtwrap {
Self(bt)
}
}
impl std::convert::From<Backtwrap> for Option<backtrace::Backtrace> {
fn from(bt: Backtwrap) -> Option<backtrace::Backtrace> {
bt.0
}
}