Bug 1923782 - Include minidump-analyzer library on android r=glandium,geckoview-reviewers,owlish,gsvelto

Differential Revision: https://phabricator.services.mozilla.com/D225787
This commit is contained in:
Alex Franchuk 2024-10-30 16:54:27 +00:00
parent b10010e527
commit a1d55b1ff2
10 changed files with 191 additions and 0 deletions

9
Cargo.lock generated
View File

@ -3882,6 +3882,14 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "minidump-analyzer-export"
version = "0.1.0"
dependencies = [
"minidump-analyzer",
"mozilla-central-workspace-hack",
]
[[package]]
name = "minidump-common"
version = "0.22.1"
@ -4068,6 +4076,7 @@ dependencies = [
"futures",
"futures-channel",
"futures-core",
"futures-executor",
"futures-sink",
"futures-util",
"getrandom",

View File

@ -17,6 +17,7 @@ members = [
"testing/geckodriver",
"toolkit/components/uniffi-bindgen-gecko-js",
"toolkit/crashreporter/client/app",
"toolkit/crashreporter/minidump-analyzer/android/export",
"toolkit/crashreporter/mozwer-rust",
"toolkit/crashreporter/rust_minidump_writer_linux",
"toolkit/library/gtest/rust",

View File

@ -242,6 +242,7 @@ http3server = ["dep:arrayvec", "dep:bindgen", "dep:bitflags", "dep:bytes", "dep:
ipcclientcerts-static = ["dep:bindgen", "dep:bitflags", "dep:itertools", "dep:memchr", "dep:nom", "dep:regex"]
jsrust = ["dep:arrayvec", "dep:cc", "dep:env_logger", "dep:getrandom", "dep:hashbrown", "dep:icu_locid", "dep:icu_properties", "dep:indexmap", "dep:log", "dep:memchr", "dep:num-traits", "dep:once_cell", "dep:semver", "dep:smallvec", "dep:stable_deref_trait", "dep:tinystr", "dep:unicode-bidi", "dep:url", "dep:yoke", "dep:zerofrom", "dep:zerovec"]
minidump-analyzer = ["dep:clap", "dep:env_logger", "dep:futures-executor", "dep:futures-util", "dep:log", "dep:serde_json", "dep:windows-sys"]
minidump-analyzer-export = ["minidump-analyzer"]
mozwer_s = ["dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:log", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:uuid", "dep:windows-sys"]
nmhproxy = ["dep:bitflags", "dep:hashbrown", "dep:icu_locid", "dep:icu_properties", "dep:indexmap", "dep:once_cell", "dep:serde_json", "dep:smallvec", "dep:stable_deref_trait", "dep:tinystr", "dep:unicode-bidi", "dep:url", "dep:windows-sys", "dep:yoke", "dep:zerofrom", "dep:zerovec"]
osclientcerts-static = ["dep:bindgen", "dep:bitflags", "dep:core-foundation-sys", "dep:env_logger", "dep:itertools", "dep:log", "dep:memchr", "dep:nom", "dep:regex"]

View File

@ -79,6 +79,10 @@
@BINPATH@/@DLL_PREFIX@gvr@DLL_SUFFIX@
#endif
#ifdef MOZ_CRASHREPORTER
@BINPATH@/@DLL_PREFIX@minidump_analyzer@DLL_SUFFIX@
#endif
[xpcom]
@BINPATH@/package-name.txt

View File

@ -0,0 +1,13 @@
[package]
name = "minidump-analyzer-export"
version = "0.1.0"
edition = "2021"
[lib]
name = "minidump_analyzer_export"
crate-type = ["staticlib"]
path = "lib.rs"
[dependencies]
minidump-analyzer = { path = "../../" }
mozilla-central-workspace-hack = { version = "0.1", features = ["minidump-analyzer-export"], optional = true }

View File

@ -0,0 +1,87 @@
/* 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/. */
use minidump_analyzer::MinidumpAnalyzer;
#[derive(Debug)]
#[repr(C)]
pub struct Utf16String {
chars: *mut u16,
len: usize,
}
impl Utf16String {
pub fn empty() -> Self {
Utf16String {
chars: std::ptr::null_mut(),
len: 0,
}
}
pub fn as_string_lossy(&self) -> String {
if self.chars.is_null() {
String::default()
} else {
String::from_utf16_lossy(unsafe { std::slice::from_raw_parts(self.chars, self.len) })
}
}
}
impl Drop for Utf16String {
fn drop(&mut self) {
if !self.chars.is_null() {
// # Safety
// We only own Utf16Strings which are created in Rust code, so when dropping, the
// memory is that which we allocated (and thus is safe to deallocate).
unsafe {
std::alloc::dealloc(
self.chars as *mut u8,
// unwrap() because the memory must have been a size that doesn't overflow when
// it was originally allocated.
std::alloc::Layout::array::<u16>(self.len).unwrap(),
)
};
}
}
}
impl Default for Utf16String {
fn default() -> Self {
Self::empty()
}
}
impl From<String> for Utf16String {
fn from(value: String) -> Self {
let utf16: Box<[u16]> = value.encode_utf16().collect();
let utf16 = Box::leak(utf16);
Utf16String {
chars: utf16.as_mut_ptr(),
len: utf16.len(),
}
}
}
#[no_mangle]
pub extern "C" fn minidump_analyzer_analyze(
minidump_path: &Utf16String,
extras_path: &Utf16String,
all_threads: bool,
) -> Utf16String {
let minidump_path = minidump_path.as_string_lossy();
let extras_path = extras_path.as_string_lossy();
MinidumpAnalyzer::new(minidump_path.as_ref())
.extras_file(extras_path.as_ref())
.all_threads(all_threads)
.analyze()
.err()
.map(|e| e.to_string().into())
.unwrap_or_default()
}
#[no_mangle]
pub extern "C" fn minidump_analyzer_free_result(result: Utf16String) {
// This will happen anyway, but we're explicit about it for clarity.
drop(result);
}

View File

@ -0,0 +1 @@
RustLibrary("minidump-analyzer-export")

View File

@ -0,0 +1,65 @@
/* 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/. */
#include <cstddef>
#include <cstdint>
#include <jni.h>
namespace {
struct Utf16String {
const uint16_t* chars;
size_t len;
};
extern "C" {
Utf16String minidump_analyzer_analyze(const Utf16String& minidump_path,
const Utf16String& extras_path,
bool all_threads);
void minidump_analyzer_free_result(Utf16String result);
}
struct LocalString : Utf16String {
LocalString(JNIEnv* env, jstring str) : env(env), str(str) {
chars = env->GetStringChars(str, nullptr);
len = env->GetStringLength(str);
}
~LocalString() { env->ReleaseStringChars(str, chars); }
LocalString(const LocalString&) = delete;
LocalString& operator=(const LocalString&) = delete;
JNIEnv* env;
jstring str;
};
struct ForeignString : Utf16String {
explicit ForeignString(Utf16String s) : Utf16String(s) {}
~ForeignString() { minidump_analyzer_free_result(*this); }
ForeignString(const ForeignString&) = delete;
ForeignString& operator=(const ForeignString&) = delete;
explicit operator bool() const { return chars != nullptr; }
jstring to_jstring(JNIEnv* env) const { return env->NewString(chars, len); }
};
} // namespace
extern "C" {
JNIEXPORT jstring JNICALL
Java_mozilla_components_lib_crash_MinidumpAnalyzer_analyze(
JNIEnv* env, jobject obj, jstring minidump_path, jstring extras_path,
jboolean all_threads) {
LocalString minidump_str(env, minidump_path);
LocalString extras_str(env, extras_path);
if (auto error = ForeignString(
minidump_analyzer_analyze(minidump_str, extras_str, all_threads))) {
return error.to_jstring(env);
}
return nullptr;
}
}

View File

@ -0,0 +1,7 @@
DIRS += ["export"]
USE_LIBS += ["minidump-analyzer-export"]
# libm log/logf are required by the rust static library
OS_LIBS += ["m"]
SOURCES += ["lib.cpp"]
SharedLibrary("minidump_analyzer")

View File

@ -66,6 +66,9 @@ if CONFIG["MOZ_CRASHREPORTER"]:
if CONFIG["OS_TARGET"] != "Android":
DIRS += ["client/app"]
if CONFIG["OS_TARGET"] == "Android":
DIRS += ["minidump-analyzer/android"]
DIRS += [
"mozannotation_client",
"mozannotation_server",