From a5a075c4e19f081376ccabece6978c67efa764ab Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Thu, 3 Oct 2019 02:31:05 +0000 Subject: [PATCH] Bug 1465709 - Hook rust OOM handler on rustc 1.28. r=froydnj Bug 1458161 added a rust OOM handler based on an unstable API that was removed in 1.27, replaced with something that didn't allow to get the failed allocation size. Latest 1.28 nightly (2018-06-13) has https://github.com/rust-lang/rust/pull/50880, https://github.com/rust-lang/rust/pull/51264 and https://github.com/rust-lang/rust/pull/51241 merged, which allow to hook the OOM handler and get the failed allocation size again. Because this is still an unstable API, we explicitly depend on strict versions of rustc. We also explicitly error out if automation builds end up using a rustc version that doesn't allow us to get the allocation size for rust OOM, because we don't want that to happen without knowing. UltraBlame original commit: 5182bca90d0609f182d5a7b6b48ed2ffbbce32c2 --- toolkit/crashreporter/nsExceptionHandler.cpp | 3 +++ toolkit/library/gtest/rust/Cargo.toml | 1 + toolkit/library/rust/Cargo.toml | 1 + toolkit/library/rust/gkrust-features.mozbuild | 7 +++++ toolkit/library/rust/shared/Cargo.toml | 1 + toolkit/library/rust/shared/build.rs | 2 +- toolkit/library/rust/shared/lib.rs | 26 +++++++++++++++++++ 7 files changed, 40 insertions(+), 1 deletion(-) diff --git a/toolkit/crashreporter/nsExceptionHandler.cpp b/toolkit/crashreporter/nsExceptionHandler.cpp index fb95dd17f4b82..dee9efc55c518 100644 --- a/toolkit/crashreporter/nsExceptionHandler.cpp +++ b/toolkit/crashreporter/nsExceptionHandler.cpp @@ -117,6 +117,7 @@ using mozilla::ipc::CrashReporterClient; extern "C" { void install_rust_panic_hook(); + void install_rust_oom_hook(); bool get_rust_panic_reason(char** reason, size_t* length); } @@ -1687,6 +1688,8 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory, install_rust_panic_hook(); + install_rust_oom_hook(); + InitThreadAnnotation(); return NS_OK; diff --git a/toolkit/library/gtest/rust/Cargo.toml b/toolkit/library/gtest/rust/Cargo.toml index 51aa6cf819616..2aba59e7e2547 100644 --- a/toolkit/library/gtest/rust/Cargo.toml +++ b/toolkit/library/gtest/rust/Cargo.toml @@ -14,6 +14,7 @@ cubeb_pulse_rust = ["gkrust-shared/cubeb_pulse_rust"] gecko_debug = ["gkrust-shared/gecko_debug"] simd-accel = ["gkrust-shared/simd-accel"] oom_with_global_alloc = ["gkrust-shared/oom_with_global_alloc"] +oom_with_hook = ["gkrust-shared/oom_with_hook"] moz_memory = ["gkrust-shared/moz_memory"] [dependencies] diff --git a/toolkit/library/rust/Cargo.toml b/toolkit/library/rust/Cargo.toml index da850f0267482..308ea06c20d09 100644 --- a/toolkit/library/rust/Cargo.toml +++ b/toolkit/library/rust/Cargo.toml @@ -14,6 +14,7 @@ cubeb_pulse_rust = ["gkrust-shared/cubeb_pulse_rust"] gecko_debug = ["gkrust-shared/gecko_debug"] simd-accel = ["gkrust-shared/simd-accel"] oom_with_global_alloc = ["gkrust-shared/oom_with_global_alloc"] +oom_with_hook = ["gkrust-shared/oom_with_hook"] moz_memory = ["gkrust-shared/moz_memory"] [dependencies] diff --git a/toolkit/library/rust/gkrust-features.mozbuild b/toolkit/library/rust/gkrust-features.mozbuild index 99d3442c317d9..1cdc8535c3d44 100644 --- a/toolkit/library/rust/gkrust-features.mozbuild +++ b/toolkit/library/rust/gkrust-features.mozbuild @@ -30,3 +30,10 @@ if CONFIG['MOZ_MEMORY']: # A string test is not the best thing, but it works well enough here. if CONFIG['RUSTC_VERSION'] < "1.27": gkrust_features += ['oom_with_global_alloc'] +elif CONFIG['RUSTC_VERSION'] >= "1.28" and CONFIG['RUSTC_VERSION'] < "1.29": + gkrust_features += ['oom_with_hook'] +elif not CONFIG['MOZ_AUTOMATION']: + # We don't want builds on automation to unwillingly stop annotating OOM + # crash reports from rust. + error('Builds on automation must use a version of rust that supports OOM ' + 'hooking') diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml index 85f6839401b59..0661f152ccc99 100644 --- a/toolkit/library/rust/shared/Cargo.toml +++ b/toolkit/library/rust/shared/Cargo.toml @@ -38,6 +38,7 @@ cubeb_pulse_rust = ["cubeb-sys", "cubeb-pulse"] gecko_debug = ["geckoservo/gecko_debug", "nsstring/gecko_debug"] simd-accel = ["encoding_c/simd-accel", "encoding_glue/simd-accel"] oom_with_global_alloc = [] +oom_with_hook = [] moz_memory = ["mp4parse_capi/mp4parse_fallible"] [lib] diff --git a/toolkit/library/rust/shared/build.rs b/toolkit/library/rust/shared/build.rs index e5f38a9920d9d..f80cf4825d038 100644 --- a/toolkit/library/rust/shared/build.rs +++ b/toolkit/library/rust/shared/build.rs @@ -3,6 +3,6 @@ fn main() { - #[cfg(feature = "oom_with_global_alloc")] + #[cfg(any(feature = "oom_with_global_alloc", feature = "oom_with_hook"))] println!("cargo:rustc-env=RUSTC_BOOTSTRAP=1"); } diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs index 54e9ccea551eb..dfd21909cac1e 100644 --- a/toolkit/library/rust/shared/lib.rs +++ b/toolkit/library/rust/shared/lib.rs @@ -4,6 +4,7 @@ #![cfg_attr(feature = "oom_with_global_alloc", feature(global_allocator, alloc, alloc_system, allocator_api))] +#![cfg_attr(feature = "oom_with_hook", feature(oom_hook))] #[cfg(feature="servo")] extern crate geckoservo; @@ -218,3 +219,28 @@ mod global_alloc { #[cfg(feature = "oom_with_global_alloc")] #[global_allocator] static HEAP: global_alloc::GeckoHeap = global_alloc::GeckoHeap; + +#[cfg(feature = "oom_with_hook")] +mod oom_hook { + use std::alloc::{Layout, set_oom_hook}; + + extern "C" { + fn GeckoHandleOOM(size: usize) -> !; + } + + pub fn hook(layout: Layout) { + unsafe { + GeckoHandleOOM(layout.size()); + } + } + + pub fn install() { + set_oom_hook(hook); + } +} + +#[no_mangle] +pub extern "C" fn install_rust_oom_hook() { + #[cfg(feature = "oom_with_hook")] + oom_hook::install(); +}