CrashReportDatabase: use InitializationStateDcheck to guard against API

abuses and misuses.

TEST=crashpad_client_test CrashReportDatabaseTest.*
R=rsesek@chromium.org, scottmg@chromium.org

Review URL: https://codereview.chromium.org/987313003
This commit is contained in:
Mark Mentovai 2015-03-10 13:24:44 -04:00
parent 4ef649d189
commit 7979d9db4e
2 changed files with 56 additions and 3 deletions

View File

@ -34,6 +34,7 @@
#include "client/settings.h"
#include "util/file/file_io.h"
#include "util/mac/xattr.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
@ -191,6 +192,7 @@ class CrashReportDatabaseMac : public CrashReportDatabase {
base::FilePath base_dir_;
Settings settings_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseMac);
};
@ -198,12 +200,15 @@ class CrashReportDatabaseMac : public CrashReportDatabase {
CrashReportDatabaseMac::CrashReportDatabaseMac(const base::FilePath& path)
: CrashReportDatabase(),
base_dir_(path),
settings_(base_dir_.Append(kSettings)) {
settings_(base_dir_.Append(kSettings)),
initialized_() {
}
CrashReportDatabaseMac::~CrashReportDatabaseMac() {}
bool CrashReportDatabaseMac::Initialize() {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
// Check if the database already exists.
if (!CreateOrEnsureDirectoryExists(base_dir_))
return false;
@ -219,15 +224,22 @@ bool CrashReportDatabaseMac::Initialize() {
// Write an xattr as the last step, to ensure the filesystem has support for
// them. This attribute will never be read.
return WriteXattrBool(base_dir_, XattrName(kXattrDatabaseInitialized), true);
if (!WriteXattrBool(base_dir_, XattrName(kXattrDatabaseInitialized), true))
return false;
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
Settings* CrashReportDatabaseMac::GetSettings() {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return &settings_;
}
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::PrepareNewCrashReport(NewReport** out_report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
uuid_t uuid_gen;
uuid_generate(uuid_gen);
UUID uuid(uuid_gen);
@ -260,6 +272,8 @@ CrashReportDatabaseMac::PrepareNewCrashReport(NewReport** out_report) {
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::FinishedWritingCrashReport(NewReport* report,
UUID* uuid) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Takes ownership of the |handle| and the O_EXLOCK.
base::ScopedFD lock(report->handle);
@ -296,6 +310,8 @@ CrashReportDatabaseMac::FinishedWritingCrashReport(NewReport* report,
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::ErrorWritingCrashReport(NewReport* report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Takes ownership of the |handle| and the O_EXLOCK.
base::ScopedFD lock(report->handle);
@ -315,6 +331,8 @@ CrashReportDatabaseMac::ErrorWritingCrashReport(NewReport* report) {
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::LookUpCrashReport(const UUID& uuid,
CrashReportDatabase::Report* report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
base::FilePath path = LocateCrashReport(uuid);
if (path.empty())
return kReportNotFound;
@ -334,18 +352,24 @@ CrashReportDatabaseMac::LookUpCrashReport(const UUID& uuid,
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::GetPendingReports(
std::vector<CrashReportDatabase::Report>* reports) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return ReportsInDirectory(base_dir_.Append(kUploadPendingDirectory), reports);
}
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::GetCompletedReports(
std::vector<CrashReportDatabase::Report>* reports) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
return ReportsInDirectory(base_dir_.Append(kCompletedDirectory), reports);
}
CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::GetReportForUploading(const UUID& uuid,
const Report** report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
base::FilePath report_path = LocateCrashReport(uuid);
if (report_path.empty())
return kReportNotFound;
@ -369,6 +393,8 @@ CrashReportDatabase::OperationStatus
CrashReportDatabaseMac::RecordUploadAttempt(const Report* report,
bool successful,
const std::string& id) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
DCHECK(report);
DCHECK(successful || id.empty());
@ -425,6 +451,8 @@ CrashReportDatabaseMac::RecordUploadAttempt(const Report* report,
CrashReportDatabase::OperationStatus CrashReportDatabaseMac::SkipReportUpload(
const UUID& uuid) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
base::FilePath report_path = LocateCrashReport(uuid);
if (report_path.empty())
return kReportNotFound;

View File

@ -24,6 +24,7 @@
#include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "util/misc/initialization_state_dcheck.h"
namespace crashpad {
@ -543,18 +544,21 @@ class CrashReportDatabaseWin : public CrashReportDatabase {
scoped_ptr<Metadata> AcquireMetadata();
base::FilePath base_dir_;
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(CrashReportDatabaseWin);
};
CrashReportDatabaseWin::CrashReportDatabaseWin(const base::FilePath& path)
: CrashReportDatabase(), base_dir_(path) {
: CrashReportDatabase(), base_dir_(path), initialized_() {
}
CrashReportDatabaseWin::~CrashReportDatabaseWin() {
}
bool CrashReportDatabaseWin::Initialize() {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
// Ensure the database and report subdirectories exist.
if (!CreateDirectoryIfNecessary(base_dir_) ||
!CreateDirectoryIfNecessary(base_dir_.Append(kReportsDirectory)))
@ -563,10 +567,13 @@ bool CrashReportDatabaseWin::Initialize() {
// TODO(scottmg): When are completed reports pruned from disk? Delete here or
// maybe on AcquireMetadata().
INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
}
Settings* CrashReportDatabaseWin::GetSettings() {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Port to Win https://code.google.com/p/crashpad/issues/detail?id=13.
NOTREACHED();
return nullptr;
@ -574,6 +581,8 @@ Settings* CrashReportDatabaseWin::GetSettings() {
OperationStatus CrashReportDatabaseWin::PrepareNewCrashReport(
NewReport** report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
::UUID system_uuid;
if (UuidCreate(&system_uuid) != RPC_S_OK)
return kFileSystemError;
@ -599,6 +608,8 @@ OperationStatus CrashReportDatabaseWin::PrepareNewCrashReport(
OperationStatus CrashReportDatabaseWin::FinishedWritingCrashReport(
NewReport* report,
UUID* uuid) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Take ownership of the report, and cast to our private version with UUID.
scoped_ptr<NewReportDisk> scoped_report(static_cast<NewReportDisk*>(report));
// Take ownership of the file handle.
@ -617,6 +628,8 @@ OperationStatus CrashReportDatabaseWin::FinishedWritingCrashReport(
OperationStatus CrashReportDatabaseWin::ErrorWritingCrashReport(
NewReport* report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Take ownership of the report, and cast to our private version with UUID.
scoped_ptr<NewReportDisk> scoped_report(static_cast<NewReportDisk*>(report));
@ -635,6 +648,8 @@ OperationStatus CrashReportDatabaseWin::ErrorWritingCrashReport(
OperationStatus CrashReportDatabaseWin::LookUpCrashReport(const UUID& uuid,
Report* report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
scoped_ptr<Metadata> metadata(AcquireMetadata());
if (!metadata)
return kDatabaseError;
@ -648,6 +663,8 @@ OperationStatus CrashReportDatabaseWin::LookUpCrashReport(const UUID& uuid,
OperationStatus CrashReportDatabaseWin::GetPendingReports(
std::vector<Report>* reports) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
scoped_ptr<Metadata> metadata(AcquireMetadata());
return metadata ? metadata->FindReports(ReportState::kPending, reports)
: kDatabaseError;
@ -655,6 +672,8 @@ OperationStatus CrashReportDatabaseWin::GetPendingReports(
OperationStatus CrashReportDatabaseWin::GetCompletedReports(
std::vector<Report>* reports) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
scoped_ptr<Metadata> metadata(AcquireMetadata());
return metadata ? metadata->FindReports(ReportState::kCompleted, reports)
: kDatabaseError;
@ -663,6 +682,8 @@ OperationStatus CrashReportDatabaseWin::GetCompletedReports(
OperationStatus CrashReportDatabaseWin::GetReportForUploading(
const UUID& uuid,
const Report** report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
scoped_ptr<Metadata> metadata(AcquireMetadata());
if (!metadata)
return kDatabaseError;
@ -692,6 +713,8 @@ OperationStatus CrashReportDatabaseWin::RecordUploadAttempt(
const Report* report,
bool successful,
const std::string& id) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
// Take ownership, allocated in GetReportForUploading.
scoped_ptr<const Report> upload_report(report);
scoped_ptr<Metadata> metadata(AcquireMetadata());
@ -716,6 +739,8 @@ OperationStatus CrashReportDatabaseWin::RecordUploadAttempt(
}
OperationStatus CrashReportDatabaseWin::SkipReportUpload(const UUID& uuid) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
scoped_ptr<Metadata> metadata(AcquireMetadata());
if (!metadata)
return kDatabaseError;