cubecl_common/
backtrace.rs1#[cfg(feature = "std")]
2type BacktraceState = backtrace_std::BacktraceState;
3#[cfg(not(feature = "std"))]
4type BacktraceState = alloc::string::String;
5
6#[derive(Clone, Default)]
13pub struct BackTrace {
14 state: Option<BacktraceState>,
15}
16
17impl core::fmt::Debug for BackTrace {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 f.write_fmt(format_args!("{self}"))
20 }
21}
22
23impl core::fmt::Display for BackTrace {
24 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
25 match &self.state {
26 Some(state) => f.write_fmt(format_args!("{state}")),
27 None => f.write_str("No backtrace available"),
28 }
29 }
30}
31
32impl BackTrace {
33 pub fn capture() -> Self {
39 Self {
40 #[cfg(feature = "std")]
41 state: {
42 let backtrace = backtrace::Backtrace::new_unresolved();
48 Some(BacktraceState::new(backtrace))
49 },
50 #[cfg(not(feature = "std"))]
51 state: None,
52 }
53 }
54}
55
56#[cfg(feature = "std")]
57mod backtrace_std {
58 use backtrace::BytesOrWideString;
59 use core::fmt::Display;
60 use std::sync::{Arc, Mutex};
61
62 #[derive(Clone)]
64 pub struct BacktraceState {
65 backtrace: Arc<Mutex<backtrace::Backtrace>>,
66 }
67
68 impl BacktraceState {
69 pub fn new(backtrace: backtrace::Backtrace) -> Self {
70 Self {
71 backtrace: Arc::new(Mutex::new(backtrace)),
72 }
73 }
74 }
75
76 impl Display for BacktraceState {
77 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
78 let mut backtrace = self.backtrace.lock().unwrap();
79 backtrace.resolve();
80
81 let cwd = std::env::current_dir();
82
83 let mut print_path =
84 move |fmt: &mut core::fmt::Formatter<'_>, path: BytesOrWideString<'_>| {
85 let path = path.into_path_buf();
86 if let Ok(cwd) = &cwd
87 && let Ok(suffix) = path.strip_prefix(cwd)
88 {
89 return core::fmt::Display::fmt(&suffix.display(), fmt);
90 }
91
92 core::fmt::Display::fmt(&path.display(), fmt)
93 };
94
95 let mut fmt =
96 backtrace::BacktraceFmt::new(f, backtrace::PrintFmt::Short, &mut print_path);
97 fmt.add_context()?;
98 for frame in backtrace.frames().iter().skip(1) {
99 fmt.frame().backtrace_frame(frame)?;
100 }
101 fmt.finish()?;
102 Ok(())
103 }
104 }
105}