diff --git a/Cargo.lock b/Cargo.lock index 4211c42333..9e9d8d8703 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,6 +252,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base", + "crash_report", "metrics", "serde", ] @@ -334,6 +335,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" +[[package]] +name = "crash_report" +version = "0.1.0" +dependencies = [ + "anyhow", + "base", + "serde", + "win_util", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -409,6 +420,7 @@ dependencies = [ "broker_ipc", "cc", "cfg-if", + "crash_report", "cros_async", "crosvm_plugin", "ctrlc", diff --git a/Cargo.toml b/Cargo.toml index 7ecde8d755..a103cdb710 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,7 @@ members = [ "base", "bit_field", "broker_ipc", + "crash_report", "cros_async", "crosvm-fuzz", "crosvm_control", @@ -121,13 +122,13 @@ all-linux = [ "wl-dmabuf", "x", ] -win64 = ["stats", "balloon", "haxm"] +win64 = [ "balloon", "crash_report", "haxm", "stats" ] audio = ["devices/audio"] audio_cras = ["devices/audio_cras"] balloon = ["devices/balloon", "vm_control/balloon"] chromeos = ["base/chromeos", "audio_cras", "devices/chromeos", "panic-memfd"] composite-disk = ["protos/composite-disk", "protobuf", "disk/composite-disk"] -crash-report = [] +crash-report = ["broker_ipc/crash-report", "crash_report"] default = ["audio", "balloon", "gpu", "qcow", "usb"] default-no-sandbox = [] direct = ["balloon", "devices/direct", "arch/direct", "x86_64/direct"] @@ -232,6 +233,7 @@ p9 = "*" [target.'cfg(windows)'.dependencies] anti_tamper = { path = "anti_tamper" } +crash_report = { path = "crash_report", optional = true } cros_async = { path = "cros_async" } ctrlc = "*" futures = "0.3" diff --git a/broker_ipc/Cargo.toml b/broker_ipc/Cargo.toml index 37b18c4c89..79a386979b 100644 --- a/broker_ipc/Cargo.toml +++ b/broker_ipc/Cargo.toml @@ -4,9 +4,13 @@ authors = ["The Chromium OS Authors"] version = "0.1.0" edition = "2021" +[features] +crash-report = [] + [dependencies] anyhow = "1.0.32" base = { path = "../base" } +crash_report = { path = "../crash_report" } serde = { version = "1", features = [ "derive" ] } metrics = { path = "../metrics" } diff --git a/broker_ipc/src/generic.rs b/broker_ipc/src/generic.rs index f44ae73296..5488c271e2 100644 --- a/broker_ipc/src/generic.rs +++ b/broker_ipc/src/generic.rs @@ -18,7 +18,11 @@ use crate::CommonChildStartupArgs; pub struct ProductAttributes {} impl CommonChildStartupArgs { - pub fn new(syslog_path: Option, metrics_tube: Option) -> anyhow::Result { + pub fn new( + syslog_path: Option, + #[cfg(feature = "crash-report")] _crash_attrs: crash_report::CrashReportAttributes, + metrics_tube: Option, + ) -> anyhow::Result { Ok(Self { product_attrs: ProductAttributes {}, metrics_tube, diff --git a/crash_report/Cargo.toml b/crash_report/Cargo.toml new file mode 100644 index 0000000000..d95f644188 --- /dev/null +++ b/crash_report/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "crash_report" +version = "0.1.0" +authors = ["The Chromium OS Authors"] +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +base = { path = "../base" } +anyhow = "1.0.32" +serde = "*" +win_util = { path = "../win_util"} + diff --git a/crash_report/src/lib.rs b/crash_report/src/lib.rs new file mode 100644 index 0000000000..917390024d --- /dev/null +++ b/crash_report/src/lib.rs @@ -0,0 +1,7 @@ +// Copyright 2022 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +pub mod noop; + +pub use noop::*; diff --git a/crash_report/src/noop.rs b/crash_report/src/noop.rs new file mode 100644 index 0000000000..802d4a8aa3 --- /dev/null +++ b/crash_report/src/noop.rs @@ -0,0 +1,81 @@ +// Copyright 2022 The ChromiumOS Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +use std::collections::HashMap; + +use anyhow::Result; +use base::RecvTube; +use base::SendTube; +use serde::Deserialize; +use serde::Serialize; +#[cfg(windows)] +use win_util::ProcessType; + +#[cfg(unix)] +pub enum ProcessType {} + +/// The reason a SimulatedException crash report is being requested. +#[derive(Clone, Copy, Serialize, Deserialize, Debug, Eq, PartialEq)] +pub enum CrashReportReason { + /// A default value for unspecified crash report reason. + Unknown, +} + +#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq)] +enum CrashTubeCommand { + UploadCrashReport(CrashReportReason), +} + +pub mod product_type { + pub const EMULATOR: &str = "KiwiEmulator_main"; + pub const BROKER: &str = "KiwiEmulator_broker"; + pub const DISK: &str = "KiwiEmulator_disk"; + pub const NET: &str = "KiwiEmulator_net"; + pub const SLIRP: &str = "KiwiEmulator_slirp"; + pub const METRICS: &str = "KiwiEmulator_metrics"; +} + +/// Attributes about a process that are required to set up annotations for crash reports. +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct CrashReportAttributes { + pub product_type: String, + pub pipe_name: Option, + pub report_uuid: Option, + pub product_name: Option, + pub product_version: Option, +} + +/// Handler for remote crash requests from other processes. +pub struct RemoteCrashHandler {} + +impl RemoteCrashHandler { + /// Creates a handler for remote crash requests from other processes. + pub fn new(_crash_tube: RecvTube) -> Result { + Ok(Self {}) + } +} + +impl Drop for RemoteCrashHandler { + fn drop(&mut self) {} +} + +/// Setup crash reporting for a process. Each process MUST provide a unique `product_type` to avoid +/// making crash reports incomprehensible. +pub fn setup_crash_reporting(mut _attrs: CrashReportAttributes) -> Result { + Ok(String::new()) +} + +/// Sets a map of tubes to trigger SimulatedException crash reports for each process type. Should +/// only be called on the main process. +pub fn set_crash_tube_map(_map: HashMap>) {} + +/// Captures a crash dump and uploads a crash report, without crashing the process. +/// +/// A crash report from the current process is always taken, modulo rate limiting. Additionally, +/// crash reports can be triggered on other processes, if the caller is the main process and +/// `reason` was mapped to process types with `set_crash_tube_map`. +pub fn upload_crash_report(_reason: CrashReportReason) {} + +/// Sets the package name to given `_package_name`. +pub fn set_package_name(_package_name: &str) {}