tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit a70a0ebf9aa5b868ae15c06fdbbbc92244c743b6
parent 51d5dea24d047b55facba470e6aeafc752a44698
Author: Bob Owen <bobowencode@gmail.com>
Date:   Thu, 20 Nov 2025 11:24:28 +0000

Bug 1967071 p2 - Annotate and crash when no font file found for WR NativeFontHandle. r=jwatt

This is only on Windows Nightly to try and diagnose the issue.

Differential Revision: https://phabricator.services.mozilla.com/D273059

Diffstat:
MCargo.lock | 1+
Mgfx/layers/wr/WebRenderBridgeParent.cpp | 2++
Mgfx/webrender_bindings/Cargo.toml | 1+
Mgfx/webrender_bindings/src/moz2d_renderer.rs | 55++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mgfx/wr/webrender_api/src/lib.rs | 1+
Mtoolkit/crashreporter/CrashAnnotations.yaml | 7+++++++
6 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -7911,6 +7911,7 @@ dependencies = [ "gecko-profiler", "gleam", "log", + "mozbuild", "nsstring", "num_cpus", "objc", diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -123,6 +123,8 @@ static CrashReporter::Annotation FromWrCrashAnnotation( return CrashReporter::Annotation::GraphicsCompileShader; case mozilla::wr::CrashAnnotation::DrawShader: return CrashReporter::Annotation::GraphicsDrawShader; + case mozilla::wr::CrashAnnotation::FontFile: + return CrashReporter::Annotation::GraphicsFontFile; default: MOZ_ASSERT_UNREACHABLE("Unhandled annotation!"); return CrashReporter::Annotation::Count; diff --git a/gfx/webrender_bindings/Cargo.toml b/gfx/webrender_bindings/Cargo.toml @@ -23,6 +23,7 @@ wr_malloc_size_of = { path = "../wr/wr_malloc_size_of" } gecko-profiler = { path = "../../tools/profiler/rust-api" } static_prefs = { path = "../../modules/libpref/init/static_prefs" } remove_dir_all = "0.5.3" +mozbuild = "0.1" [dependencies.webrender] path = "../wr/webrender" diff --git a/gfx/webrender_bindings/src/moz2d_renderer.rs b/gfx/webrender_bindings/src/moz2d_renderer.rs @@ -35,6 +35,19 @@ use core_graphics::font::CGFont; #[cfg(any(target_os = "macos", target_os = "ios"))] use foreign_types::ForeignType; +#[cfg(target_os = "windows")] +use std::ffi::CStr; +#[cfg(target_os = "windows")] +use std::ffi::OsStr; +#[cfg(target_os = "windows")] +use std::iter::FromIterator; +#[cfg(target_os = "windows")] +use std::os::raw::c_char; +#[cfg(target_os = "windows")] +use std::path::PathBuf; +#[cfg(target_os = "windows")] +use winapi::um::errhandlingapi::GetLastError; + #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))] use std::ffi::CString; #[cfg(not(any(target_os = "macos", target_os = "ios", target_os = "windows")))] @@ -742,7 +755,8 @@ extern "C" { ); fn DeleteBlobFont(key: WrFontInstanceKey); fn ClearBlobImageResources(namespace: WrIdNamespace); - + #[cfg(target_os = "windows")] + fn gfx_wr_set_crash_annotation(annotation: CrashAnnotation, value: *const c_char); } impl Moz2dBlobImageHandler { @@ -761,6 +775,42 @@ impl Moz2dBlobImageHandler { /// Currently just sets up fonts found in the blob. fn prepare_request(&self, blob: &[u8], resources: &dyn BlobImageResources) { #[cfg(target_os = "windows")] + fn maybe_crash_on_no_font_file(font_path: &PathBuf) { + if !mozbuild::config::NIGHTLY_BUILD { + return; + } + + // On Nightly add annotation of the error and font file path then crash. We strip + // the user's dir if necessary to try to prevent capturing personal information. + let end_of_path = PathBuf::from_iter( + font_path + .components() + .skip_while(|c| !c.as_os_str().eq_ignore_ascii_case(OsStr::new("users"))) + .skip(2), + ); + // end_of_path will be empty if we don't find the Users dir. + let annotation_path = if end_of_path.as_os_str().is_empty() { + font_path.as_os_str() + } else { + end_of_path.as_os_str() + }; + let annotation_string = format!( + "Error: {:x} loading: {}", + unsafe { GetLastError() }, + annotation_path.display() + ); + unsafe { + gfx_wr_set_crash_annotation( + CrashAnnotation::FontFile, + CStr::from_bytes_with_nul(annotation_string.as_bytes()) + .unwrap() + .as_ptr(), + ); + } + panic!("Moz2D font file not found"); + } + + #[cfg(target_os = "windows")] fn process_native_font_handle(key: FontKey, handle: &NativeFontHandle) { if let Some(file) = dwrote::FontFile::new_from_path(&handle.path) { if let Ok(face) = file.create_face(handle.index, dwrote::DWRITE_FONT_SIMULATIONS_NONE) { @@ -768,6 +818,9 @@ impl Moz2dBlobImageHandler { return; } } + + maybe_crash_on_no_font_file(&handle.path); + // Failed to open the font file? Try to set up a fallback font so that // we don't simply crash, although text will be garbage. let desc = dwrote::FontDescriptor { diff --git a/gfx/wr/webrender_api/src/lib.rs b/gfx/wr/webrender_api/src/lib.rs @@ -805,6 +805,7 @@ pub enum ScrollLocation { pub enum CrashAnnotation { CompileShader = 0, DrawShader = 1, + FontFile = 2, } /// Handler to expose support for annotating crash reports. diff --git a/toolkit/crashreporter/CrashAnnotations.yaml b/toolkit/crashreporter/CrashAnnotations.yaml @@ -554,6 +554,13 @@ GraphicsDrawShader: type: string scope: report +GraphicsFontFile: + description: > + Error and path of the font file that has failed to load. The user's profile + dir is removed from the front of the path if necessary. + type: string + scope: report + GraphicsNumActiveRenderers: description: > Number of webrender renderer instances that are not in a paused state.