ssh: Log error when remote server panics (#18853)

Release Notes:

- N/A
This commit is contained in:
Bennet Bo Fenner 2024-10-08 12:57:47 +02:00 committed by GitHub
parent be531653a4
commit f0566d54eb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 51 additions and 4 deletions

1
Cargo.lock generated
View file

@ -9163,6 +9163,7 @@ name = "remote_server"
version = "0.1.0"
dependencies = [
"anyhow",
"backtrace",
"cargo_toml",
"clap",
"client",

View file

@ -22,6 +22,7 @@ test-support = ["fs/test-support"]
[dependencies]
anyhow.workspace = true
backtrace = "0.3"
clap.workspace = true
client.workspace = true
env_logger.workspace = true

View file

@ -37,7 +37,7 @@ fn main() {
#[cfg(not(windows))]
fn main() -> Result<()> {
use remote_server::unix::{execute_proxy, execute_run, init_logging};
use remote_server::unix::{execute_proxy, execute_run, init};
let cli = Cli::parse();
@ -48,11 +48,11 @@ fn main() -> Result<()> {
stdin_socket,
stdout_socket,
}) => {
init_logging(Some(log_file))?;
init(Some(log_file))?;
execute_run(pid_file, stdin_socket, stdout_socket)
}
Some(Commands::Proxy { identifier }) => {
init_logging(None)?;
init(None)?;
execute_proxy(identifier)
}
Some(Commands::Version) => {

View file

@ -20,7 +20,13 @@ use std::{
sync::Arc,
};
pub fn init_logging(log_file: Option<PathBuf>) -> Result<()> {
pub fn init(log_file: Option<PathBuf>) -> Result<()> {
init_logging(log_file)?;
init_panic_hook();
Ok(())
}
fn init_logging(log_file: Option<PathBuf>) -> Result<()> {
if let Some(log_file) = log_file {
let target = Box::new(if log_file.exists() {
std::fs::OpenOptions::new()
@ -46,6 +52,45 @@ pub fn init_logging(log_file: Option<PathBuf>) -> Result<()> {
Ok(())
}
fn init_panic_hook() {
std::panic::set_hook(Box::new(|info| {
let payload = info
.payload()
.downcast_ref::<&str>()
.map(|s| s.to_string())
.or_else(|| info.payload().downcast_ref::<String>().cloned())
.unwrap_or_else(|| "Box<Any>".to_string());
let backtrace = backtrace::Backtrace::new();
let mut backtrace = backtrace
.frames()
.iter()
.flat_map(|frame| {
frame
.symbols()
.iter()
.filter_map(|frame| Some(format!("{:#}", frame.name()?)))
})
.collect::<Vec<_>>();
// Strip out leading stack frames for rust panic-handling.
if let Some(ix) = backtrace
.iter()
.position(|name| name == "rust_begin_unwind")
{
backtrace.drain(0..=ix);
}
log::error!(
"server: panic occurred: {}\nBacktrace:\n{}",
payload,
backtrace.join("\n")
);
std::process::abort();
}));
}
fn start_server(
stdin_listener: UnixListener,
stdout_listener: UnixListener,