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

Side by Side Diff: client/crash_report_database_mac.mm

Issue 1395653002: crashpad_database_util: Don’t create a database unless explicitly asked (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: For checkin Created 5 years, 2 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
« no previous file with comments | « client/crash_report_database.h ('k') | client/crash_report_database_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 63
64 const char kXattrDatabaseInitialized[] = "initialized"; 64 const char kXattrDatabaseInitialized[] = "initialized";
65 65
66 // 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 // indicating that |path| already was a directory.
69 bool EnsureDirectoryExists(const base::FilePath& path) {
70 struct stat st;
71 if (stat(path.value().c_str(), &st) != 0) {
72 PLOG(ERROR) << "stat " << path.value();
73 return false;
74 }
75 if (!S_ISDIR(st.st_mode)) {
76 LOG(ERROR) << "stat " << path.value() << ": not a directory";
77 return false;
78 }
79 return true;
80 }
81
66 // Ensures that the node at |path| is a directory, and creates it if it does 82 // Ensures that the node at |path| is a directory, and creates it if it does
67 // not exist. If the |path| points to a file, rather than a directory, or the 83 // not exist. If the |path| refers to a file, rather than a directory, or the
68 // directory could not be created, returns false. Otherwise, returns true, 84 // directory could not be created, returns false. Otherwise, returns true,
69 // indicating that |path| already was or now is a directory. 85 // indicating that |path| already was or now is a directory.
70 bool CreateOrEnsureDirectoryExists(const base::FilePath& path) { 86 bool CreateOrEnsureDirectoryExists(const base::FilePath& path) {
71 if (mkdir(path.value().c_str(), 0755) == 0) { 87 if (mkdir(path.value().c_str(), 0755) == 0) {
72 return true; 88 return true;
73 } else if (errno == EEXIST) { 89 }
74 struct stat st; 90 if (errno != EEXIST) {
75 if (stat(path.value().c_str(), &st) != 0) { 91 PLOG(ERROR) << "mkdir " << path.value();
76 PLOG(ERROR) << "stat";
77 return false;
78 }
79 if (S_ISDIR(st.st_mode)) {
80 return true;
81 } else {
82 LOG(ERROR) << "not a directory";
83 return false;
84 }
85 } else {
86 PLOG(ERROR) << "mkdir";
87 return false; 92 return false;
88 } 93 }
94 return EnsureDirectoryExists(path);
89 } 95 }
90 96
91 //! \brief A CrashReportDatabase that uses HFS+ extended attributes to store 97 //! \brief A CrashReportDatabase that uses HFS+ extended attributes to store
92 //! report metadata. 98 //! report metadata.
93 //! 99 //!
94 //! The database maintains three directories of reports: `"new"` to hold crash 100 //! The database maintains three directories of reports: `"new"` to hold crash
95 //! reports that are in the process of being written, `"completed"` to hold 101 //! reports that are in the process of being written, `"completed"` to hold
96 //! reports that have been written and are awaiting upload, and `"uploaded"` to 102 //! reports that have been written and are awaiting upload, and `"uploaded"` to
97 //! hold reports successfully uploaded to a collection server. If the user has 103 //! hold reports successfully uploaded to a collection server. If the user has
98 //! opted out of report collection, reports will still be written and moved 104 //! opted out of report collection, reports will still be written and moved
99 //! to the completed directory, but they just will not be uploaded. 105 //! to the completed directory, but they just will not be uploaded.
100 //! 106 //!
101 //! The database stores its metadata in extended filesystem attributes. To 107 //! The database stores its metadata in extended filesystem attributes. To
102 //! ensure safe access, the report file is locked using `O_EXLOCK` during all 108 //! ensure safe access, the report file is locked using `O_EXLOCK` during all
103 //! extended attribute operations. The lock should be obtained using 109 //! extended attribute operations. The lock should be obtained using
104 //! ObtainReportLock(). 110 //! ObtainReportLock().
105 class CrashReportDatabaseMac : public CrashReportDatabase { 111 class CrashReportDatabaseMac : public CrashReportDatabase {
106 public: 112 public:
107 explicit CrashReportDatabaseMac(const base::FilePath& path); 113 explicit CrashReportDatabaseMac(const base::FilePath& path);
108 virtual ~CrashReportDatabaseMac(); 114 virtual ~CrashReportDatabaseMac();
109 115
110 bool Initialize(); 116 bool Initialize(bool may_create);
111 117
112 // CrashReportDatabase: 118 // CrashReportDatabase:
113 Settings* GetSettings() override; 119 Settings* GetSettings() override;
114 OperationStatus PrepareNewCrashReport(NewReport** report) override; 120 OperationStatus PrepareNewCrashReport(NewReport** report) override;
115 OperationStatus FinishedWritingCrashReport(NewReport* report, 121 OperationStatus FinishedWritingCrashReport(NewReport* report,
116 UUID* uuid) override; 122 UUID* uuid) override;
117 OperationStatus ErrorWritingCrashReport(NewReport* report) override; 123 OperationStatus ErrorWritingCrashReport(NewReport* report) override;
118 OperationStatus LookUpCrashReport(const UUID& uuid, 124 OperationStatus LookUpCrashReport(const UUID& uuid, Report* report) override;
119 Report* report) override;
120 OperationStatus GetPendingReports(std::vector<Report>* reports) override; 125 OperationStatus GetPendingReports(std::vector<Report>* reports) override;
121 OperationStatus GetCompletedReports(std::vector<Report>* reports) override; 126 OperationStatus GetCompletedReports(std::vector<Report>* reports) override;
122 OperationStatus GetReportForUploading(const UUID& uuid, 127 OperationStatus GetReportForUploading(const UUID& uuid,
123 const Report** report) override; 128 const Report** report) override;
124 OperationStatus RecordUploadAttempt(const Report* report, 129 OperationStatus RecordUploadAttempt(const Report* report,
125 bool successful, 130 bool successful,
126 const std::string& id) override; 131 const std::string& id) override;
127 OperationStatus SkipReportUpload(const UUID& uuid) override; 132 OperationStatus SkipReportUpload(const UUID& uuid) override;
128 OperationStatus DeleteReport(const UUID& uuid) override; 133 OperationStatus DeleteReport(const UUID& uuid) override;
129 134
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 //! \brief Reads the metadata from all the reports in a database subdirectory. 179 //! \brief Reads the metadata from all the reports in a database subdirectory.
175 //! Invalid reports are skipped. 180 //! Invalid reports are skipped.
176 //! 181 //!
177 //! \param[in] path The database subdirectory path. 182 //! \param[in] path The database subdirectory path.
178 //! \param[out] reports An empty vector of reports, which will be filled. 183 //! \param[out] reports An empty vector of reports, which will be filled.
179 //! 184 //!
180 //! \return The operation status code. 185 //! \return The operation status code.
181 static OperationStatus ReportsInDirectory(const base::FilePath& path, 186 static OperationStatus ReportsInDirectory(const base::FilePath& path,
182 std::vector<Report>* reports); 187 std::vector<Report>* reports);
183 188
184
185 //! \brief Creates a database xattr name from the short constant name. 189 //! \brief Creates a database xattr name from the short constant name.
186 //! 190 //!
187 //! \param[in] name The short name of the extended attribute. 191 //! \param[in] name The short name of the extended attribute.
188 //! 192 //!
189 //! \return The long name of the extended attribute. 193 //! \return The long name of the extended attribute.
190 static std::string XattrName(const base::StringPiece& name); 194 static std::string XattrName(const base::StringPiece& name);
191 195
192 base::FilePath base_dir_; 196 base::FilePath base_dir_;
193 Settings settings_; 197 Settings settings_;
194 InitializationStateDcheck initialized_; 198 InitializationStateDcheck initialized_;
195 199
196 DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac); 200 DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac);
197 }; 201 };
198 202
199 CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path) 203 CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path)
200 : CrashReportDatabase(), 204 : CrashReportDatabase(),
201 base_dir_(path), 205 base_dir_(path),
202 settings_(base_dir_.Append(kSettings)), 206 settings_(base_dir_.Append(kSettings)),
203 initialized_() { 207 initialized_() {
204 } 208 }
205 209
206 CrashReportDatabaseMac::~CrashReportDatabaseMac() {} 210 CrashReportDatabaseMac::~CrashReportDatabaseMac() {}
207 211
208 bool CrashReportDatabaseMac::Initialize() { 212 bool CrashReportDatabaseMac::Initialize(bool may_create) {
209 INITIALIZATION_STATE_SET_INITIALIZING(initialized_); 213 INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
210 214
211 // Check if the database already exists. 215 // Check if the database already exists.
212 if (!CreateOrEnsureDirectoryExists(base_dir_)) 216 if (may_create) {
217 if (!CreateOrEnsureDirectoryExists(base_dir_)) {
218 return false;
219 }
220 } else if (!EnsureDirectoryExists(base_dir_)) {
213 return false; 221 return false;
222 }
214 223
215 // Create the three processing directories for the database. 224 // Create the three processing directories for the database.
216 for (size_t i = 0; i < arraysize(kReportDirectories); ++i) { 225 for (size_t i = 0; i < arraysize(kReportDirectories); ++i) {
217 if (!CreateOrEnsureDirectoryExists(base_dir_.Append(kReportDirectories[i]))) 226 if (!CreateOrEnsureDirectoryExists(base_dir_.Append(kReportDirectories[i])))
218 return false; 227 return false;
219 } 228 }
220 229
221 if (!settings_.Initialize()) 230 if (!settings_.Initialize())
222 return false; 231 return false;
223 232
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 return kFileSystemError; 503 return kFileSystemError;
495 } 504 }
496 505
497 return kNoError; 506 return kNoError;
498 } 507 }
499 508
500 base::FilePath CrashReportDatabaseMac::LocateCrashReport(const UUID& uuid) { 509 base::FilePath CrashReportDatabaseMac::LocateCrashReport(const UUID& uuid) {
501 const std::string target_uuid = uuid.ToString(); 510 const std::string target_uuid = uuid.ToString();
502 for (size_t i = 0; i < arraysize(kReportDirectories); ++i) { 511 for (size_t i = 0; i < arraysize(kReportDirectories); ++i) {
503 base::FilePath path = 512 base::FilePath path =
504 base_dir_.Append(kReportDirectories[i]) 513 base_dir_.Append(kReportDirectories[i])
505 .Append(target_uuid + "." + kCrashReportFileExtension); 514 .Append(target_uuid + "." + kCrashReportFileExtension);
506 515
507 // Test if the path exists. 516 // Test if the path exists.
508 struct stat st; 517 struct stat st;
509 if (lstat(path.value().c_str(), &st)) { 518 if (lstat(path.value().c_str(), &st)) {
510 continue; 519 continue;
511 } 520 }
512 521
513 // Check that the UUID of the report matches. 522 // Check that the UUID of the report matches.
514 std::string uuid_string; 523 std::string uuid_string;
515 if (ReadXattr(path, XattrName(kXattrUUID), 524 if (ReadXattr(path, XattrName(kXattrUUID),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 } 618 }
610 619
611 return kNoError; 620 return kNoError;
612 } 621 }
613 622
614 // static 623 // static
615 std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) { 624 std::string CrashReportDatabaseMac::XattrName(const base::StringPiece& name) {
616 return base::StringPrintf("com.googlecode.crashpad.%s", name.data()); 625 return base::StringPrintf("com.googlecode.crashpad.%s", name.data());
617 } 626 }
618 627
628 scoped_ptr<CrashReportDatabase> InitializeInternal(const base::FilePath& path,
629 bool may_create) {
630 scoped_ptr<CrashReportDatabaseMac> database_mac(
631 new CrashReportDatabaseMac(path));
632 if (!database_mac->Initialize(may_create))
633 database_mac.reset();
634
635 return scoped_ptr<CrashReportDatabase>(database_mac.release());
636 }
637
619 } // namespace 638 } // namespace
620 639
621 // static 640 // static
622 scoped_ptr<CrashReportDatabase> CrashReportDatabase::Initialize( 641 scoped_ptr<CrashReportDatabase> CrashReportDatabase::Initialize(
623 const base::FilePath& path) { 642 const base::FilePath& path) {
624 scoped_ptr<CrashReportDatabaseMac> database_mac( 643 return InitializeInternal(path, true);
625 new CrashReportDatabaseMac(path)); 644 }
626 if (!database_mac->Initialize())
627 database_mac.reset();
628 645
629 return scoped_ptr<CrashReportDatabase>(database_mac.release()); 646 // static
647 scoped_ptr<CrashReportDatabase> CrashReportDatabase::InitializeWithoutCreating(
648 const base::FilePath& path) {
649 return InitializeInternal(path, false);
630 } 650 }
631 651
632 } // namespace crashpad 652 } // namespace crashpad
OLDNEW
« no previous file with comments | « client/crash_report_database.h ('k') | client/crash_report_database_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698