Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(377)

Side by Side Diff: third_party/crashpad/crashpad/client/crash_report_database_mac.mm

Issue 2277943002: Update Crashpad to b35ee1fca18956f3c27ba124d6dc456a723c7670 (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Crashpad Authors. All rights reserved. 1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
(...skipping 29 matching lines...) Expand all
40 40
41 namespace { 41 namespace {
42 42
43 const char kWriteDirectory[] = "new"; 43 const char kWriteDirectory[] = "new";
44 const char kUploadPendingDirectory[] = "pending"; 44 const char kUploadPendingDirectory[] = "pending";
45 const char kCompletedDirectory[] = "completed"; 45 const char kCompletedDirectory[] = "completed";
46 46
47 const char kSettings[] = "settings.dat"; 47 const char kSettings[] = "settings.dat";
48 48
49 const char* const kReportDirectories[] = { 49 const char* const kReportDirectories[] = {
50 kWriteDirectory, 50 kWriteDirectory,
51 kUploadPendingDirectory, 51 kUploadPendingDirectory,
52 kCompletedDirectory, 52 kCompletedDirectory,
53 }; 53 };
54 54
55 const char kCrashReportFileExtension[] = "dmp"; 55 const char kCrashReportFileExtension[] = "dmp";
56 56
57 const char kXattrUUID[] = "uuid"; 57 const char kXattrUUID[] = "uuid";
58 const char kXattrCollectorID[] = "id"; 58 const char kXattrCollectorID[] = "id";
59 const char kXattrCreationTime[] = "creation_time"; 59 const char kXattrCreationTime[] = "creation_time";
60 const char kXattrIsUploaded[] = "uploaded"; 60 const char kXattrIsUploaded[] = "uploaded";
61 const char kXattrLastUploadTime[] = "last_upload_time"; 61 const char kXattrLastUploadTime[] = "last_upload_time";
62 const char kXattrUploadAttemptCount[] = "upload_count"; 62 const char kXattrUploadAttemptCount[] = "upload_count";
63 const char kXattrIsUploadExplicitlyRequested[] = "upload_explicitly_requested";
63 64
64 const char kXattrDatabaseInitialized[] = "initialized"; 65 const char kXattrDatabaseInitialized[] = "initialized";
65 66
66 // Ensures that the node at |path| is a directory. If the |path| refers to a 67 // Ensures that the node at |path| is a directory. If the |path| refers to a
67 // file, rather than a directory, returns false. Otherwise, returns true, 68 // file, rather than a directory, returns false. Otherwise, returns true,
68 // indicating that |path| already was a directory. 69 // indicating that |path| already was a directory.
69 bool EnsureDirectoryExists(const base::FilePath& path) { 70 bool EnsureDirectoryExists(const base::FilePath& path) {
70 struct stat st; 71 struct stat st;
71 if (stat(path.value().c_str(), &st) != 0) { 72 if (stat(path.value().c_str(), &st) != 0) {
72 PLOG(ERROR) << "stat " << path.value(); 73 PLOG(ERROR) << "stat " << path.value();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override; 134 OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
134 OperationStatus GetPendingReports(std::vector<Report>* reports) override; 135 OperationStatus GetPendingReports(std::vector<Report>* reports) override;
135 OperationStatus GetCompletedReports(std::vector<Report>* reports) override; 136 OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
136 OperationStatus GetReportForUploading(const UUID& uuid, 137 OperationStatus GetReportForUploading(const UUID& uuid,
137 const Report** report) override; 138 const Report** report) override;
138 OperationStatus RecordUploadAttempt(const Report* report, 139 OperationStatus RecordUploadAttempt(const Report* report,
139 bool successful, 140 bool successful,
140 const std::string& id) override; 141 const std::string& id) override;
141 OperationStatus SkipReportUpload(const UUID& uuid) override; 142 OperationStatus SkipReportUpload(const UUID& uuid) override;
142 OperationStatus DeleteReport(const UUID& uuid) override; 143 OperationStatus DeleteReport(const UUID& uuid) override;
144 OperationStatus RequestUpload(const UUID& uuid) override;
143 145
144 private: 146 private:
145 //! \brief A private extension of the Report class that maintains bookkeeping 147 //! \brief A private extension of the Report class that maintains bookkeeping
146 //! information of the database. 148 //! information of the database.
147 struct UploadReport : public Report { 149 struct UploadReport : public Report {
148 //! \brief Stores the flock of the file for the duration of 150 //! \brief Stores the flock of the file for the duration of
149 //! GetReportForUploading() and RecordUploadAttempt(). 151 //! GetReportForUploading() and RecordUploadAttempt().
150 int lock_fd; 152 int lock_fd;
151 }; 153 };
152 154
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 OperationStatus ReportsInDirectory(const base::FilePath& path, 196 OperationStatus ReportsInDirectory(const base::FilePath& path,
195 std::vector<Report>* reports); 197 std::vector<Report>* reports);
196 198
197 //! \brief Creates a database xattr name from the short constant name. 199 //! \brief Creates a database xattr name from the short constant name.
198 //! 200 //!
199 //! \param[in] name The short name of the extended attribute. 201 //! \param[in] name The short name of the extended attribute.
200 //! 202 //!
201 //! \return The long name of the extended attribute. 203 //! \return The long name of the extended attribute.
202 std::string XattrName(const base::StringPiece& name); 204 std::string XattrName(const base::StringPiece& name);
203 205
206 //! \brief Marks a report with a given path as completed.
207 //!
208 //! Assumes that the report is locked.
209 //!
210 //! \param[in] report_path The path of the file to mark completed.
211 //! \param[out] out_path The path of the new file. This parameter is optional.
212 //!
213 //! \return The operation status code.
214 CrashReportDatabase::OperationStatus MarkReportCompletedLocked(
215 const base::FilePath& report_path,
216 base::FilePath* out_path);
217
204 base::FilePath base_dir_; 218 base::FilePath base_dir_;
205 Settings settings_; 219 Settings settings_;
206 bool xattr_new_names_; 220 bool xattr_new_names_;
207 InitializationStateDcheck initialized_; 221 InitializationStateDcheck initialized_;
208 222
209 DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac); 223 DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac);
210 }; 224 };
211 225
212 CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path) 226 CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path)
213 : CrashReportDatabase(), 227 : CrashReportDatabase(),
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 return kReportNotFound; 456 return kReportNotFound;
443 457
444 std::unique_ptr<const UploadReport> upload_report( 458 std::unique_ptr<const UploadReport> upload_report(
445 static_cast<const UploadReport*>(report)); 459 static_cast<const UploadReport*>(report));
446 460
447 base::ScopedFD lock(upload_report->lock_fd); 461 base::ScopedFD lock(upload_report->lock_fd);
448 if (!lock.is_valid()) 462 if (!lock.is_valid())
449 return kBusyError; 463 return kBusyError;
450 464
451 if (successful) { 465 if (successful) {
452 base::FilePath new_path = 466 CrashReportDatabase::OperationStatus os =
453 base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName()); 467 MarkReportCompletedLocked(report_path, &report_path);
454 if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) { 468 if (os != kNoError)
455 PLOG(ERROR) << "rename " << report_path.value() << " to " 469 return os;
456 << new_path.value();
457 return kFileSystemError;
458 }
459 report_path = new_path;
460 } 470 }
461 471
462 if (!WriteXattrBool(report_path, XattrName(kXattrIsUploaded), successful)) { 472 if (!WriteXattrBool(report_path, XattrName(kXattrIsUploaded), successful)) {
463 return kDatabaseError; 473 return kDatabaseError;
464 } 474 }
465 if (!WriteXattr(report_path, XattrName(kXattrCollectorID), id)) { 475 if (!WriteXattr(report_path, XattrName(kXattrCollectorID), id)) {
466 return kDatabaseError; 476 return kDatabaseError;
467 } 477 }
468 478
469 time_t now = time(nullptr); 479 time_t now = time(nullptr);
(...skipping 23 matching lines...) Expand all
493 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 503 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
494 504
495 base::FilePath report_path = LocateCrashReport(uuid); 505 base::FilePath report_path = LocateCrashReport(uuid);
496 if (report_path.empty()) 506 if (report_path.empty())
497 return kReportNotFound; 507 return kReportNotFound;
498 508
499 base::ScopedFD lock(ObtainReportLock(report_path)); 509 base::ScopedFD lock(ObtainReportLock(report_path));
500 if (!lock.is_valid()) 510 if (!lock.is_valid())
501 return kBusyError; 511 return kBusyError;
502 512
503 base::FilePath new_path = 513 return MarkReportCompletedLocked(report_path, nullptr);
504 base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
505 if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
506 PLOG(ERROR) << "rename " << report_path.value() << " to "
507 << new_path.value();
508 return kFileSystemError;
509 }
510
511 return kNoError;
512 } 514 }
513 515
514 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::DeleteReport( 516 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::DeleteReport(
515 const UUID& uuid) { 517 const UUID& uuid) {
516 INITIALIZATION_STATE_DCHECK_VALID(initialized_); 518 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
517 519
518 base::FilePath report_path = LocateCrashReport(uuid); 520 base::FilePath report_path = LocateCrashReport(uuid);
519 if (report_path.empty()) 521 if (report_path.empty())
520 return kReportNotFound; 522 return kReportNotFound;
521 523
(...skipping 27 matching lines...) Expand all
549 if (ReadXattr(path, XattrName(kXattrUUID), 551 if (ReadXattr(path, XattrName(kXattrUUID),
550 &uuid_string) == XattrStatus::kOK && 552 &uuid_string) == XattrStatus::kOK &&
551 uuid_string == target_uuid) { 553 uuid_string == target_uuid) {
552 return path; 554 return path;
553 } 555 }
554 } 556 }
555 557
556 return base::FilePath(); 558 return base::FilePath();
557 } 559 }
558 560
561 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::RequestUpload(
562 const UUID& uuid) {
563 INITIALIZATION_STATE_DCHECK_VALID(initialized_);
564
565 base::FilePath report_path = LocateCrashReport(uuid);
566 if (report_path.empty())
567 return kReportNotFound;
568
569 base::ScopedFD lock(ObtainReportLock(report_path));
570 if (!lock.is_valid())
571 return kBusyError;
572
573 // If the crash report has already been uploaded, don't request new upload.
574 bool uploaded = false;
575 XattrStatus status =
576 ReadXattrBool(report_path, XattrName(kXattrIsUploaded), &uploaded);
577 if (status == XattrStatus::kOtherError)
578 return kDatabaseError;
579 if (uploaded)
580 return kCannotRequestUpload;
581
582 // Mark the crash report as having upload explicitly requested by the user,
583 // and move it to the pending state.
584 if (!WriteXattrBool(
585 report_path, XattrName(kXattrIsUploadExplicitlyRequested), true)) {
586 return kDatabaseError;
587 }
588
589 base::FilePath new_path =
590 base_dir_.Append(kUploadPendingDirectory).Append(report_path.BaseName());
591 if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
592 PLOG(ERROR) << "rename " << report_path.value() << " to "
593 << new_path.value();
594 return kFileSystemError;
595 }
596
597 return kNoError;
598 }
599
559 // static 600 // static
560 base::ScopedFD CrashReportDatabaseMac::ObtainReportLock( 601 base::ScopedFD CrashReportDatabaseMac::ObtainReportLock(
561 const base::FilePath& path) { 602 const base::FilePath& path) {
562 int fd = HANDLE_EINTR(open(path.value().c_str(), 603 int fd = HANDLE_EINTR(open(path.value().c_str(),
563 O_RDONLY | O_EXLOCK | O_NONBLOCK)); 604 O_RDONLY | O_EXLOCK | O_NONBLOCK));
564 PLOG_IF(ERROR, fd < 0) << "open lock " << path.value(); 605 PLOG_IF(ERROR, fd < 0) << "open lock " << path.value();
565 return base::ScopedFD(fd); 606 return base::ScopedFD(fd);
566 } 607 }
567 608
568 bool CrashReportDatabaseMac::ReadReportMetadataLocked( 609 bool CrashReportDatabaseMac::ReadReportMetadataLocked(
(...skipping 28 matching lines...) Expand all
597 XattrStatus::kOtherError) { 638 XattrStatus::kOtherError) {
598 return false; 639 return false;
599 } 640 }
600 641
601 report->upload_attempts = 0; 642 report->upload_attempts = 0;
602 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount), 643 if (ReadXattrInt(path, XattrName(kXattrUploadAttemptCount),
603 &report->upload_attempts) == XattrStatus::kOtherError) { 644 &report->upload_attempts) == XattrStatus::kOtherError) {
604 return false; 645 return false;
605 } 646 }
606 647
648 report->upload_explicitly_requested = false;
649 if (ReadXattrBool(path,
650 XattrName(kXattrIsUploadExplicitlyRequested),
651 &report->upload_explicitly_requested) ==
652 XattrStatus::kOtherError) {
653 return false;
654 }
655
607 return true; 656 return true;
608 } 657 }
609 658
610 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::ReportsInDirectory( 659 CrashReportDatabase::OperationStatus CrashReportDatabaseMac::ReportsInDirectory(
611 const base::FilePath& path, 660 const base::FilePath& path,
612 std::vector<CrashReportDatabase::Report>* reports) { 661 std::vector<CrashReportDatabase::Report>* reports) {
613 base::mac::ScopedNSAutoreleasePool pool; 662 base::mac::ScopedNSAutoreleasePool pool;
614 663
615 DCHECK(reports->empty()); 664 DCHECK(reports->empty());
616 665
(...skipping 23 matching lines...) Expand all
640 reports->push_back(report); 689 reports->push_back(report);
641 } 690 }
642 691
643 return kNoError; 692 return kNoError;
644 } 693 }
645 694
646 std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) { 695 std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) {
647 return XattrNameInternal(name, xattr_new_names_); 696 return XattrNameInternal(name, xattr_new_names_);
648 } 697 }
649 698
699 CrashReportDatabase::OperationStatus
700 CrashReportDatabaseMac::MarkReportCompletedLocked(
701 const base::FilePath& report_path,
702 base::FilePath* out_path) {
703 if (RemoveXattr(report_path, XattrName(kXattrIsUploadExplicitlyRequested)) ==
704 XattrStatus::kOtherError) {
705 return kDatabaseError;
706 }
707
708 base::FilePath new_path =
709 base_dir_.Append(kCompletedDirectory).Append(report_path.BaseName());
710 if (rename(report_path.value().c_str(), new_path.value().c_str()) != 0) {
711 PLOG(ERROR) << "rename " << report_path.value() << " to "
712 << new_path.value();
713 return kFileSystemError;
714 }
715
716 if (out_path)
717 *out_path = new_path;
718 return kNoError;
719 }
720
650 std::unique_ptr<CrashReportDatabase> InitializeInternal( 721 std::unique_ptr<CrashReportDatabase> InitializeInternal(
651 const base::FilePath& path, 722 const base::FilePath& path,
652 bool may_create) { 723 bool may_create) {
653 std::unique_ptr<CrashReportDatabaseMac> database_mac( 724 std::unique_ptr<CrashReportDatabaseMac> database_mac(
654 new CrashReportDatabaseMac(path)); 725 new CrashReportDatabaseMac(path));
655 if (!database_mac->Initialize(may_create)) 726 if (!database_mac->Initialize(may_create))
656 database_mac.reset(); 727 database_mac.reset();
657 728
658 return std::unique_ptr<CrashReportDatabase>(database_mac.release()); 729 return std::unique_ptr<CrashReportDatabase>(database_mac.release());
659 } 730 }
660 731
661 } // namespace 732 } // namespace
662 733
663 // static 734 // static
664 std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize( 735 std::unique_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
665 const base::FilePath& path) { 736 const base::FilePath& path) {
666 return InitializeInternal(path, true); 737 return InitializeInternal(path, true);
667 } 738 }
668 739
669 // static 740 // static
670 std::unique_ptr<CrashReportDatabase> 741 std::unique_ptr<CrashReportDatabase>
671 CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) { 742 CrashReportDatabase::InitializeWithoutCreating(const base::FilePath& path) {
672 return InitializeInternal(path, false); 743 return InitializeInternal(path, false);
673 } 744 }
674 745
675 } // namespace crashpad 746 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698