crash_reporter_mac.mm 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (c) 2013 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/common/crash_reporter/crash_reporter_mac.h"
  5. #include <memory>
  6. #include "base/files/file_util.h"
  7. #include "base/mac/bundle_locations.h"
  8. #include "base/mac/mac_util.h"
  9. #include "base/memory/singleton.h"
  10. #include "base/strings/string_piece.h"
  11. #include "base/strings/stringprintf.h"
  12. #include "base/strings/sys_string_conversions.h"
  13. #include "base/threading/thread_restrictions.h"
  14. #include "crashpad/client/crashpad_client.h"
  15. #include "crashpad/client/crashpad_info.h"
  16. #include "crashpad/client/settings.h"
  17. namespace crash_reporter {
  18. CrashReporterMac::CrashReporterMac() {}
  19. CrashReporterMac::~CrashReporterMac() {}
  20. void CrashReporterMac::InitBreakpad(const std::string& product_name,
  21. const std::string& version,
  22. const std::string& company_name,
  23. const std::string& submit_url,
  24. const base::FilePath& crashes_dir,
  25. bool upload_to_server,
  26. bool skip_system_crash_handler) {
  27. // check whether crashpad has been initialized.
  28. // Only need to initialize once.
  29. if (simple_string_dictionary_)
  30. return;
  31. if (is_browser_) {
  32. @autoreleasepool {
  33. base::FilePath framework_bundle_path = base::mac::FrameworkBundlePath();
  34. base::FilePath handler_path =
  35. framework_bundle_path.Append("Resources").Append("crashpad_handler");
  36. std::vector<std::string> args = {
  37. "--no-rate-limit",
  38. "--no-upload-gzip", // not all servers accept gzip
  39. };
  40. crashpad::CrashpadClient crashpad_client;
  41. crashpad_client.StartHandler(handler_path, crashes_dir, crashes_dir,
  42. submit_url, StringMap(), args, true, false);
  43. } // @autoreleasepool
  44. }
  45. crashpad::CrashpadInfo* crashpad_info =
  46. crashpad::CrashpadInfo::GetCrashpadInfo();
  47. if (skip_system_crash_handler) {
  48. crashpad_info->set_system_crash_reporter_forwarding(
  49. crashpad::TriState::kDisabled);
  50. }
  51. simple_string_dictionary_.reset(new crashpad::SimpleStringDictionary());
  52. crashpad_info->set_simple_annotations(simple_string_dictionary_.get());
  53. SetCrashKeyValue("prod", ATOM_PRODUCT_NAME);
  54. SetCrashKeyValue("process_type", is_browser_ ? "browser" : "renderer");
  55. SetCrashKeyValue("ver", version);
  56. for (const auto& upload_parameter : upload_parameters_) {
  57. SetCrashKeyValue(upload_parameter.first, upload_parameter.second);
  58. }
  59. if (is_browser_) {
  60. database_ = crashpad::CrashReportDatabase::Initialize(crashes_dir);
  61. SetUploadToServer(upload_to_server);
  62. }
  63. }
  64. bool CrashReporterMac::GetUploadToServer() {
  65. bool enabled = true;
  66. if (database_) {
  67. database_->GetSettings()->GetUploadsEnabled(&enabled);
  68. }
  69. return enabled;
  70. }
  71. void CrashReporterMac::SetUploadToServer(const bool upload_to_server) {
  72. if (database_) {
  73. database_->GetSettings()->SetUploadsEnabled(upload_to_server);
  74. }
  75. }
  76. void CrashReporterMac::SetUploadParameters() {
  77. upload_parameters_["platform"] = "darwin";
  78. }
  79. void CrashReporterMac::SetCrashKeyValue(const base::StringPiece& key,
  80. const base::StringPiece& value) {
  81. simple_string_dictionary_->SetKeyValue(key.data(), value.data());
  82. }
  83. void CrashReporterMac::AddExtraParameter(const std::string& key,
  84. const std::string& value) {
  85. if (simple_string_dictionary_) {
  86. SetCrashKeyValue(key, value);
  87. } else {
  88. upload_parameters_[key] = value;
  89. }
  90. }
  91. void CrashReporterMac::RemoveExtraParameter(const std::string& key) {
  92. if (simple_string_dictionary_)
  93. simple_string_dictionary_->RemoveKey(key.data());
  94. else
  95. upload_parameters_.erase(key);
  96. }
  97. std::map<std::string, std::string> CrashReporterMac::GetParameters() const {
  98. if (simple_string_dictionary_) {
  99. std::map<std::string, std::string> ret;
  100. crashpad::SimpleStringDictionary::Iterator iter(*simple_string_dictionary_);
  101. for (;;) {
  102. auto* const entry = iter.Next();
  103. if (!entry)
  104. break;
  105. ret[entry->key] = entry->value;
  106. }
  107. return ret;
  108. }
  109. return upload_parameters_;
  110. }
  111. std::vector<CrashReporter::UploadReportResult>
  112. CrashReporterMac::GetUploadedReports(const base::FilePath& crashes_dir) {
  113. std::vector<CrashReporter::UploadReportResult> uploaded_reports;
  114. {
  115. base::ThreadRestrictions::ScopedAllowIO allow_io;
  116. if (!base::PathExists(crashes_dir)) {
  117. return uploaded_reports;
  118. }
  119. }
  120. // Load crashpad database.
  121. std::unique_ptr<crashpad::CrashReportDatabase> database =
  122. crashpad::CrashReportDatabase::Initialize(crashes_dir);
  123. DCHECK(database);
  124. std::vector<crashpad::CrashReportDatabase::Report> completed_reports;
  125. crashpad::CrashReportDatabase::OperationStatus status =
  126. database->GetCompletedReports(&completed_reports);
  127. if (status != crashpad::CrashReportDatabase::kNoError) {
  128. return uploaded_reports;
  129. }
  130. for (const crashpad::CrashReportDatabase::Report& completed_report :
  131. completed_reports) {
  132. if (completed_report.uploaded) {
  133. uploaded_reports.push_back(
  134. UploadReportResult(static_cast<int>(completed_report.creation_time),
  135. completed_report.id));
  136. }
  137. }
  138. auto sort_by_time = [](const UploadReportResult& a,
  139. const UploadReportResult& b) {
  140. return a.first >= b.first;
  141. };
  142. std::sort(uploaded_reports.begin(), uploaded_reports.end(), sort_by_time);
  143. return uploaded_reports;
  144. }
  145. // static
  146. CrashReporterMac* CrashReporterMac::GetInstance() {
  147. return base::Singleton<CrashReporterMac>::get();
  148. }
  149. // static
  150. CrashReporter* CrashReporter::GetInstance() {
  151. return CrashReporterMac::GetInstance();
  152. }
  153. } // namespace crash_reporter