aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-11-04 16:33:05 +0100
committerAlex Auvolat <alex@adnab.me>2022-11-04 16:39:02 +0100
commite03d9062f7f21dd0493dd82a7dcf82f2cd035943 (patch)
treeb96e5830c8a40d25988e0e496a52eba4c71454c5 /src
parent8d3bbf5703f97ff1f468bc09fc515b6c12b027a3 (diff)
downloadgarage-e03d9062f7f21dd0493dd82a7dcf82f2cd035943.tar.gz
garage-e03d9062f7f21dd0493dd82a7dcf82f2cd035943.zip
Show a nice message and a backtrace when Garage panics
Diffstat (limited to 'src')
-rw-r--r--src/garage/Cargo.toml1
-rw-r--r--src/garage/main.rs56
2 files changed, 41 insertions, 16 deletions
diff --git a/src/garage/Cargo.toml b/src/garage/Cargo.toml
index 35caf2c1..69852db7 100644
--- a/src/garage/Cargo.toml
+++ b/src/garage/Cargo.toml
@@ -30,6 +30,7 @@ garage_table = { version = "0.8.0", path = "../table" }
garage_util = { version = "0.8.0", path = "../util" }
garage_web = { version = "0.8.0", path = "../web" }
+backtrace = "0.3"
bytes = "1.0"
bytesize = "1.1"
timeago = "0.3"
diff --git a/src/garage/main.rs b/src/garage/main.rs
index 5b2a85c0..edda734b 100644
--- a/src/garage/main.rs
+++ b/src/garage/main.rs
@@ -65,21 +65,6 @@ struct Opt {
#[tokio::main]
async fn main() {
- if std::env::var("RUST_LOG").is_err() {
- std::env::set_var("RUST_LOG", "netapp=info,garage=info")
- }
- tracing_subscriber::fmt()
- .with_writer(std::io::stderr)
- .with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
- .init();
- sodiumoxide::init().expect("Unable to init sodiumoxide");
-
- // Abort on panic (same behavior as in Go)
- std::panic::set_hook(Box::new(|panic_info| {
- error!("{}", panic_info.to_string());
- std::process::abort();
- }));
-
// Initialize version and features info
let features = &[
#[cfg(feature = "k2v")]
@@ -108,12 +93,51 @@ async fn main() {
}
garage_util::version::init_features(features);
- // Parse arguments
let version = format!(
"{} [features: {}]",
garage_util::version::garage_version(),
features.join(", ")
);
+
+ // Initialize panic handler that aborts on panic and shows a nice message.
+ // By default, Tokio continues runing normally when a task panics. We want
+ // to avoid this behavior in Garage as this would risk putting the process in an
+ // unknown/uncontrollable state. We prefer to exit the process and restart it
+ // from scratch, so that it boots back into a fresh, known state.
+ let panic_version_info = version.clone();
+ std::panic::set_hook(Box::new(move |panic_info| {
+ eprintln!("======== PANIC (internal Garage error) ========");
+ eprintln!("{}", panic_info);
+ eprintln!();
+ eprintln!("Panics are internal errors that Garage is unable to handle on its own.");
+ eprintln!("They can be caused by bugs in Garage's code, or by corrupted data in");
+ eprintln!("the node's storage. If you feel that this error is likely to be a bug");
+ eprintln!("in Garage, please report it on our issue tracker a the following address:");
+ eprintln!();
+ eprintln!(" https://git.deuxfleurs.fr/Deuxfleurs/garage/issues");
+ eprintln!();
+ eprintln!("Please include the last log messages and the the full backtrace below in");
+ eprintln!("your bug report, as well as any relevant information on the context in");
+ eprintln!("which Garage was running when this error occurred.");
+ eprintln!();
+ eprintln!("GARAGE VERSION: {}", panic_version_info);
+ eprintln!();
+ eprintln!("BACKTRACE:");
+ eprintln!("{:?}", backtrace::Backtrace::new());
+ std::process::abort();
+ }));
+
+ // Initialize logging as well as other libraries used in Garage
+ if std::env::var("RUST_LOG").is_err() {
+ std::env::set_var("RUST_LOG", "netapp=info,garage=info")
+ }
+ tracing_subscriber::fmt()
+ .with_writer(std::io::stderr)
+ .with_env_filter(tracing_subscriber::filter::EnvFilter::from_default_env())
+ .init();
+ sodiumoxide::init().expect("Unable to init sodiumoxide");
+
+ // Parse arguments and dispatch command line
let opt = Opt::from_clap(&Opt::clap().version(version.as_str()).get_matches());
let res = match opt.cmd {