veilid_tools/
trim_backtrace.rs1use super::*;
2
3pub struct TrimmedBacktrace {
4 backtrace: backtrace::Backtrace,
5}
6
7impl TrimmedBacktrace {
8 #[must_use]
9 pub fn new(mut backtrace: backtrace::Backtrace) -> Self {
10 backtrace.resolve();
11 Self { backtrace }
12 }
13
14 #[must_use]
15 pub fn backtrace(&self) -> &backtrace::Backtrace {
16 &self.backtrace
17 }
18
19 #[must_use]
20 pub fn backtrace_mut(&mut self) -> &mut backtrace::Backtrace {
21 &mut self.backtrace
22 }
23
24 fn format_display(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 let cwd = std::env::current_dir();
26 let mut print_path =
27 move |f: &mut fmt::Formatter<'_>, path: backtrace::BytesOrWideString<'_>| {
28 let path = path.into_path_buf();
29 if let Ok(cwd) = &cwd {
30 if let Ok(suffix) = path.strip_prefix(cwd) {
31 return fmt::Display::fmt(&suffix.display(), f);
32 }
33 }
34 fmt::Display::fmt(&path.display(), f)
35 };
36
37 let mut f = backtrace::BacktraceFmt::new(f, backtrace::PrintFmt::Short, &mut print_path);
38 f.add_context()?;
39 'frame_loop: for frame in self.backtrace.frames() {
40 let mut frame_fmt = f.frame();
41
42 let symbols = frame.symbols();
43 for symbol in symbols {
44 let symbol_name = symbol.name().map(|x| x.to_string()).unwrap_or_default();
45
46 if symbol_name.starts_with("backtrace::")
48 || symbol_name.starts_with("veilid_tools::async_locks::")
49 || symbol_name.starts_with("<tracing::instrument::Instrumented")
50 || symbol_name.starts_with("<core::pin::Pin<")
51 || symbol_name.starts_with("<core::panic::")
52 || symbol_name.starts_with("tokio::runtime::")
53 || symbol_name.starts_with("tokio::loom::")
54 || symbol_name.starts_with("std::panicking::")
55 || symbol_name.starts_with("std::panic::")
56 {
57 continue 'frame_loop;
58 }
59
60 if symbol_name.starts_with("___rust_try") {
62 break 'frame_loop;
63 }
64
65 frame_fmt.backtrace_symbol(frame, symbol)?;
66 }
67 if symbols.is_empty() {
68 }
71 }
72 f.finish()?;
73 Ok(())
74 }
75}
76
77impl core::ops::Deref for TrimmedBacktrace {
78 type Target = backtrace::Backtrace;
79
80 fn deref(&self) -> &Self::Target {
81 self.backtrace()
82 }
83}
84
85impl core::ops::DerefMut for TrimmedBacktrace {
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 self.backtrace_mut()
88 }
89}
90
91pub trait TrimBacktraceTrait {
92 fn trim(&self) -> TrimmedBacktrace;
93}
94
95impl TrimBacktraceTrait for backtrace::Backtrace {
96 fn trim(&self) -> TrimmedBacktrace {
97 TrimmedBacktrace::new(self.clone())
98 }
99}
100
101impl From<TrimmedBacktrace> for backtrace::Backtrace {
102 fn from(value: TrimmedBacktrace) -> Self {
103 value.backtrace
104 }
105}
106
107impl fmt::Display for TrimmedBacktrace {
108 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109 self.format_display(f)
110 }
111}
112
113impl fmt::Debug for TrimmedBacktrace {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 self.backtrace.fmt(f)
116 }
117}