diff --git a/Cargo.lock b/Cargo.lock index cc2a504c..2bfb0b5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -539,6 +539,7 @@ dependencies = [ name = "jay-config" version = "0.1.0" dependencies = [ + "backtrace", "bincode", "futures-util", "log", diff --git a/jay-config/Cargo.toml b/jay-config/Cargo.toml index 896649dc..15246115 100644 --- a/jay-config/Cargo.toml +++ b/jay-config/Cargo.toml @@ -12,3 +12,4 @@ log = "0.4.14" futures-util = { version = "0.3.30", features = ["io"] } uapi = "0.2.10" thiserror = "1.0.57" +backtrace = "0.3.69" diff --git a/jay-config/src/_private/logging.rs b/jay-config/src/_private/logging.rs index 28836038..04080155 100644 --- a/jay-config/src/_private/logging.rs +++ b/jay-config/src/_private/logging.rs @@ -1,11 +1,31 @@ use { crate::logging::LogLevel, + backtrace::Backtrace, log::{Level, LevelFilter, Log, Metadata, Record}, }; pub fn init() { let _ = log::set_logger(&Logger); log::set_max_level(LevelFilter::Trace); + std::panic::set_hook(Box::new(|p| { + if let Some(loc) = p.location() { + log::error!( + "Panic at {} line {} column {}", + loc.file(), + loc.line(), + loc.column() + ); + } else { + log::error!("Panic at unknown location"); + } + if let Some(msg) = p.payload().downcast_ref::<&str>() { + log::error!("Message: {}", msg); + } + if let Some(msg) = p.payload().downcast_ref::() { + log::error!("Message: {}", msg); + } + log::error!("Backtrace:\n{:?}", Backtrace::new()); + })); } struct Logger; diff --git a/src/config.rs b/src/config.rs index 975e4b0b..36a1e3f7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -156,9 +156,15 @@ unsafe extern "C" fn default_client_init( } impl ConfigProxy { - fn new(lib: Option, entry: &ConfigEntry, state: &Rc) -> Self { + fn new( + lib: Option, + entry: &ConfigEntry, + state: &Rc, + path: Option, + ) -> Self { let version = entry.version.min(VERSION); let data = Rc::new(ConfigProxyHandler { + path, client_data: Cell::new(ptr::null()), dropped: Cell::new(false), _lib: lib, @@ -207,12 +213,12 @@ impl ConfigProxy { unref: jay_config::_private::client::unref, handle_msg: jay_config::_private::client::handle_msg, }; - Self::new(None, &entry, state) + Self::new(None, &entry, state, None) } #[cfg(feature = "it")] pub fn for_test(state: &Rc) -> Self { - Self::new(None, &TEST_CONFIG_ENTRY, state) + Self::new(None, &TEST_CONFIG_ENTRY, state, None) } pub fn from_config_dir(state: &Rc) -> Result { @@ -251,7 +257,7 @@ impl ConfigProxy { if let Err(e) = std::fs::copy(path, ©) { return Err(ConfigError::CopyConfigFile(e)); } - let _unlink = UnlinkOnDrop(©); + let unlink = UnlinkOnDrop(©); let lib = match Library::new(©) { Ok(l) => l, Err(e) => return Err(ConfigError::CouldNotLoadLibrary(e)), @@ -261,7 +267,8 @@ impl ConfigProxy { Ok(e) => *e, Err(e) => return Err(ConfigError::LibraryDoesNotContainEntry(e)), }; - Ok(Self::new(Some(lib), entry, state)) + mem::forget(unlink); + Ok(Self::new(Some(lib), entry, state, Some(copy))) } } diff --git a/src/config/handler.rs b/src/config/handler.rs index d18e453f..22f102e4 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -55,6 +55,7 @@ use { }; pub(super) struct ConfigProxyHandler { + pub path: Option, pub client_data: Cell<*const u8>, pub dropped: Cell, pub _lib: Option, @@ -100,6 +101,12 @@ impl ConfigProxyHandler { self.timers_by_id.clear(); self.pollables.clear(); + + if let Some(path) = &self.path { + if let Err(e) = uapi::unlink(path.as_str()) { + log::error!("Could not unlink {}: {}", path, ErrorFmt(OsError(e.0))); + } + } } pub fn send(&self, msg: &ServerMessage) {