From c821a06e2f001db8726777b01a8ee5656d7067e9 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 5 Jun 2015 18:50:52 +0800 Subject: [PATCH 1/3] Implement crash-reporter.getUploadedReports API. Also redefine the getLastCrashReport API implementation using getUploadedReports API. --- atom/common/api/lib/crash-reporter.coffee | 22 +++++++-------- atom/common/crash_reporter/crash_reporter.cc | 23 ++++++++++++++-- atom/common/crash_reporter/crash_reporter.h | 3 ++- .../crash_reporter/crash_reporter_mac.h | 8 ++---- .../crash_reporter/crash_reporter_mac.mm | 27 ++++++++++--------- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/atom/common/api/lib/crash-reporter.coffee b/atom/common/api/lib/crash-reporter.coffee index c151ff7f71c8..868cda28fcf6 100644 --- a/atom/common/api/lib/crash-reporter.coffee +++ b/atom/common/api/lib/crash-reporter.coffee @@ -41,23 +41,23 @@ class CrashReporter start() getLastCrashReport: -> - if process.platform is 'darwin' - reports = binding._getUploadedReports() - return if reports.length > 0 then reports[0] else null + reports = this.getUploadedReports() + if reports.length > 0 then reports[0] else null + getUploadedReports: -> tmpdir = if process.platform is 'win32' os.tmpdir() else '/tmp' - log = path.join tmpdir, "#{@productName} Crashes", 'uploads.log' - try - reports = String(fs.readFileSync(log)).split('\n') - return null unless reports.length > 1 - [time, id] = reports[reports.length - 2].split ',' - return {date: new Date(parseInt(time) * 1000), id} - catch e - return null + log = + if process.platform is 'darwin' + path.join tmpdir, "#{@productName} Crashes" + else + path.join tmpdir, "#{@productName} Crashes", 'uploads.log' + console.log log; + binding._getUploadedReports(log) + crashRepoter = new CrashReporter module.exports = crashRepoter diff --git a/atom/common/crash_reporter/crash_reporter.cc b/atom/common/crash_reporter/crash_reporter.cc index 25dbf6065d96..365860b256c7 100644 --- a/atom/common/crash_reporter/crash_reporter.cc +++ b/atom/common/crash_reporter/crash_reporter.cc @@ -7,6 +7,9 @@ #include "atom/browser/browser.h" #include "atom/common/atom_version.h" #include "base/command_line.h" +#include "base/files/file_util.h" +#include "base/strings/string_split.h" +#include "base/strings/string_number_conversions.h" #include "content/public/common/content_switches.h" namespace crash_reporter { @@ -40,8 +43,24 @@ void CrashReporter::SetUploadParameters(const StringMap& parameters) { } std::vector -CrashReporter::GetUploadedReports() { - return std::vector(); +CrashReporter::GetUploadedReports(const std::string& path) { + std::string file_content; + std::vector result; + if (base::ReadFileToString(base::FilePath(path), &file_content)) { + std::vector reports; + base::SplitString(file_content, '\n', &reports); + for (const std::string& report : reports) { + std::vector report_item; + base::SplitString(report, ',', &report_item); + int report_time = 0; + if (report_item.size() >= 2 && base::StringToInt(report_item[0], + &report_time)) { + result.push_back(CrashReporter::UploadReportResult(report_time, + report_item[1])); + } + } + } + return result; } } // namespace crash_reporter diff --git a/atom/common/crash_reporter/crash_reporter.h b/atom/common/crash_reporter/crash_reporter.h index 6cfa5b3f3a59..c7d58ca3aa76 100644 --- a/atom/common/crash_reporter/crash_reporter.h +++ b/atom/common/crash_reporter/crash_reporter.h @@ -28,7 +28,8 @@ class CrashReporter { bool skip_system_crash_handler, const StringMap& extra_parameters); - virtual std::vector GetUploadedReports(); + virtual std::vector GetUploadedReports( + const std::string& path); protected: CrashReporter(); diff --git a/atom/common/crash_reporter/crash_reporter_mac.h b/atom/common/crash_reporter/crash_reporter_mac.h index ca31237cc154..cbdb3c65feb1 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.h +++ b/atom/common/crash_reporter/crash_reporter_mac.h @@ -16,10 +16,6 @@ template struct DefaultSingletonTraits; -namespace crashpad { -class CrashReportDatabase; -} - namespace crash_reporter { class CrashReporterMac : public CrashReporter { @@ -44,10 +40,10 @@ class CrashReporterMac : public CrashReporter { void SetCrashKeyValue(const base::StringPiece& key, const base::StringPiece& value); - std::vector GetUploadedReports() override; + std::vector GetUploadedReports( + const std::string& path) override; scoped_ptr simple_string_dictionary_; - scoped_ptr crash_report_database_; DISALLOW_COPY_AND_ASSIGN(CrashReporterMac); }; diff --git a/atom/common/crash_reporter/crash_reporter_mac.mm b/atom/common/crash_reporter/crash_reporter_mac.mm index 4edd35a43138..00f37cc3febb 100644 --- a/atom/common/crash_reporter/crash_reporter_mac.mm +++ b/atom/common/crash_reporter/crash_reporter_mac.mm @@ -5,6 +5,7 @@ #include "atom/common/crash_reporter/crash_reporter_mac.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" #include "base/mac/bundle_locations.h" #include "base/mac/mac_util.h" #include "base/memory/singleton.h" @@ -71,9 +72,11 @@ void CrashReporterMac::InitBreakpad(const std::string& product_name, SetCrashKeyValue(upload_parameter.first, upload_parameter.second); } if (is_browser_) { - crash_report_database_ = crashpad::CrashReportDatabase::Initialize( - database_path); - SetUploadsEnabled(auto_submit); + scoped_ptr database = + crashpad::CrashReportDatabase::Initialize(database_path); + if (database) { + database->GetSettings()->SetUploadsEnabled(auto_submit); + } } } @@ -81,29 +84,27 @@ void CrashReporterMac::SetUploadParameters() { upload_parameters_["platform"] = "darwin"; } -void CrashReporterMac::SetUploadsEnabled(bool enable_uploads) { - if (crash_report_database_) { - crashpad::Settings* settings = crash_report_database_->GetSettings(); - settings->SetUploadsEnabled(enable_uploads); - } -} - void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key, const base::StringPiece& value) { simple_string_dictionary_->SetKeyValue(key.data(), value.data()); } std::vector -CrashReporterMac::GetUploadedReports() { +CrashReporterMac::GetUploadedReports(const std::string& path) { std::vector uploaded_reports; - if (!crash_report_database_) { + base::FilePath file_path(path); + if (!base::PathExists(file_path)) { return uploaded_reports; } + // Load crashpad database. + scoped_ptr database = + crashpad::CrashReportDatabase::Initialize(file_path); + DCHECK(database); std::vector completed_reports; crashpad::CrashReportDatabase::OperationStatus status = - crash_report_database_->GetCompletedReports(&completed_reports); + database->GetCompletedReports(&completed_reports); if (status != crashpad::CrashReportDatabase::kNoError) { return uploaded_reports; } From 4da7578daba66c82c945ecaeb5f485d6fe8fd156 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 5 Jun 2015 19:05:55 +0800 Subject: [PATCH 2/3] :memo: Add getUploadedReports API doc. --- docs/api/crash-reporter.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/api/crash-reporter.md b/docs/api/crash-reporter.md index d867f77ce398..2064f20f3951 100644 --- a/docs/api/crash-reporter.md +++ b/docs/api/crash-reporter.md @@ -27,6 +27,9 @@ crashReporter.start({ * Only string properties are send correctly. * Nested objects are not supported. +Developers are required to call the API before using other crashReporter APIs. + + **Note:** On OS X, electron uses a new `crashpad` client, which is different with the `breakpad` on Windows and Linux. To enable crash collection feature, you are required to call `crashReporter.start` API to initiliaze `crashpad` in @@ -37,6 +40,10 @@ main process, even you only collect crash report in renderer process. Returns the date and ID of last crash report, when there was no crash report sent or the crash reporter is not started, `null` will be returned. +## crashReporter.getUploadedReports() + +Returns all uploaded crash reports, each report contains date and uploaded ID. + # crash-reporter payload The crash reporter will send the following data to the `submitUrl` as `POST`: From cd1c331112360ded924830bcc07ab54ccaff9207 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Sat, 6 Jun 2015 17:59:20 +0800 Subject: [PATCH 3/3] Fix coffeelint error. --- atom/common/api/lib/crash-reporter.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/atom/common/api/lib/crash-reporter.coffee b/atom/common/api/lib/crash-reporter.coffee index 868cda28fcf6..451fa1729428 100644 --- a/atom/common/api/lib/crash-reporter.coffee +++ b/atom/common/api/lib/crash-reporter.coffee @@ -55,8 +55,7 @@ class CrashReporter path.join tmpdir, "#{@productName} Crashes" else path.join tmpdir, "#{@productName} Crashes", 'uploads.log' - console.log log; - binding._getUploadedReports(log) + binding._getUploadedReports log crashRepoter = new CrashReporter