diff --git a/Cargo.lock b/Cargo.lock index bb5f58441..ca485fd7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,6 +81,20 @@ dependencies = [ "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]] name = "backtrace-sys" version = "0.1.11" @@ -783,6 +797,7 @@ version = "0.1.0" dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethkey 0.2.0", + "panic_hook 0.1.0", "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_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -818,6 +833,7 @@ version = "0.1.0" dependencies = [ "docopt 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "ethstore 0.1.0", + "panic_hook 0.1.0", "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_derive 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -875,6 +891,7 @@ dependencies = [ "ethcore 1.8.0", "ethcore-util 1.8.0", "evm 0.1.0", + "panic_hook 0.1.0", "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_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)", ] +[[package]] +name = "panic_hook" +version = "0.1.0" +dependencies = [ + "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parity" version = "1.7.0" @@ -1746,6 +1770,7 @@ dependencies = [ "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)", "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-hash-fetch 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 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.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 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" diff --git a/Cargo.toml b/Cargo.toml index d541636da..21961776e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ parity-rpc-client = { path = "rpc_client" } parity-updater = { path = "updater" } parity-whisper = { path = "whisper" } path = { path = "util/path" } +panic_hook = { path = "panic_hook" } parity-dapps = { path = "dapps", optional = true } clippy = { version = "0.0.103", optional = true} diff --git a/ethkey/cli/Cargo.toml b/ethkey/cli/Cargo.toml index 3ea931e25..6921af745 100644 --- a/ethkey/cli/Cargo.toml +++ b/ethkey/cli/Cargo.toml @@ -9,6 +9,7 @@ serde = "1.0" serde_derive = "1.0" rustc-hex = "1.0" docopt = "0.8" +panic_hook = { path = "../../panic_hook" } [[bin]] name = "ethkey" diff --git a/ethkey/cli/src/main.rs b/ethkey/cli/src/main.rs index a47abbbab..7ad07e295 100644 --- a/ethkey/cli/src/main.rs +++ b/ethkey/cli/src/main.rs @@ -20,6 +20,7 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate ethkey; +extern crate panic_hook; use std::{env, fmt, process}; use std::num::ParseIntError; @@ -155,6 +156,8 @@ impl DisplayMode { } fn main() { + panic_hook::set(); + match execute(env::args()) { Ok(ok) => println!("{}", ok), Err(err) => { diff --git a/ethstore/cli/Cargo.toml b/ethstore/cli/Cargo.toml index 80d20f792..71215fefe 100644 --- a/ethstore/cli/Cargo.toml +++ b/ethstore/cli/Cargo.toml @@ -9,6 +9,7 @@ serde = "1.0" serde_derive = "1.0" docopt = "0.8" ethstore = { path = "../" } +panic_hook = { path = "../../panic_hook" } [[bin]] name = "ethstore" diff --git a/ethstore/cli/src/main.rs b/ethstore/cli/src/main.rs index 06ebfcd20..09ccc8cd4 100644 --- a/ethstore/cli/src/main.rs +++ b/ethstore/cli/src/main.rs @@ -20,6 +20,7 @@ extern crate serde; #[macro_use] extern crate serde_derive; extern crate ethstore; +extern crate panic_hook; use std::{env, process, fs, fmt}; use std::io::Read; @@ -134,6 +135,8 @@ impl fmt::Display for Error { } fn main() { + panic_hook::set(); + match execute(env::args()) { Ok(result) => println!("{}", result), Err(err) => { diff --git a/evmbin/Cargo.toml b/evmbin/Cargo.toml index e3de99f2b..5e9c50f8f 100644 --- a/evmbin/Cargo.toml +++ b/evmbin/Cargo.toml @@ -16,6 +16,7 @@ serde_derive = "1.0" ethcore = { path = "../ethcore" } ethcore-util = { path = "../util" } evm = { path = "../ethcore/evm" } +panic_hook = { path = "../panic_hook" } [features] evm-debug = ["ethcore/evm-debug-tests"] diff --git a/evmbin/src/main.rs b/evmbin/src/main.rs index df9b088d0..7e89c7c7f 100644 --- a/evmbin/src/main.rs +++ b/evmbin/src/main.rs @@ -26,6 +26,7 @@ extern crate serde_derive; extern crate docopt; extern crate ethcore_util as util; extern crate evm; +extern crate panic_hook; use std::sync::Arc; use std::{fmt, fs}; @@ -63,6 +64,8 @@ General options: fn main() { + panic_hook::set(); + let args: Args = Docopt::new(USAGE).and_then(|d| d.deserialize()).unwrap_or_else(|e| e.exit()); if args.flag_json { diff --git a/panic_hook/Cargo.toml b/panic_hook/Cargo.toml new file mode 100644 index 000000000..eb70c19f1 --- /dev/null +++ b/panic_hook/Cargo.toml @@ -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 "] + +[dependencies] +backtrace = "0.3.2" diff --git a/panic_hook/src/lib.rs b/panic_hook/src/lib.rs new file mode 100644 index 000000000..a1487eb78 --- /dev/null +++ b/panic_hook/src/lib.rs @@ -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 . + +//! 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(""); + 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); +} diff --git a/parity/main.rs b/parity/main.rs index 72579be74..8bd6bf53f 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -57,6 +57,7 @@ extern crate ethcore_logger; extern crate ethcore_util as util; extern crate ethkey; extern crate ethsync; +extern crate panic_hook; extern crate parity_hash_fetch as hash_fetch; extern crate parity_ipfs_api; extern crate parity_local_store as local_store; @@ -315,8 +316,7 @@ macro_rules! trace_main { } fn main() { - // Always print backtrace on panic. - env::set_var("RUST_BACKTRACE", "1"); + panic_hook::set(); // assuming the user is not running with `--force-direct`, then: // if argv[0] == "parity" and this executable != ~/.parity-updates/parity, run that instead.