summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/rust_minidump_writer_linux
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/crashreporter/rust_minidump_writer_linux
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/crashreporter/rust_minidump_writer_linux')
-rw-r--r--toolkit/crashreporter/rust_minidump_writer_linux/Cargo.toml15
-rw-r--r--toolkit/crashreporter/rust_minidump_writer_linux/cbindgen.toml15
-rw-r--r--toolkit/crashreporter/rust_minidump_writer_linux/moz.build17
-rw-r--r--toolkit/crashreporter/rust_minidump_writer_linux/src/lib.rs132
4 files changed, 179 insertions, 0 deletions
diff --git a/toolkit/crashreporter/rust_minidump_writer_linux/Cargo.toml b/toolkit/crashreporter/rust_minidump_writer_linux/Cargo.toml
new file mode 100644
index 0000000000..b6028f6af9
--- /dev/null
+++ b/toolkit/crashreporter/rust_minidump_writer_linux/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "rust_minidump_writer_linux"
+version = "0.1.0"
+authors = ["Martin Sirringhaus"]
+edition = "2018"
+license = "MPL-2.0"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+crash-context = "0.6.0"
+minidump-writer = "0.8.0"
+libc = "0.2.74"
+anyhow = "1.0"
+nsstring = { path = "../../../xpcom/rust/nsstring/" }
diff --git a/toolkit/crashreporter/rust_minidump_writer_linux/cbindgen.toml b/toolkit/crashreporter/rust_minidump_writer_linux/cbindgen.toml
new file mode 100644
index 0000000000..e858d0bf0a
--- /dev/null
+++ b/toolkit/crashreporter/rust_minidump_writer_linux/cbindgen.toml
@@ -0,0 +1,15 @@
+header = """/* 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 http://mozilla.org/MPL/2.0/. */"""
+autogen_warning = """/* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen. See RunCbindgen.py */
+"""
+include_version = true
+braces = "SameLine"
+line_length = 100
+tab_width = 2
+language = "C++"
+include_guard = "rust_minidump_writer_linux_ffi_generated_h"
+sys_includes = ["sys/signalfd.h"]
+
+[export.rename]
+"fpregset_t" = "struct _libc_fpstate"
diff --git a/toolkit/crashreporter/rust_minidump_writer_linux/moz.build b/toolkit/crashreporter/rust_minidump_writer_linux/moz.build
new file mode 100644
index 0000000000..834a97de28
--- /dev/null
+++ b/toolkit/crashreporter/rust_minidump_writer_linux/moz.build
@@ -0,0 +1,17 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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 http://mozilla.org/MPL/2.0/.
+
+if CONFIG["COMPILE_ENVIRONMENT"]:
+ # This tells mach to run cbindgen and that this header-file should be created
+ CbindgenHeader(
+ "rust_minidump_writer_linux_ffi_generated.h",
+ inputs=["/toolkit/crashreporter/rust_minidump_writer_linux"],
+ )
+
+ # This tells mach to copy that generated file to obj/dist/includes/mozilla/toolkit/crashreporter/
+ EXPORTS.mozilla.toolkit.crashreporter += [
+ "!rust_minidump_writer_linux_ffi_generated.h",
+ ]
diff --git a/toolkit/crashreporter/rust_minidump_writer_linux/src/lib.rs b/toolkit/crashreporter/rust_minidump_writer_linux/src/lib.rs
new file mode 100644
index 0000000000..92a0795f41
--- /dev/null
+++ b/toolkit/crashreporter/rust_minidump_writer_linux/src/lib.rs
@@ -0,0 +1,132 @@
+/* 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 http://mozilla.org/MPL/2.0/. */
+extern crate minidump_writer;
+
+use anyhow;
+use libc::pid_t;
+use minidump_writer::crash_context::CrashContext;
+use minidump_writer::minidump_writer::MinidumpWriter;
+use nsstring::nsCString;
+use std::ffi::CStr;
+use std::mem::{self, MaybeUninit};
+use std::os::raw::c_char;
+
+// This function will be exposed to C++
+#[no_mangle]
+pub unsafe extern "C" fn write_minidump_linux(
+ dump_path: *const c_char,
+ child: pid_t,
+ child_blamed_thread: pid_t,
+ error_msg: &mut nsCString,
+) -> bool {
+ assert!(!dump_path.is_null());
+ let c_path = CStr::from_ptr(dump_path);
+ let path = match c_path.to_str() {
+ Ok(s) => s,
+ Err(x) => {
+ error_msg.assign(&format!(
+ "Wrapper error. Path not convertable: {:#}",
+ anyhow::Error::new(x)
+ ));
+ return false;
+ }
+ };
+
+ let mut dump_file = match std::fs::OpenOptions::new()
+ .create(true) // Create file if it doesn't exist
+ .write(true) // Truncate file
+ .open(path)
+ {
+ Ok(f) => f,
+ Err(x) => {
+ error_msg.assign(&format!(
+ "Wrapper error when opening minidump destination at {:?}: {:#}",
+ path,
+ anyhow::Error::new(x)
+ ));
+ return false;
+ }
+ };
+
+ match MinidumpWriter::new(child, child_blamed_thread).dump(&mut dump_file) {
+ Ok(_) => {
+ return true;
+ }
+ Err(x) => {
+ error_msg.assign(&format!("{:#}", anyhow::Error::new(x)));
+ return false;
+ }
+ }
+}
+
+// This function will be exposed to C++
+#[no_mangle]
+pub unsafe extern "C" fn write_minidump_linux_with_context(
+ dump_path: *const c_char,
+ child: pid_t,
+ ucontext: *const crash_context::ucontext_t,
+ float_state: *const crash_context::fpregset_t,
+ siginfo: *const libc::signalfd_siginfo,
+ child_thread: libc::pid_t,
+ error_msg: &mut nsCString,
+) -> bool {
+ let c_path = CStr::from_ptr(dump_path);
+
+ let mut crash_context: MaybeUninit<crash_context::CrashContext> = mem::MaybeUninit::zeroed();
+ let mut cc = &mut *crash_context.as_mut_ptr();
+
+ core::ptr::copy_nonoverlapping(siginfo, &mut cc.siginfo, 1);
+ core::ptr::copy_nonoverlapping(ucontext, &mut cc.context, 1);
+
+ #[cfg(not(target_arch = "arm"))]
+ core::ptr::copy_nonoverlapping(float_state, &mut cc.float_state, 1);
+ // core::ptr::copy_nonoverlapping(float_state, ((&mut cc.float_state) as *mut crash_context::fpregset_t).cast(), 1);
+
+ cc.pid = child;
+ cc.tid = child_thread;
+ let crash_context = crash_context.assume_init();
+ let crash_context = CrashContext {
+ inner: crash_context,
+ };
+
+ let path = match c_path.to_str() {
+ Ok(s) => s,
+ Err(x) => {
+ error_msg.assign(&format!(
+ "Wrapper error. Path not convertable: {:#}",
+ anyhow::Error::new(x)
+ ));
+ return false;
+ }
+ };
+
+ let mut dump_file = match std::fs::OpenOptions::new()
+ .create(true) // Create file if it doesn't exist
+ .write(true) // Truncate file
+ .open(path)
+ {
+ Ok(f) => f,
+ Err(x) => {
+ error_msg.assign(&format!(
+ "Wrapper error when opening minidump destination at {:?}: {:#}",
+ path,
+ anyhow::Error::new(x)
+ ));
+ return false;
+ }
+ };
+
+ match MinidumpWriter::new(child, child_thread)
+ .set_crash_context(crash_context)
+ .dump(&mut dump_file)
+ {
+ Ok(_) => {
+ return true;
+ }
+ Err(x) => {
+ error_msg.assign(&format!("{:#}", anyhow::Error::new(x)));
+ return false;
+ }
+ }
+}