Merge pull request #2776 from cgwalters/fix-potential-double-unwind

repo: Avoid potential double unwind when writing panic value
This commit is contained in:
Luca Bruno 2022-11-22 11:18:14 +00:00 committed by GitHub
commit d9bb160a7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 12 additions and 4 deletions

View File

@ -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. /// If the panic value is either `&str` or `String`, we print it. Otherwise, we don't.
fn print_panic(panic: Box<dyn Any>) { fn print_panic(panic: Box<dyn Any>) {
eprintln!("A Rust callback invoked by C code panicked."); use std::io::Write;
eprintln!("Unwinding across FFI boundaries is Undefined Behavior so abort() will be called."); 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 = { let msg = {
if let Some(s) = panic.as_ref().downcast_ref::<&str>() { if let Some(s) = panic.as_ref().downcast_ref::<&str>() {
s s
} else if let Some(s) = panic.as_ref().downcast_ref::<String>() { } else if let Some(s) = panic.as_ref().downcast_ref::<String>() {
s s
} else { } else {
"UNABLE TO SHOW VALUE OF PANIC" "(non-string panic value)"
} }
}; };
eprintln!("Panic value: {}", msg); let _ = stderr.write_all(msg.as_bytes());
} }
#[cfg(test)] #[cfg(test)]