servo: Merge #11530 - Obtain backtraces automatically from segfaults (from jdm:sigsegv); r=metajack
authorJosh Matthews <josh@joshmatthews.net>
Mon, 20 Jun 2016 20:08:50 -0500
changeset 339104 74d756311b16ca74ad4618ad30119a19d877b9cb
parent 339103 135dda876b83910c41a4abd44917afb5ff2fb9b2
child 339105 36964148481864b31b627abf9f6819705dbd8818
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmetajack
servo: Merge #11530 - Obtain backtraces automatically from segfaults (from jdm:sigsegv); r=metajack <!-- Please describe your changes on the following line: --> This enables more meaningful output from observing hard crashes outside of GDB through the judicious use of a SIGSEGV signal handler. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #9371 (github issue number if applicable). - [X] There are tests for these changes OR <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: 2c4c2d8779a185a2da264f1ac11eb68b0d492fd0
servo/components/script/dom/testbinding.rs
servo/components/script/dom/webidls/TestBinding.webidl
servo/components/servo/Cargo.lock
servo/components/servo/Cargo.toml
servo/components/servo/main.rs
servo/ports/cef/Cargo.lock
servo/resources/prefs.json
--- a/servo/components/script/dom/testbinding.rs
+++ b/servo/components/script/dom/testbinding.rs
@@ -566,16 +566,25 @@ impl TestBindingMethods for TestBinding 
     fn PrefControlledAttributeDisabled(&self) -> bool { false }
     fn PrefControlledAttributeEnabled(&self) -> bool { false }
     fn PrefControlledMethodDisabled(&self) {}
     fn PrefControlledMethodEnabled(&self) {}
     fn FuncControlledAttributeDisabled(&self) -> bool { false }
     fn FuncControlledAttributeEnabled(&self) -> bool { false }
     fn FuncControlledMethodDisabled(&self) {}
     fn FuncControlledMethodEnabled(&self) {}
