aboutsummaryrefslogtreecommitdiffstats
path: root/third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch')
-rw-r--r--third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch226
1 files changed, 226 insertions, 0 deletions
diff --git a/third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch b/third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
new file mode 100644
index 00000000000..674e9801466
--- /dev/null
+++ b/third_party/webrender/patches/0001-Add-signal-handler-to-catch-segfault-in-build-script.patch
@@ -0,0 +1,226 @@
+From 34d968adeda2e06b057a13d14a88df5766b38eda Mon Sep 17 00:00:00 2001
+From: Josh Matthews <josh@joshmatthews.net>
+Date: Mon, 6 Jul 2020 14:37:42 -0400
+Subject: [PATCH] Add signal handler to catch segfault in build script.
+
+---
+ Cargo.lock | 11 +++++
+ webrender/Cargo.toml | 5 ++
+ webrender/backtrace.rs | 103 +++++++++++++++++++++++++++++++++++++++++
+ webrender/build.rs | 30 ++++++++++++
+ 4 files changed, 149 insertions(+)
+ create mode 100644 webrender/backtrace.rs
+
+diff --git a/Cargo.lock b/Cargo.lock
+index afdd336ae..cf91162d5 100644
+--- a/Cargo.lock
++++ b/Cargo.lock
+@@ -1477,6 +1477,14 @@ dependencies = [
+ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
+ ]
+
++[[package]]
++name = "sig"
++version = "1.0.0"
++source = "registry+https://github.com/rust-lang/crates.io-index"
++dependencies = [
++ "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)",
++]
++
+ [[package]]
+ name = "slab"
+ version = "0.4.2"
+@@ -1750,6 +1758,7 @@ dependencies = [
+ name = "webrender"
+ version = "0.61.0"
+ dependencies = [
++ "backtrace 0.3.46 (registry+https://github.com/rust-lang/crates.io-index)",
+ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -1780,6 +1789,7 @@ dependencies = [
+ "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.51 (registry+https://github.com/rust-lang/crates.io-index)",
++ "sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "svg_fmt 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -2178,6 +2188,7 @@ dependencies = [
+ "checksum servo-freetype-sys 4.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4ccb6d0d32d277d3ef7dea86203d8210945eb7a45fba89dd445b3595dd0dfc"
+ "checksum sha-1 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
+ "checksum shared_library 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11"
++"checksum sig 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6567e29578f9bfade6a5d94a32b9a4256348358d2a3f448cab0021f9a02614a2"
+ "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
+ "checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
+ "checksum smallvec 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05720e22615919e4734f6a99ceae50d00226c3c5aca406e102ebc33298214e0a"
+diff --git a/webrender/Cargo.toml b/webrender/Cargo.toml
+index dcf26d913..f7679da57 100644
+--- a/webrender/Cargo.toml
++++ b/webrender/Cargo.toml
+@@ -59,6 +59,11 @@ tracy-rs = { version = "0.1" }
+ mozangle = "0.3.1"
+ rand = "0.4"
+
++[target.'cfg(any(target_os = "macos", target_os = "linux"))'.build-dependencies]
++backtrace = "0.3"
++sig = "1.0"
++libc = "0.2"
++
+ [target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
+ freetype = { version = "0.4", default-features = false }
+ libc = "0.2"
+diff --git a/webrender/backtrace.rs b/webrender/backtrace.rs
+new file mode 100644
+index 000000000..aa6bb6b32
+--- /dev/null
++++ b/webrender/backtrace.rs
+@@ -0,0 +1,103 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
++
++//! Similar to `println!("{:?}", Backtrace::new())`, but doesn’t allocate.
++//!
++//! Seems to fix some deadlocks: https://github.com/servo/servo/issues/24881
++//!
++//! FIXME: if/when a future version of the `backtrace` crate has
++//! https://github.com/rust-lang/backtrace-rs/pull/265, use that instead.
++
++use std::fmt::{self, Write};
++use backtrace::{BytesOrWideString, PrintFmt};
++
++#[inline(never)]
++pub(crate) fn print(w: &mut dyn std::io::Write) -> Result<(), std::io::Error> {
++ write!(w, "{:?}", Print {
++ print_fn_address: print as usize,
++ })
++}
++
++struct Print {
++ print_fn_address: usize,
++}
++
++impl fmt::Debug for Print {
++ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
++ // Safety: we’re in a signal handler that is about to call `libc::_exit`.
++ // Potential data races from using `*_unsynchronized` functions are perhaps
++ // less bad than potential deadlocks?
++ unsafe {
++ let mut print_fn_frame = 0;
++ let mut frame_count = 0;
++ backtrace::trace_unsynchronized(|frame| {
++ let found = frame.symbol_address() as usize == self.print_fn_address;
++ if found {
++ print_fn_frame = frame_count;
++ }
++ frame_count += 1;
++ !found
++ });
++
++ let mode = PrintFmt::Short;
++ let mut p = print_path;
++ let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
++ f.add_context()?;
++ let mut result = Ok(());
++ let mut frame_count = 0;
++ backtrace::trace_unsynchronized(|frame| {
++ let skip = frame_count < print_fn_frame;
++ frame_count += 1;
++ if skip {
++ return true
++ }
++
++ let mut frame_fmt = f.frame();
++ let mut any_symbol = false;
++ backtrace::resolve_frame_unsynchronized(frame, |symbol| {
++ any_symbol = true;
++ if let Err(e) = frame_fmt.symbol(frame, symbol) {
++ result = Err(e)
++ }
++ });
++ if !any_symbol {
++ if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
++ result = Err(e)
++ }
++ }
++ result.is_ok()
++ });
++ result?;
++ f.finish()
++ }
++ }
++}
++
++fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result {
++ match path {
++ BytesOrWideString::Bytes(mut bytes) => {
++ loop {
++ match std::str::from_utf8(bytes) {
++ Ok(s) => {
++ fmt.write_str(s)?;
++ break;
++ }
++ Err(err) => {
++ fmt.write_char(std::char::REPLACEMENT_CHARACTER)?;
++ match err.error_len() {
++ Some(len) => bytes = &bytes[err.valid_up_to() + len..],
++ None => break,
++ }
++ }
++ }
++ }
++ }
++ BytesOrWideString::Wide(wide) => {
++ for c in std::char::decode_utf16(wide.iter().cloned()) {
++ fmt.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
++ }
++ }
++ }
++ Ok(())
++}
+diff --git a/webrender/build.rs b/webrender/build.rs
+index 3521d1342..36a7f17a8 100644
+--- a/webrender/build.rs
++++ b/webrender/build.rs
+@@ -244,7 +244,37 @@ fn write_optimized_shaders(shader_dir: &Path, shader_file: &mut File, out_dir: &
+ Ok(())
+ }
+
++#[cfg(any(target_os = "macos", target_os = "linux"))]
++mod backtrace;
++
++#[cfg(any(target_os = "macos", target_os = "linux"))]
++extern "C" fn handler(sig: i32) {
++ use std::sync::atomic;
++ static BEEN_HERE_BEFORE: atomic::AtomicBool = atomic::AtomicBool::new(false);
++ if !BEEN_HERE_BEFORE.swap(true, atomic::Ordering::SeqCst) {
++ let stdout = std::io::stdout();
++ let mut stdout = stdout.lock();
++ let _ = write!(&mut stdout, "Stack trace");
++ if let Some(name) = std::thread::current().name() {
++ let _ = write!(&mut stdout, " for thread \"{}\"", name);
++ }
++ let _ = write!(&mut stdout, "\n");
++ let _ = backtrace::print(&mut stdout);
++ }
++ unsafe {
++ libc::_exit(sig);
++ }
++}
++
+ fn main() -> Result<(), std::io::Error> {
++ #[cfg(any(target_os = "macos", target_os = "linux"))]
++ {
++ sig::signal!(sig::ffi::Sig::SEGV, handler); // handle segfaults
++ sig::signal!(sig::ffi::Sig::ILL, handler); // handle stack overflow and unsupported CPUs
++ sig::signal!(sig::ffi::Sig::IOT, handler); // handle double panics
++ sig::signal!(sig::ffi::Sig::BUS, handler); // handle invalid memory access
++ }
++
+ let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());
+
+ let shaders_file_path = Path::new(&out_dir).join("shaders.rs");
+--
+2.39.2
+