| Index: third_party/crashpad/crashpad/client/crash_report_database_mac.mm
|
| diff --git a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
|
| index 4222078130e74f6dab0b15a9732ad025d3489cb7..9799bb0fa25d5677d0953e83fc28b37a017a9a97 100644
|
| --- a/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
|
| +++ b/third_party/crashpad/crashpad/client/crash_report_database_mac.mm
|
| @@ -47,9 +47,9 @@ const char kCompletedDirectory[] = "completed";
|
| const char kSettings[] = "settings.dat";
|
|
|
| const char* const kReportDirectories[] = {
|
| - kWriteDirectory,
|
| - kUploadPendingDirectory,
|
| - kCompletedDirectory,
|
| + kWriteDirectory,
|
| + kUploadPendingDirectory,
|
| + kCompletedDirectory,
|
| };
|
|
|
| const char kCrashReportFileExtension[] = "dmp";
|
| @@ -60,6 +60,7 @@ const char kXattrCreationTime[] = "creation_time";
|
| const char kXattrIsUploaded[] = "uploaded";
|
| const char kXattrLastUploadTime[] = "last_upload_time";
|
| const char kXattrUploadAttemptCount[] = "upload_count";
|
| +const char kXattrIsUploadExplicitlyRequested[] = "upload_explicitly_requested";
|
|
|
| const char kXattrDatabaseInitialized[] = "initialized";
|
|
|
| @@ -140,6 +141,7 @@ class CrashReportDatabaseMac : public CrashReportDatabase {
|
| const std::string& id) override;
|
| OperationStatus SkipReportUpload(const UUID& uuid) override;
|
| OperationStatus DeleteReport(const UUID& uuid) override;
|
| + OperationStatus RequestUpload(const UUID& uuid) override;
|
|
|
| private:
|
| //! \brief A private extension of the Report class that maintains bookkeeping
|
| @@ -201,6 +203,18 @@ class CrashReportDatabaseMac : public CrashReportDatabase {
|
| //! \return The long name of the extended attribute.
|
| std::string XattrName(const base::StringPiece& name);
|
|
|
| + //! \brief Marks a report with a given path as completed.
|
| + //!
|
| + //! Assumes that the report is locked.
|
| + //!
|
| + //! \param[in] report_path The path of the file to mark completed.
|
| + //! \param[out] out_path The path of the new file. This parameter is optional.
|
| + //!
|
| + //! \return The operation status code.
|
| + CrashReportDatabase::OperationStatus MarkReportCompletedLocked(
|
| + const base::FilePath& report_path,
|
| + base::FilePath* out_path);
|
| +
|
| base::FilePath base_dir_;
|
| Settings settings_;
|
| bool xattr_new_names_;
|
| @@ -449,14 +463,10 @@ CrashReportDatabaseMac::RecordUploadAttempt(const Report* report,
|
| return kBusyError;
|
|
|
| if (successful) {
|
| - base::FilePath new_path =
|
| - base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
|
| - if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
|
| - PLOG(ERROR) << "rename " << report_path.value() << " to "
|
| - << new_path.value();
|
| - return kFileSystemError;
|
| - }
|
| - report_path = new_path;
|
| + CrashReportDatabase::OperationStatus os =
|
| + MarkReportCompletedLocked(report_path, &report_path);
|
| + if (os != kNoError)
|
| + return os;
|
| }
|
|
|
| if (!WriteXattrBool(report_path, XattrName(kXattrIsUploaded), successful)) {
|
| @@ -500,15 +510,7 @@ CrashReportDatabase::OperationStatus CrashReportDatabaseMac::SkipReportUpload(
|
| if (!lock.is_valid())
|
| return kBusyError;
|
|
|
| - base::FilePath new_path =
|
| - base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
|
| - if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
|
| - PLOG(ERROR) << "rename " << report_path.value() << " to "
|
| - << new_path.value();
|
| - return kFileSystemError;
|
| - }
|
| -
|
| - return kNoError;
|
| + return MarkReportCompletedLocked(report_path, nullptr);
|
| }
|
|
|
| CrashReportDatabase::OperationStatus CrashReportDatabaseMac::DeleteReport(
|
| @@ -556,6 +558,45 @@ base::FilePath CrashReportDatabaseMac::LocateCrashReport(const UUID& uuid) {
|
| return base::FilePath();
|
| }
|
|
|
| +CrashReportDatabase::OperationStatus CrashReportDatabaseMac::RequestUpload(
|
| + const UUID& uuid) {
|
| + INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
| +
|
| + base::FilePath report_path = LocateCrashReport(uuid);
|
| + if (report_path.empty())
|
| + return kReportNotFound;
|
| +
|
| + base::ScopedFD lock(ObtainReportLock(report_path));
|
| + if (!lock.is_valid())
|
| + return kBusyError;
|
| +
|
| + // If the crash report has already been uploaded, don't request new upload.
|
| + bool uploaded = false;
|
| + XattrStatus status =
|
| + ReadXattrBool(report_path, XattrName(kXattrIsUploaded), &uploaded);
|
| + if (status == XattrStatus::kOtherError)
|
| + return kDatabaseError;
|
| + if (uploaded)
|
| + return kCannotRequestUpload;
|
| +
|
| + // Mark the crash report as having upload explicitly requested by the user,
|
| + // and move it to the pending state.
|
| + if (!WriteXattrBool(
|
| + report_path, XattrName(kXattrIsUploadExplicitlyRequested), true)) {
|
| + return kDatabaseError;
|
| + }
|
| +
|
| + base::FilePath new_path =
|
| + base_dir_.Append(kUploadPendingDirectory).Append(report_path.BaseName());
|
| + if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
|
| + PLOG(ERROR) << "rename " << report_path.value() << " to "
|
| + << new_path.value();
|
| + return kFileSystemError;
|
| + }
|
| +
|
| + return kNoError;
|
| +}
|
| +
|
| // static
|
| base::ScopedFD CrashReportDatabaseMac::ObtainReportLock(
|
| const base::FilePath& path) {
|
| @@ -604,6 +645,14 @@ bool CrashReportDatabaseMac::ReadReportMetadataLocked(
|
| return false;
|
| }
|
|
|
| + report->upload_explicitly_requested = false;
|
| + if (ReadXattrBool(path,
|
| + XattrName(kXattrIsUploadExplicitlyRequested),
|
| + &report->upload_explicitly_requested) ==
|
| + XattrStatus::kOtherError) {
|
| + return false;
|
| + }
|
| +
|
| return true;
|
| }
|
|
|
| @@ -647,6 +696,28 @@ std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) {
|
| return XattrNameInternal(name, xattr_new_names_);
|
| }
|
|
|
| +CrashReportDatabase::OperationStatus
|
| +CrashReportDatabaseMac::MarkReportCompletedLocked(
|
| + const base::FilePath& report_path,
|
| + base::FilePath* out_path) {
|
| + if (RemoveXattr(report_path, XattrName(kXattrIsUploadExplicitlyRequested)) ==
|
| + XattrStatus::kOtherError) {
|
| + return kDatabaseError;
|
| + }
|
| +
|
| + base::FilePath new_path =
|
| + base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
|
| + if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
|
| + PLOG(ERROR) << "rename " << report_path.value() << " to "
|
| + << new_path.value();
|
| + return kFileSystemError;
|
| + }
|
| +
|
| + if (out_path)
|
| + *out_path = new_path;
|
| + return kNoError;
|
| +}
|
| +
|
| std::unique_ptr<CrashReportDatabase> InitializeInternal(
|
| const base::FilePath& path,
|
| bool may_create) {
|
|
|