Never panic during execution proof check (#3504)

* do not panic during execution proof check

* Update core/state-machine/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Update core/state-machine/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Update core/state-machine/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* BackendTrustLevel enum

* up runtime version

* Update core/state-machine/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* Update core/state-machine/src/lib.rs

Co-Authored-By: DemiMarie-parity <48690212+DemiMarie-parity@users.noreply.github.com>

* fixed some grumbles

* Update core/state-machine/src/testing.rs

Co-Authored-By: Gavin Wood <gavin@parity.io>

* Update core/state-machine/src/lib.rs

Co-Authored-By: Gavin Wood <gavin@parity.io>

* mov where

* spaces -> tabs (to restart build)
This commit is contained in:
Svyatoslav Nikolsky
2019-09-11 10:27:32 +03:00
committed by GitHub
parent 9607afd629
commit 010395e620
18 changed files with 254 additions and 78 deletions
+41 -10
View File
@@ -31,7 +31,18 @@ use std::cell::Cell;
use std::thread;
thread_local! {
static ABORT: Cell<bool> = Cell::new(true);
static ON_PANIC: Cell<OnPanic> = Cell::new(OnPanic::Abort);
}
/// Panic action.
#[derive(Debug, Clone, Copy, PartialEq)]
enum OnPanic {
/// Abort when panic occurs.
Abort,
/// Unwind when panic occurs.
Unwind,
/// Always unwind even if someone changes strategy to Abort afterwards.
NeverAbort,
}
/// Set the panic hook.
@@ -52,10 +63,13 @@ This is a bug. Please report it at:
")}
/// Set aborting flag. Returns previous value of the flag.
fn set_abort(enabled: bool) -> bool {
ABORT.with(|flag| {
let prev = flag.get();
flag.set(enabled);
fn set_abort(on_panic: OnPanic) -> OnPanic {
ON_PANIC.with(|val| {
let prev = val.get();
match prev {
OnPanic::Abort | OnPanic::Unwind => val.set(on_panic),
OnPanic::NeverAbort => (),
}
prev
})
}
@@ -69,7 +83,7 @@ fn set_abort(enabled: bool) -> bool {
/// > the `AbortGuard` on the stack and let it destroy itself naturally.
pub struct AbortGuard {
/// Value that was in `ABORT` before we created this guard.
previous_val: bool,
previous_val: OnPanic,
/// Marker so that `AbortGuard` doesn't implement `Send`.
_not_send: PhantomData<std::rc::Rc<()>>
}
@@ -79,7 +93,7 @@ impl AbortGuard {
/// unwind the stack (unless another guard is created afterwards).
pub fn force_unwind() -> AbortGuard {
AbortGuard {
previous_val: set_abort(false),
previous_val: set_abort(OnPanic::Unwind),
_not_send: PhantomData
}
}
@@ -88,7 +102,16 @@ impl AbortGuard {
/// abort the process (unless another guard is created afterwards).
pub fn force_abort() -> AbortGuard {
AbortGuard {
previous_val: set_abort(true),
previous_val: set_abort(OnPanic::Abort),
_not_send: PhantomData
}
}
/// Create a new guard. While the guard is alive, panics that happen in the current thread will
/// **never** abort the process (even if `AbortGuard::force_abort()` guard will be created afterwards).
pub fn never_abort() -> AbortGuard {
AbortGuard {
previous_val: set_abort(OnPanic::NeverAbort),
_not_send: PhantomData
}
}
@@ -133,8 +156,8 @@ fn panic_hook(info: &PanicInfo, report_url: &'static str) {
);
let _ = writeln!(stderr, ABOUT_PANIC!(), report_url);
ABORT.with(|flag| {
if flag.get() {
ON_PANIC.with(|val| {
if val.get() == OnPanic::Abort {
::std::process::exit(1);
}
})
@@ -150,4 +173,12 @@ mod tests {
let _guard = AbortGuard::force_unwind();
::std::panic::catch_unwind(|| panic!()).ok();
}
#[test]
fn does_not_abort_after_never_abort() {
set("test");
let _guard = AbortGuard::never_abort();
let _guard = AbortGuard::force_abort();
std::panic::catch_unwind(|| panic!()).ok();
}
}