Add custom panic hook

The panic hook prints a backtrace, the panic message, file, and line
number, and a plea to report bugs.
This commit is contained in:
Brian Anderson 2017-07-03 06:31:29 +01:00
parent 4c32177ef3
commit 6345b54034
11 changed files with 120 additions and 2 deletions

26
Cargo.lock generated
View File

@ -81,6 +81,20 @@ dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "backtrace"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "backtrace-sys" name = "backtrace-sys"
version = "0.1.11" version = "0.1.11"
@ -783,6 +797,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethkey 0.2.0", "ethkey 0.2.0",
"panic_hook 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -818,6 +833,7 @@ version = "0.1.0"
dependencies = [ dependencies = [
"docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ethstore 0.1.0", "ethstore 0.1.0",
"panic_hook 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -875,6 +891,7 @@ dependencies = [
"ethcore 1.8.0", "ethcore 1.8.0",
"ethcore-util 1.8.0", "ethcore-util 1.8.0",
"evm 0.1.0", "evm 0.1.0",
"panic_hook 0.1.0",
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1713,6 +1730,13 @@ dependencies = [
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "panic_hook"
version = "0.1.0"
dependencies = [
"backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "parity" name = "parity"
version = "1.7.0" version = "1.7.0"
@ -1746,6 +1770,7 @@ dependencies = [
"log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"panic_hook 0.1.0",
"parity-dapps 1.8.0", "parity-dapps 1.8.0",
"parity-hash-fetch 1.8.0", "parity-hash-fetch 1.8.0",
"parity-ipfs-api 1.8.0", "parity-ipfs-api 1.8.0",
@ -3126,6 +3151,7 @@ dependencies = [
"checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0" "checksum aster 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfdf7355d9db158df68f976ed030ab0f6578af811f5a7bb6dcf221ec24e0e0"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159" "checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f" "checksum backtrace 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "346d7644f0b5f9bc73082d3b2236b69a05fd35cce0cfa3724e184e6a5c9e2a2f"
"checksum backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "72f9b4182546f4b04ebc4ab7f84948953a118bd6021a1b6a6c909e3e94f6be76"
"checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff" "checksum backtrace-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3a0d842ea781ce92be2bf78a9b38883948542749640b8378b3b2f03d1fd9f1ff"
"checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1" "checksum base-x 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2f59103b47307f76e03bef1633aec7fa9e29bfb5aa6daf5a334f94233c71f6c1"
"checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c" "checksum base32 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1b9605ba46d61df0410d8ac686b0007add8172eba90e8e909c347856fe794d8c"

View File

@ -53,6 +53,7 @@ parity-rpc-client = { path = "rpc_client" }
parity-updater = { path = "updater" } parity-updater = { path = "updater" }
parity-whisper = { path = "whisper" } parity-whisper = { path = "whisper" }
path = { path = "util/path" } path = { path = "util/path" }
panic_hook = { path = "panic_hook" }
parity-dapps = { path = "dapps", optional = true } parity-dapps = { path = "dapps", optional = true }
clippy = { version = "0.0.103", optional = true} clippy = { version = "0.0.103", optional = true}

View File

@ -9,6 +9,7 @@ serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
rustc-hex = "1.0" rustc-hex = "1.0"
docopt = "0.8" docopt = "0.8"
panic_hook = { path = "../../panic_hook" }
[[bin]] [[bin]]
name = "ethkey" name = "ethkey"

View File

@ -20,6 +20,7 @@ extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate ethkey; extern crate ethkey;
extern crate panic_hook;
use std::{env, fmt, process}; use std::{env, fmt, process};
use std::num::ParseIntError; use std::num::ParseIntError;
@ -155,6 +156,8 @@ impl DisplayMode {
} }
fn main() { fn main() {
panic_hook::set();
match execute(env::args()) { match execute(env::args()) {
Ok(ok) => println!("{}", ok), Ok(ok) => println!("{}", ok),
Err(err) => { Err(err) => {

View File

@ -9,6 +9,7 @@ serde = "1.0"
serde_derive = "1.0" serde_derive = "1.0"
docopt = "0.8" docopt = "0.8"
ethstore = { path = "../" } ethstore = { path = "../" }
panic_hook = { path = "../../panic_hook" }
[[bin]] [[bin]]
name = "ethstore" name = "ethstore"

View File

@ -20,6 +20,7 @@ extern crate serde;
#[macro_use] #[macro_use]
extern crate serde_derive; extern crate serde_derive;
extern crate ethstore; extern crate ethstore;
extern crate panic_hook;
use std::{env, process, fs, fmt}; use std::{env, process, fs, fmt};
use std::io::Read; use std::io::Read;
@ -134,6 +135,8 @@ impl fmt::Display for Error {
} }
fn main() { fn main() {
panic_hook::set();
match execute(env::args()) { match execute(env::args()) {
Ok(result) => println!("{}", result), Ok(result) => println!("{}", result),
Err(err) => { Err(err) => {

View File

@ -16,6 +16,7 @@ serde_derive = "1.0"
ethcore = { path = "../ethcore" } ethcore = { path = "../ethcore" }
ethcore-util = { path = "../util" } ethcore-util = { path = "../util" }
evm = { path = "../ethcore/evm" } evm = { path = "../ethcore/evm" }
panic_hook = { path = "../panic_hook" }
[features] [features]
evm-debug = ["ethcore/evm-debug-tests"] evm-debug = ["ethcore/evm-debug-tests"]

View File

@ -26,6 +26,7 @@ extern crate serde_derive;
extern crate docopt; extern crate docopt;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate evm; extern crate evm;
extern crate panic_hook;
use std::sync::Arc; use std::sync::Arc;
use std::{fmt, fs}; use std::{fmt, fs};
@ -63,6 +64,8 @@ General options:
fn main() { fn main() {
panic_hook::set();
let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize()).unwrap_or_else(|e| e.exit()); let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize()).unwrap_or_else(|e| e.exit());
if args.flag_json { if args.flag_json {

10
panic_hook/Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
description = "Parity custom panic hook"
homepage = "http://parity.io"
license = "GPL-3.0"
name = "panic_hook"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
backtrace = "0.3.2"

69
panic_hook/src/lib.rs Normal file
View File

@ -0,0 +1,69 @@
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity 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.
// Parity 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 Parity. If not, see <http://www.gnu.org/licenses/>.
//! Custom panic hook with bug report link
extern crate backtrace;
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/parity/issues/new
";
fn panic_hook(info: &PanicInfo) {
let location = info.location();
let file = location.as_ref().map(|l| l.file()).unwrap_or("<unknown>");
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::<String>() {
Some(s) => &s[..],
None => "Box<Any>",
}
};
let thread = thread::current();
let name = thread.name().unwrap_or("<unnamed>");
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);
}

View File

@ -57,6 +57,7 @@ extern crate ethcore_logger;
extern crate ethcore_util as util; extern crate ethcore_util as util;
extern crate ethkey; extern crate ethkey;
extern crate ethsync; extern crate ethsync;
extern crate panic_hook;
extern crate parity_hash_fetch as hash_fetch; extern crate parity_hash_fetch as hash_fetch;
extern crate parity_ipfs_api; extern crate parity_ipfs_api;
extern crate parity_local_store as local_store; extern crate parity_local_store as local_store;
@ -315,8 +316,7 @@ macro_rules! trace_main {
} }
fn main() { fn main() {
// Always print backtrace on panic. panic_hook::set();
env::set_var("RUST_BACKTRACE", "1");
// assuming the user is not running with `--force-direct`, then: // assuming the user is not running with `--force-direct`, then:
// if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead. // if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead.