Bug 1373881 - Call default panic hook after crashreporter. r=rillian, a=jcristau
authorJ. Ryan Stinnett <jryans@gmail.com>
Fri, 07 Jul 2017 19:19:07 -0500
changeset 414289 5e694949cac6fa216cb0579814a9c13d538542c2
parent 414288 d25975fc2946c4b8a5e0b38c01b58e859b42de20
child 414290 87127a0ad8e6849dbb9e039f93082966d70e2766
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrillian, jcristau
bugs1373881
milestone55.0
Bug 1373881 - Call default panic hook after crashreporter. r=rillian, a=jcristau 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
@@ -43,31 +43,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)) => {