From f7dc9f92b0ec8098dadff47ec3484d8c88b14110 Mon Sep 17 00:00:00 2001 From: Arkadiy Paronyan Date: Thu, 19 Jul 2018 14:14:30 +0200 Subject: [PATCH] Panic hook (#379) * Panic hook * Abort on panic in release --- polkadot/cli/Cargo.toml | 1 + polkadot/cli/src/lib.rs | 4 ++ polkadot/cli/src/panic_hook.rs | 68 ++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 polkadot/cli/src/panic_hook.rs diff --git a/polkadot/cli/Cargo.toml b/polkadot/cli/Cargo.toml index fe25cb45c2..3f6505ba6f 100644 --- a/polkadot/cli/Cargo.toml +++ b/polkadot/cli/Cargo.toml @@ -6,6 +6,7 @@ description = "Polkadot node implementation in Rust." [dependencies] clap = { version = "2.27", features = ["yaml"] } +backtrace = "0.3" env_logger = "0.4" error-chain = "0.12" log = "0.3" diff --git a/polkadot/cli/src/lib.rs b/polkadot/cli/src/lib.rs index 1810922c7b..6257116d6b 100644 --- a/polkadot/cli/src/lib.rs +++ b/polkadot/cli/src/lib.rs @@ -33,6 +33,7 @@ extern crate parking_lot; extern crate serde; extern crate serde_json; extern crate names; +extern crate backtrace; extern crate substrate_client as client; extern crate substrate_network as network; @@ -66,6 +67,7 @@ extern crate log; pub mod error; mod informant; mod chain_spec; +mod panic_hook; pub use chain_spec::ChainSpec; pub use client::error::Error as ClientError; @@ -166,6 +168,8 @@ pub fn run(args: I, worker: W) -> error::Result<()> where T: Into + Clone, W: Worker, { + panic_hook::set(); + let yaml = load_yaml!("./cli.yml"); let matches = match clap::App::from_yaml(yaml).version(&(crate_version!().to_owned() + "\n")[..]).get_matches_from_safe(args) { Ok(m) => m, diff --git a/polkadot/cli/src/panic_hook.rs b/polkadot/cli/src/panic_hook.rs new file mode 100644 index 0000000000..fa48ce08cb --- /dev/null +++ b/polkadot/cli/src/panic_hook.rs @@ -0,0 +1,68 @@ +// Copyright 2017 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Custom panic hook with bug report link + +use backtrace::Backtrace; +use std::io::{self, Write}; +use std::panic::{self, PanicInfo}; +use std::thread; + +/// Set the panic hook +pub fn set() { + panic::set_hook(Box::new(panic_hook)); +} + +static ABOUT_PANIC: &str = " +This is a bug. Please report it at: + + https://github.com/paritytech/polkadot/issues/new +"; + +fn panic_hook(info: &PanicInfo) { + let location = info.location(); + let file = location.as_ref().map(|l| l.file()).unwrap_or(""); + let line = location.as_ref().map(|l| l.line()).unwrap_or(0); + + let msg = match info.payload().downcast_ref::<&'static str>() { + Some(s) => *s, + None => match info.payload().downcast_ref::() { + Some(s) => &s[..], + None => "Box", + } + }; + + let thread = thread::current(); + let name = thread.name().unwrap_or(""); + + let backtrace = Backtrace::new(); + + let mut stderr = io::stderr(); + + let _ = writeln!(stderr, ""); + let _ = writeln!(stderr, "===================="); + let _ = writeln!(stderr, ""); + let _ = writeln!(stderr, "{:?}", backtrace); + let _ = writeln!(stderr, ""); + let _ = writeln!( + stderr, + "Thread '{}' panicked at '{}', {}:{}", + name, msg, file, line + ); + + let _ = writeln!(stderr, "{}", ABOUT_PANIC); +} +