Bug 1433495 - Save minidump files if MINIDUMP_SAVE_PATH is set. draft
authorHenrik Skupin <mail@hskupin.info>
Tue, 27 Feb 2018 16:37:39 +0100
changeset 760414 f863be95f6de08d64e427c0fea674d6f926485a8
parent 760185 580d833df9c44acec686a9fb88b5f27e9d29f68d
push id100633
push userbmo:hskupin@gmail.com
push dateTue, 27 Feb 2018 15:38:09 +0000
bugs1433495
milestone60.0a1
Bug 1433495 - Save minidump files if MINIDUMP_SAVE_PATH is set. As long as minidump files cannot be analyzed by a tool like mozcrash the generated files should at least be saved to a location which is persistent. MozReview-Commit-ID: 6781QQy41pD
testing/mozbase/rust/mozrunner/Cargo.toml
testing/mozbase/rust/mozrunner/src/lib.rs
testing/mozbase/rust/mozrunner/src/minidump.rs
testing/mozbase/rust/mozrunner/src/runner.rs
--- a/testing/mozbase/rust/mozrunner/Cargo.toml
+++ b/testing/mozbase/rust/mozrunner/Cargo.toml
@@ -4,14 +4,15 @@ version = "0.5.0"
 authors = ["Mozilla Tools and Automation <auto-tools@mozilla.com>"]
 description = "Library for starting Firefox binaries."
 repository = "https://hg.mozilla.org/mozilla-central/file/tip/testing/mozbase/rust/mozrunner"
 license = "MPL-2.0"
 
 [dependencies]
 log = "0.4"
 mozprofile = { path = "../mozprofile" }
+walkdir = "2"
 
 [target.'cfg(target_os = "windows")'.dependencies]
 winreg = "0.5"
 
 [[bin]]
 name = "firefox-default-path"
--- a/testing/mozbase/rust/mozrunner/src/lib.rs
+++ b/testing/mozbase/rust/mozrunner/src/lib.rs
@@ -1,8 +1,10 @@
 #[macro_use] extern crate log;
 extern crate mozprofile;
+extern crate walkdir;
 #[cfg(target_os = "windows")]
 extern crate winreg;
 
+mod minidump;
 pub mod runner;
 
 pub use runner::platform::firefox_default_path;
new file mode 100644
--- /dev/null
+++ b/testing/mozbase/rust/mozrunner/src/minidump.rs
@@ -0,0 +1,35 @@
+use std::env;
+use std::fs;
+use std::path::PathBuf;
+use walkdir::WalkDir;
+
+pub fn save_minidump_files(path: &PathBuf) -> () {
+    // Until we can analyze crash reports similar to mozcrash
+    // lets save available minidump files to a safe location
+    // if the MINIDUMP_SAVE_PATH env variable has been set.
+    if let Ok(val) = env::var("MINIDUMP_SAVE_PATH") {
+        let minidump_folder = path.join("minidumps");
+        let mut save_path = PathBuf::from(val);
+
+        if !save_path.is_dir() {
+            println!("MINIDUMP_SAVE_PATH set, but {:?} is not a valid path", save_path);
+            return;
+        }
+
+        // temporarily set a filename which will be replace for each entry later
+        save_path.join("minidumps");
+
+        let walker = WalkDir::new(minidump_folder).into_iter();
+        for entry in walker.filter_map(|e| e.ok()) {
+            if entry.path().is_file() {
+                save_path.set_file_name(entry.file_name());
+                match fs::copy(entry.path(), &save_path) {
+                    Ok(_) => {
+                        println!("Saved {:?} as {:?}", entry.file_name(), save_path);
+                    }
+                    _ => {}
+                }
+            }
+        }
+    }
+}
--- a/testing/mozbase/rust/mozrunner/src/runner.rs
+++ b/testing/mozbase/rust/mozrunner/src/runner.rs
@@ -1,22 +1,23 @@
 use mozprofile::prefreader::PrefReaderError;
 use mozprofile::profile::Profile;
-use std::ascii::AsciiExt;
 use std::collections::HashMap;
 use std::convert::From;
 use std::env;
 use std::error::Error;
 use std::ffi::{OsStr, OsString};
 use std::fmt;
 use std::io::{Error as IoError, ErrorKind, Result as IoResult};
 use std::path::{Path, PathBuf};
 use std::process::{Child, Command, Stdio};
 use std::process;
 
+use minidump;
+
 pub trait Runner {
     type Process;
 
     fn arg<'a, S>(&'a mut self, arg: S) -> &'a mut Self
     where
         S: AsRef<OsStr>;
 
     fn args<'a, I, S>(&'a mut self, args: I) -> &'a mut Self
@@ -98,16 +99,22 @@ impl From<PrefReaderError> for RunnerErr
 }
 
 #[derive(Debug)]
 pub struct FirefoxProcess {
     process: Child,
     profile: Profile
 }
 
+impl Drop for FirefoxProcess {
+    fn drop(&mut self) {
+        minidump::save_minidump_files(&self.profile.path);
+    }
+}
+
 impl RunnerProcess for FirefoxProcess {
     fn status(&mut self) -> IoResult<Option<process::ExitStatus>> {
         self.process.try_wait()
     }
 
     fn is_running(&mut self) -> bool {
         self.status().unwrap().is_none()
     }