+
+    #[allow(unsafe_code)]
+    fn CrashHard(&self) {
+        static READ_ONLY_VALUE: i32 = 0;
+        unsafe {
+            let p: *mut u32 = &READ_ONLY_VALUE as *const _ as *mut _;
+            ptr::write_volatile(p, 0xbaadc0de);
+        }
+    }
 }
 
 impl TestBinding {
     pub fn BooleanAttributeStatic(_: GlobalRef) -> bool { false }
     pub fn SetBooleanAttributeStatic(_: GlobalRef, _: bool) {}
     pub fn ReceiveVoidStatic(_: GlobalRef) {}
     pub fn PrefControlledStaticAttributeDisabled(_: GlobalRef) -> bool { false }
     pub fn PrefControlledStaticAttributeEnabled(_: GlobalRef) -> bool { false }
--- a/servo/components/script/dom/webidls/TestBinding.webidl
+++ b/servo/components/script/dom/webidls/TestBinding.webidl
@@ -451,8 +451,13 @@ interface TestBinding {
   static readonly attribute boolean funcControlledStaticAttributeEnabled;
   [Func="TestBinding::condition_satisfied"]
   void funcControlledMethodEnabled();
   [Func="TestBinding::condition_satisfied"]
   static void funcControlledStaticMethodEnabled();
   [Func="TestBinding::condition_satisfied"]
   const unsigned short funcControlledConstEnabled = 0;
 };
+
+partial interface TestBinding {
+  [Pref="dom.testable_crash.enabled"]
+  void crashHard();
+};
--- a/servo/components/servo/Cargo.lock
+++ b/servo/components/servo/Cargo.lock
@@ -1,13 +1,14 @@
 [root]
 name = "servo"
 version = "0.0.1"
 dependencies = [
  "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "browserhtml 0.1.7 (git+https://github.com/browserhtml/browserhtml?branch=gh-pages)",
  "canvas 0.0.1",
  "canvas_traits 0.0.1",
  "compiletest_helper 0.0.1",
  "compositing 0.0.1",
  "constellation 0.0.1",
  "devtools 0.0.1",
  "devtools_traits 0.0.1",
@@ -32,16 +33,17 @@ dependencies = [
  "plugin_compiletest 0.0.1",
  "profile 0.0.1",
  "profile_tests 0.0.1",
  "profile_traits 0.0.1",
  "script 0.0.1",
  "script_layout_interface 0.0.1",
  "script_tests 0.0.1",
  "script_traits 0.0.1",
+ "sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_tests 0.0.1",
  "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "util_tests 0.0.1",
  "webdriver_server 0.0.1",
  "webrender 0.1.0 (git+https://github.com/servo/webrender)",
  "webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
@@ -2155,16 +2157,21 @@ name = "shell32-sys"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "sig"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "simd"
 version = "0.1.0"
 source = "git+https://github.com/huonw/simd#03de1cd0a278ab902b4beb402d57505f3797ea56"
 
 [[package]]
 name = "smallvec"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
--- a/servo/components/servo/Cargo.toml
+++ b/servo/components/servo/Cargo.toml
@@ -70,14 +70,18 @@ ipc-channel = {git = "https://github.com
 gleam = "0.2"
 browserhtml = {git = "https://github.com/browserhtml/browserhtml", branch = "gh-pages"}
 log = "0.3"
 env_logger = "0.3"
 euclid = "0.6.4"
 libc = "0.2"
 url = "1.0.0"
 
+[target.'cfg(not(target_os = "android"))'.dependencies]
+sig = "0.1"
+backtrace = "0.2"
+
 [target.'cfg(target_os = "android")'.dependencies]
 log = "0.3"
 android_glue = "0.1.3"
 
 [target.'cfg(not(target_os = "windows"))'.dependencies]
 gaol = {git = "https://github.com/servo/gaol"}
--- a/servo/components/servo/main.rs
+++ b/servo/components/servo/main.rs
@@ -10,31 +10,36 @@
 //! This browser's implementation of `WindowMethods` is built on top
 //! of [glutin], the cross-platform OpenGL utility and windowing
 //! library.
 //!
 //! For the engine itself look next door in lib.rs.
 //!
 //! [glutin]: https://github.com/tomaka/glutin
 
-#![feature(start)]
+#![feature(start, core_intrinsics)]
 
 #[cfg(target_os = "android")]
 #[macro_use]
 extern crate android_glue;
+#[cfg(not(target_os = "android"))]
+extern crate backtrace;
 extern crate env_logger;
 // The window backed by glutin
 extern crate glutin_app as app;
 #[cfg(target_os = "android")]
 extern crate libc;
 #[cfg(target_os = "android")]
 #[macro_use]
 extern crate log;
 // The Servo engine
 extern crate servo;
+#[cfg(not(target_os = "android"))]
+#[macro_use]
+extern crate sig;
 
 use servo::Browser;
 use servo::compositing::windowing::WindowEvent;
 use servo::util::opts::{self, ArgumentParsingResult};
 use servo::util::panicking::initiate_panic_hook;
 use std::rc::Rc;
 
 pub mod platform {
@@ -43,17 +48,43 @@ pub mod platform {
 
     #[cfg(target_os = "macos")]
     pub mod macos;
 
     #[cfg(not(target_os = "macos"))]
     pub fn deinit() {}
 }
 
+#[cfg(not(target_os = "android"))]
+fn install_crash_handler() {
+    use backtrace::Backtrace;
+    use sig::ffi::Sig;
+    use std::intrinsics::abort;
+    use std::thread;
+
+    fn handler(_sig: i32) {
+        let name = thread::current().name()
+                                    .map(|n| format!(" for thread \"{}\"", n))
+                                    .unwrap_or("".to_owned());
+        println!("Stack trace{}\n{:?}", name, Backtrace::new());
+        unsafe {
+            abort();
+        }
+    }
+
+    signal!(Sig::SEGV, handler);
+}
+
+#[cfg(target_os = "android")]
+fn install_crash_handler() {
+}
+
 fn main() {
+    install_crash_handler();
+
     // Parse the command line options and store them globally
     let opts_result = opts::from_cmdline_args(&*args());
 
     let content_process_token = if let ArgumentParsingResult::ContentProcess(token) = opts_result {
         Some(token)
     } else {
         if opts::get().is_running_problem_test && ::std::env::var("RUST_LOG").is_err() {
             ::std::env::set_var("RUST_LOG", "compositing::constellation");
--- a/servo/ports/cef/Cargo.lock
+++ b/servo/ports/cef/Cargo.lock
@@ -1904,16 +1904,17 @@ dependencies = [
  "serde_codegen 0.7.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "servo"
 version = "0.0.1"
 dependencies = [
  "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "browserhtml 0.1.7 (git+https://github.com/browserhtml/browserhtml?branch=gh-pages)",
  "canvas 0.0.1",
  "canvas_traits 0.0.1",
  "compositing 0.0.1",
  "constellation 0.0.1",
  "devtools 0.0.1",
  "devtools_traits 0.0.1",
  "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1930,16 +1931,17 @@ dependencies = [
  "msg 0.0.1",
  "net 0.0.1",
  "net_traits 0.0.1",
  "profile 0.0.1",
  "profile_traits 0.0.1",
  "script 0.0.1",
  "script_layout_interface 0.0.1",
  "script_traits 0.0.1",
+ "sig 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "util 0.0.1",
  "webdriver_server 0.0.1",
  "webrender 0.1.0 (git+https://github.com/servo/webrender)",
  "webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
 ]
 
@@ -2040,16 +2042,21 @@ name = "shell32-sys"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "winapi 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "sig"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "simd"
 version = "0.1.0"
 source = "git+https://github.com/huonw/simd#03de1cd0a278ab902b4beb402d57505f3797ea56"
 
 [[package]]
 name = "smallvec"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
--- a/servo/resources/prefs.json
+++ b/servo/resources/prefs.json
@@ -1,14 +1,15 @@
 {
   "dom.bluetooth.enabled": false,
   "dom.forcetouch.enabled": false,
   "dom.mouseevent.which.enabled": false,
   "dom.mozbrowser.enabled": false,
   "dom.serviceworker.timeout_seconds": 60,
+  "dom.testable_crash.enabled": false,
   "dom.testbinding.enabled": false,
   "gfx.webrender.enabled": false,
   "js.baseline.enabled": true,
   "js.ion.enabled": true,
   "js.asmjs.enabled": true,
   "js.strict.enabled": false,
   "js.strict.debug.enabled": false,
   "js.throw_on_asmjs_validation_failure.enabled": false,