mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-11 20:48:49 +00:00
Crash reporting
Provide an easy way to send panic messages, stacktrace and version info, via Sentry (https://sentry.io). For unclear reasons, this triggers a seemingly unrelated compile error: error[E0282]: type annotations needed --> src/reader.rs:2000:81 | 2000 | if EXIT_STATE.load(Ordering::Relaxed) != ExitState::FinishedHandlers as _ { | ^ cannot infer type
This commit is contained in:
parent
d3ed3037c5
commit
1c69fa22df
4 changed files with 1554 additions and 12 deletions
1499
Cargo.lock
generated
1499
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -50,6 +50,7 @@ fish-printf = { path = "./printf", features = ["widestring"] }
|
|||
# available on macOS < 10.12. We can enable "getrandom" when we raise the
|
||||
# minimum supported version to 10.12.
|
||||
rand = { version = "0.8.5", default-features = false, features = ["small_rng"] }
|
||||
sentry = "0.35.0"
|
||||
widestring = "1.1.0"
|
||||
# We need 0.9.0 specifically for some crash fixes.
|
||||
terminfo = "0.9.0"
|
||||
|
|
64
src/panic.rs
64
src/panic.rs
|
@ -1,11 +1,15 @@
|
|||
use std::{
|
||||
panic::{set_hook, take_hook, UnwindSafe},
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
panic::{set_hook, take_hook, PanicInfo, UnwindSafe},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use libc::{SIGINT, SIG_DFL, STDIN_FILENO};
|
||||
use once_cell::sync::OnceCell;
|
||||
use sentry::integrations::panic::PanicIntegration;
|
||||
|
||||
use crate::{
|
||||
common::{read_blocked, PROGRAM_NAME},
|
||||
|
@ -54,12 +58,10 @@ pub fn panic_handler(main: impl FnOnce() -> i32 + UnwindSafe) -> ! {
|
|||
unsafe { libc::sigaction(SIGINT, &act, std::ptr::null_mut()) };
|
||||
}
|
||||
|
||||
let mut buf = [0_u8; 1];
|
||||
while let Ok(n) = read_blocked(STDIN_FILENO, &mut buf) {
|
||||
if n == 0 || matches!(buf[0], b'q' | b'\n' | b'\r') {
|
||||
eprintf!("\n");
|
||||
break;
|
||||
}
|
||||
if read_line("Type 'report' to send a bug report: ") == b"report" {
|
||||
report_crash(panic_info);
|
||||
} else {
|
||||
eprintf!("Not sending crash report\n");
|
||||
}
|
||||
}
|
||||
std::process::abort();
|
||||
|
@ -72,3 +74,49 @@ pub fn panic_handler(main: impl FnOnce() -> i32 + UnwindSafe) -> ! {
|
|||
asan_maybe_exit(exit_status);
|
||||
std::process::exit(exit_status)
|
||||
}
|
||||
|
||||
fn read_line(prompt: &str) -> Vec<u8> {
|
||||
eprintf!("%s", prompt);
|
||||
let mut line = vec![];
|
||||
let mut c = [0_u8; 1];
|
||||
while let Ok(n) = read_blocked(STDIN_FILENO, &mut c) {
|
||||
let c = c[0];
|
||||
if n == 0 || matches!(c, b'\n' | b'\r') {
|
||||
break;
|
||||
}
|
||||
line.push(c);
|
||||
}
|
||||
line
|
||||
}
|
||||
|
||||
fn report_crash(panic_info: &PanicInfo) {
|
||||
let email = read_line("optional email address or username: ");
|
||||
let message = read_line("optional other info such as steps to reproduce: ");
|
||||
|
||||
let _sentry = sentry::init(("https://cef1ac6352bd78fa3dfe5e3e51e3358c@o4508437566586880.ingest.us.sentry.io/4508437569142784", sentry::ClientOptions {
|
||||
release: sentry::release_name!(),
|
||||
default_integrations: false,
|
||||
integrations: vec![
|
||||
Arc::new(sentry::integrations::backtrace::AttachStacktraceIntegration),
|
||||
Arc::new(sentry::integrations::debug_images::DebugImagesIntegration::default()),
|
||||
Arc::new(sentry::integrations::contexts::ContextIntegration::default()),
|
||||
Arc::new(sentry::integrations::backtrace::ProcessStacktraceIntegration),
|
||||
],
|
||||
..Default::default()
|
||||
}));
|
||||
let mut event = PanicIntegration::new().event_from_panic_info(panic_info);
|
||||
let event_id = event.event_id;
|
||||
event.user = Some(sentry::User {
|
||||
email: Some(String::from_utf8_lossy(&email).to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
event.message = Some(String::from_utf8_lossy(&message).to_string());
|
||||
eprintf!("Sending crash report\n");
|
||||
sentry::Hub::with_active(|hub| {
|
||||
hub.capture_event(event);
|
||||
if let Some(client) = hub.client() {
|
||||
client.flush(None);
|
||||
}
|
||||
});
|
||||
eprintf!("Sent crash report with ID %s\n", event_id.to_string());
|
||||
}
|
||||
|
|
|
@ -1991,7 +1991,7 @@ impl<'a> Reader<'a> {
|
|||
zelf.clear_pager();
|
||||
}
|
||||
|
||||
if EXIT_STATE.load(Ordering::Relaxed) != ExitState::FinishedHandlers as _ {
|
||||
if EXIT_STATE.load(Ordering::Relaxed) != ExitState::FinishedHandlers as u8 {
|
||||
// The order of the two conditions below is important. Try to restore the mode
|
||||
// in all cases, but only complain if interactive.
|
||||
if unsafe { libc::tcsetattr(zelf.conf.inputfd, TCSANOW, &old_modes) } == -1
|
||||
|
|
Loading…
Reference in a new issue