crash_reporter_linux.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright (c) 2014 GitHub, Inc.
  2. // Copyright (c) 2013 The Chromium Authors. All rights reserved.
  3. // Use of this source code is governed by the MIT license that can be
  4. // found in the LICENSE file.
  5. #include "atom/common/crash_reporter/crash_reporter_linux.h"
  6. #include <sys/time.h>
  7. #include <unistd.h>
  8. #include <string>
  9. #include "base/debug/crash_logging.h"
  10. #include "base/files/file_path.h"
  11. #include "base/files/file_util.h"
  12. #include "base/linux_util.h"
  13. #include "base/logging.h"
  14. #include "base/memory/singleton.h"
  15. #include "base/process/memory.h"
  16. #include "base/threading/thread_restrictions.h"
  17. #include "breakpad/src/client/linux/handler/exception_handler.h"
  18. #include "breakpad/src/common/linux/linux_libc_support.h"
  19. using google_breakpad::ExceptionHandler;
  20. using google_breakpad::MinidumpDescriptor;
  21. namespace crash_reporter {
  22. namespace {
  23. // Define a preferred limit on minidump sizes, because Crash Server currently
  24. // throws away any larger than 1.2MB (1.2 * 1024 * 1024). A value of -1 means
  25. // no limit.
  26. static const off_t kMaxMinidumpFileSize = 1258291;
  27. } // namespace
  28. CrashReporterLinux::CrashReporterLinux() : pid_(getpid()) {
  29. // Set the base process start time value.
  30. struct timeval tv;
  31. if (!gettimeofday(&tv, NULL)) {
  32. uint64_t ret = tv.tv_sec;
  33. ret *= 1000;
  34. ret += tv.tv_usec / 1000;
  35. process_start_time_ = ret;
  36. }
  37. // Make base::g_linux_distro work.
  38. base::SetLinuxDistro(base::GetLinuxDistro());
  39. }
  40. CrashReporterLinux::~CrashReporterLinux() {}
  41. void CrashReporterLinux::InitBreakpad(const std::string& product_name,
  42. const std::string& version,
  43. const std::string& company_name,
  44. const std::string& submit_url,
  45. const base::FilePath& crashes_dir,
  46. bool upload_to_server,
  47. bool skip_system_crash_handler) {
  48. EnableCrashDumping(crashes_dir);
  49. crash_keys_.reset(new CrashKeyStorage());
  50. crash_keys_->SetKeyValue("prod", ATOM_PRODUCT_NAME);
  51. crash_keys_->SetKeyValue("ver", version.c_str());
  52. upload_url_ = submit_url;
  53. upload_to_server_ = upload_to_server;
  54. for (StringMap::const_iterator iter = upload_parameters_.begin();
  55. iter != upload_parameters_.end(); ++iter)
  56. crash_keys_->SetKeyValue(iter->first.c_str(), iter->second.c_str());
  57. }
  58. void CrashReporterLinux::SetUploadParameters() {
  59. upload_parameters_["platform"] = "linux";
  60. }
  61. void CrashReporterLinux::SetUploadToServer(const bool upload_to_server) {
  62. upload_to_server_ = upload_to_server;
  63. }
  64. bool CrashReporterLinux::GetUploadToServer() {
  65. return upload_to_server_;
  66. }
  67. void CrashReporterLinux::EnableCrashDumping(const base::FilePath& crashes_dir) {
  68. {
  69. base::ThreadRestrictions::ScopedAllowIO allow_io;
  70. base::CreateDirectory(crashes_dir);
  71. }
  72. std::string log_file = crashes_dir.Append("uploads.log").value();
  73. strncpy(g_crash_log_path, log_file.c_str(), sizeof(g_crash_log_path));
  74. MinidumpDescriptor minidump_descriptor(crashes_dir.value());
  75. minidump_descriptor.set_size_limit(kMaxMinidumpFileSize);
  76. breakpad_.reset(new ExceptionHandler(minidump_descriptor, NULL, CrashDone,
  77. this,
  78. true, // Install handlers.
  79. -1));
  80. }
  81. bool CrashReporterLinux::CrashDone(const MinidumpDescriptor& minidump,
  82. void* context,
  83. const bool succeeded) {
  84. CrashReporterLinux* self = static_cast<CrashReporterLinux*>(context);
  85. // WARNING: this code runs in a compromised context. It may not call into
  86. // libc nor allocate memory normally.
  87. if (!succeeded) {
  88. const char msg[] = "Failed to generate minidump.";
  89. WriteLog(msg, sizeof(msg) - 1);
  90. return false;
  91. }
  92. DCHECK(!minidump.IsFD());
  93. BreakpadInfo info = {0};
  94. info.filename = minidump.path();
  95. info.fd = minidump.fd();
  96. info.distro = base::g_linux_distro;
  97. info.distro_length = my_strlen(base::g_linux_distro);
  98. info.upload = self->upload_to_server_;
  99. info.process_start_time = self->process_start_time_;
  100. info.oom_size = base::g_oom_size;
  101. info.pid = self->pid_;
  102. info.upload_url = self->upload_url_.c_str();
  103. info.crash_keys = self->crash_keys_.get();
  104. HandleCrashDump(info);
  105. return true;
  106. }
  107. // static
  108. CrashReporterLinux* CrashReporterLinux::GetInstance() {
  109. return base::Singleton<CrashReporterLinux>::get();
  110. }
  111. // static
  112. CrashReporter* CrashReporter::GetInstance() {
  113. return CrashReporterLinux::GetInstance();
  114. }
  115. } // namespace crash_reporter