Abort earlier upon multi-panics
The double-panic `abort` is run after the logging code, to provide feedback in case of a double-panic. This means that if the panic logging fails with a panic, the `abort` might never be reached. This should not normally occur, but if the `on_panic` function detects more than 2 panics, aborting *before* logging makes panic handling somewhat more robust, as it avoids an infinite recursion, which would eventually crash the process, but also make the problem harder to debug. This handles the FIXME about what to do if the thread printing panics.
This commit is contained in:
parent
c7b84909b0
commit
54c0231b14
@ -52,7 +52,6 @@ fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
|
||||
let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
|
||||
match (prev, err.as_mut()) {
|
||||
(Some(mut stderr), _) => {
|
||||
// FIXME: what to do when the thread printing panics?
|
||||
write(&mut *stderr);
|
||||
let mut s = Some(stderr);
|
||||
LOCAL_STDERR.with(|slot| {
|
||||
@ -71,6 +70,17 @@ pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
|
||||
count
|
||||
});
|
||||
|
||||
// If this is the third nested call, on_panic triggered the last panic,
|
||||
// otherwise the double-panic check would have aborted the process.
|
||||
// Even if it is likely that on_panic was unable to log the backtrace,
|
||||
// abort immediately to avoid infinite recursion, so that attaching a
|
||||
// debugger provides a useable stacktrace.
|
||||
if panics >= 3 {
|
||||
util::dumb_print(format_args!("thread panicked while processing \
|
||||
panic. aborting."));
|
||||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
// If this is a double panic, make sure that we print a backtrace
|
||||
// for this panic. Otherwise only print it if logging is enabled.
|
||||
let log_backtrace = panics >= 2 || backtrace::log_enabled();
|
||||
|
Loading…
x
Reference in New Issue
Block a user