Bug 1373881 - Call default panic hook after crashreporter. r=rillian draft
authorJ. Ryan Stinnett <jryans@gmail.com>
Fri, 07 Jul 2017 19:19:07 -0500
changeset 605560 0e9909b986d2fed508d4005bf8249e14286cd310
parent 604699 0da28256801b8fa5465049c6dca59e8f98c409ea
child 636535 0ef6e23d3bf5567964646ce990404fd343ecb29a
push id67455
push userbmo:jryans@gmail.com
push dateSat, 08 Jul 2017 00:21:16 +0000
reviewersrillian
bugs1373881
milestone56.0a1
Bug 1373881 - Call default panic hook after crashreporter. r=rillian Crash reporter installs a special Rust panic hook to grab the panic reason. However, we still want to call the default hook as well, so that we still print the reason and backtrace to the console. MozReview-Commit-ID: JlCamBPb51X
toolkit/library/rust/shared/lib.rs
--- a/toolkit/library/rust/shared/lib.rs
+++ b/toolkit/library/rust/shared/lib.rs
@@ -45,31 +45,35 @@ static mut PANIC_REASON: Option<(*const 
 /// We don't store this in `gMozCrashReason` because:
 /// a) Rust strings aren't null-terminated, so we'd have to allocate
 ///    memory to get a null-terminated string
 /// b) The panic=abort handler is going to call `abort()` on non-Windows,
 ///    which is `mozalloc_abort` for us, which will use `MOZ_CRASH` and
 ///    overwrite `gMozCrashReason` with an unhelpful string.
 #[no_mangle]
 pub extern "C" fn install_rust_panic_hook() {
-    panic::set_hook(Box::new(|info| {
+    let default_hook = panic::take_hook();
+    panic::set_hook(Box::new(move |info| {
         // Try to handle &str/String payloads, which should handle 99% of cases.
         let payload = info.payload();
         // We'll hold a raw *const str here, but it will be OK because
         // Rust is going to abort the process before the payload could be
         // deallocated.
         if let Some(s) = payload.downcast_ref::<&str>() {
             unsafe { PANIC_REASON = Some((*s as *const str, s.len())) }
         } else if let Some(s) = payload.downcast_ref::<String>() {
             unsafe { PANIC_REASON = Some((s.as_str() as *const str, s.len())) }
         } else {
             // Not the most helpful thing, but seems unlikely to happen
             // in practice.
             println!("Unhandled panic payload!");
         }
+        // Fall through to the default hook so we still print the reason and
+        // backtrace to the console.
+        default_hook(info);
     }));
 }
 
 #[no_mangle]
 pub extern "C" fn get_rust_panic_reason(reason: *mut *const c_char, length: *mut usize) -> bool {
     unsafe {
         match PANIC_REASON {
             Some((s, len)) => {