|
1 | 1 | //! Common code for printing backtraces.
|
| 2 | +#![forbid(unsafe_op_in_unsafe_fn)] |
2 | 3 |
|
3 | 4 | use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
|
4 | 5 | use crate::borrow::Cow;
|
@@ -62,73 +63,76 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
|
62 | 63 | // Start immediately if we're not using a short backtrace.
|
63 | 64 | let mut start = print_fmt != PrintFmt::Short;
|
64 | 65 | set_image_base();
|
65 |
| - backtrace_rs::trace_unsynchronized(|frame| { |
66 |
| - if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES { |
67 |
| - return false; |
68 |
| - } |
| 66 | + // SAFETY: we roll our own locking in this town |
| 67 | + unsafe { |
| 68 | + backtrace_rs::trace_unsynchronized(|frame| { |
| 69 | + if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES { |
| 70 | + return false; |
| 71 | + } |
69 | 72 |
|
70 |
| - let mut hit = false; |
71 |
| - backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { |
72 |
| - hit = true; |
73 |
| - |
74 |
| - // Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace` |
75 |
| - // are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be |
76 |
| - // called before the panic hook, so we won't ignore any frames if there is no |
77 |
| - // invoke of `__rust_begin_short_backtrace`. |
78 |
| - if print_fmt == PrintFmt::Short { |
79 |
| - if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { |
80 |
| - if start && sym.contains("__rust_begin_short_backtrace") { |
81 |
| - start = false; |
82 |
| - return; |
83 |
| - } |
84 |
| - if sym.contains("__rust_end_short_backtrace") { |
85 |
| - start = true; |
86 |
| - return; |
87 |
| - } |
88 |
| - if !start { |
89 |
| - omitted_count += 1; |
| 73 | + let mut hit = false; |
| 74 | + backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { |
| 75 | + hit = true; |
| 76 | + |
| 77 | + // Any frames between `__rust_begin_short_backtrace` and `__rust_end_short_backtrace` |
| 78 | + // are omitted from the backtrace in short mode, `__rust_end_short_backtrace` will be |
| 79 | + // called before the panic hook, so we won't ignore any frames if there is no |
| 80 | + // invoke of `__rust_begin_short_backtrace`. |
| 81 | + if print_fmt == PrintFmt::Short { |
| 82 | + if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { |
| 83 | + if start && sym.contains("__rust_begin_short_backtrace") { |
| 84 | + start = false; |
| 85 | + return; |
| 86 | + } |
| 87 | + if sym.contains("__rust_end_short_backtrace") { |
| 88 | + start = true; |
| 89 | + return; |
| 90 | + } |
| 91 | + if !start { |
| 92 | + omitted_count += 1; |
| 93 | + } |
90 | 94 | }
|
91 | 95 | }
|
92 |
| - } |
93 | 96 |
|
94 |
| - if start { |
95 |
| - if omitted_count > 0 { |
96 |
| - debug_assert!(print_fmt == PrintFmt::Short); |
97 |
| - // only print the message between the middle of frames |
98 |
| - if !first_omit { |
99 |
| - let _ = writeln!( |
100 |
| - bt_fmt.formatter(), |
101 |
| - " [... omitted {} frame{} ...]", |
102 |
| - omitted_count, |
103 |
| - if omitted_count > 1 { "s" } else { "" } |
104 |
| - ); |
| 97 | + if start { |
| 98 | + if omitted_count > 0 { |
| 99 | + debug_assert!(print_fmt == PrintFmt::Short); |
| 100 | + // only print the message between the middle of frames |
| 101 | + if !first_omit { |
| 102 | + let _ = writeln!( |
| 103 | + bt_fmt.formatter(), |
| 104 | + " [... omitted {} frame{} ...]", |
| 105 | + omitted_count, |
| 106 | + if omitted_count > 1 { "s" } else { "" } |
| 107 | + ); |
| 108 | + } |
| 109 | + first_omit = false; |
| 110 | + omitted_count = 0; |
105 | 111 | }
|
106 |
| - first_omit = false; |
107 |
| - omitted_count = 0; |
| 112 | + res = bt_fmt.frame().symbol(frame, symbol); |
108 | 113 | }
|
109 |
| - res = bt_fmt.frame().symbol(frame, symbol); |
| 114 | + }); |
| 115 | + #[cfg(target_os = "nto")] |
| 116 | + if libc::__my_thread_exit as *mut libc::c_void == frame.ip() { |
| 117 | + if !hit && start { |
| 118 | + use crate::backtrace_rs::SymbolName; |
| 119 | + res = bt_fmt.frame().print_raw( |
| 120 | + frame.ip(), |
| 121 | + Some(SymbolName::new("__my_thread_exit".as_bytes())), |
| 122 | + None, |
| 123 | + None, |
| 124 | + ); |
| 125 | + } |
| 126 | + return false; |
110 | 127 | }
|
111 |
| - }); |
112 |
| - #[cfg(target_os = "nto")] |
113 |
| - if libc::__my_thread_exit as *mut libc::c_void == frame.ip() { |
114 | 128 | if !hit && start {
|
115 |
| - use crate::backtrace_rs::SymbolName; |
116 |
| - res = bt_fmt.frame().print_raw( |
117 |
| - frame.ip(), |
118 |
| - Some(SymbolName::new("__my_thread_exit".as_bytes())), |
119 |
| - None, |
120 |
| - None, |
121 |
| - ); |
| 129 | + res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); |
122 | 130 | }
|
123 |
| - return false; |
124 |
| - } |
125 |
| - if !hit && start { |
126 |
| - res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); |
127 |
| - } |
128 | 131 |
|
129 |
| - idx += 1; |
130 |
| - res.is_ok() |
131 |
| - }); |
| 132 | + idx += 1; |
| 133 | + res.is_ok() |
| 134 | + }) |
| 135 | + }; |
132 | 136 | res?;
|
133 | 137 | bt_fmt.finish()?;
|
134 | 138 | if print_fmt == PrintFmt::Short {
|
|
0 commit comments