From a4f56459268869f0188607ae2a897d6bf1136208 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Nov 2022 11:26:46 -0500 Subject: [PATCH] repo: Avoid potential double unwind when writing panic value Thanks to @shinmao for the report! Closes: https://github.com/ostreedev/ostree/issues/2775 --- .../repo_checkout_filter.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/rust-bindings/src/repo_checkout_at_options/repo_checkout_filter.rs b/rust-bindings/src/repo_checkout_at_options/repo_checkout_filter.rs index 755efea2..c63b3ffb 100644 --- a/rust-bindings/src/repo_checkout_at_options/repo_checkout_filter.rs +++ b/rust-bindings/src/repo_checkout_at_options/repo_checkout_filter.rs @@ -107,18 +107,26 @@ pub(super) unsafe extern "C" fn filter_trampoline_unwindsafe( /// /// If the panic value is either `&str` or `String`, we print it. Otherwise, we don't. fn print_panic(panic: Box) { - eprintln!("A Rust callback invoked by C code panicked."); - eprintln!("Unwinding across FFI boundaries is Undefined Behavior so abort() will be called."); + use std::io::Write; + let stderr = std::io::stderr(); + let mut stderr = stderr.lock(); + // Directly write to stderr instead of eprintln!() as that function panics + // if writing fails, which would involve a double panic which we don't want. + let _ = stderr.write_all( + r#"A Rust callback invoked by C code panicked. +Unwinding across FFI boundaries is Undefined Behavior so abort() will be called."# + .as_bytes(), + ); let msg = { if let Some(s) = panic.as_ref().downcast_ref::<&str>() { s } else if let Some(s) = panic.as_ref().downcast_ref::() { s } else { - "UNABLE TO SHOW VALUE OF PANIC" + "(non-string panic value)" } }; - eprintln!("Panic value: {}", msg); + let _ = stderr.write_all(msg.as_bytes()); } #[cfg(test)]