std: Unsafe-wrap backtrace code held in-common · model-checking/verify-rust-std@de2a037 (original) (raw)
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 {
`