Commit 3027c932 authored by bcwhite's avatar bcwhite Committed by Commit bot

Fix problem with persistent histograms getting ID of zero.

1) Create persistent histogram records in an atomic manner
so there are no half-filled entries left around should the
process crash before it completes.

2) Validate the ID is non-zero before trying to access a
histogram from persistent storage.

BUG=649371

Review-Url: https://codereview.chromium.org/2367503002
Cr-Commit-Position: refs/heads/master@{#420654}
parent 0e30b8a0
...@@ -38,6 +38,8 @@ enum : uint32_t { ...@@ -38,6 +38,8 @@ enum : uint32_t {
kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2 kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2
kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1 kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1
kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1 kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1
kTypeIdHistogramUnderConstruction = ~kTypeIdHistogram,
}; };
// The current globally-active persistent allocator for all new histograms. // The current globally-active persistent allocator for all new histograms.
...@@ -274,8 +276,15 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram( ...@@ -274,8 +276,15 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
memory_allocator_->GetAsObject<PersistentHistogramData>( memory_allocator_->GetAsObject<PersistentHistogramData>(
ref, kTypeIdHistogram); ref, kTypeIdHistogram);
size_t length = memory_allocator_->GetAllocSize(ref); size_t length = memory_allocator_->GetAllocSize(ref);
// Check that metadata is reasonable: name is NUL terminated and non-empty,
// ID fields have been loaded with a hash of the name (0 is considered
// unset/invalid).
if (!histogram_data || if (!histogram_data ||
reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') { reinterpret_cast<char*>(histogram_data)[length - 1] != '\0' ||
histogram_data->name[0] == '\0' ||
histogram_data->samples_metadata.id == 0 ||
histogram_data->logged_metadata.id == 0) {
RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA); RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
NOTREACHED(); NOTREACHED();
return nullptr; return nullptr;
...@@ -302,14 +311,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( ...@@ -302,14 +311,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
// Create the metadata necessary for a persistent sparse histogram. This // Create the metadata necessary for a persistent sparse histogram. This
// is done first because it is a small subset of what is required for // is done first because it is a small subset of what is required for
// other histograms. // other histograms. The type is "under construction" so that a crash
// during the datafill doesn't leave a bad record around that could cause
// confusion by another process trying to read it. It will be corrected
// once histogram construction is complete.
PersistentMemoryAllocator::Reference histogram_ref = PersistentMemoryAllocator::Reference histogram_ref =
memory_allocator_->Allocate( memory_allocator_->Allocate(
offsetof(PersistentHistogramData, name) + name.length() + 1, offsetof(PersistentHistogramData, name) + name.length() + 1,
kTypeIdHistogram); kTypeIdHistogramUnderConstruction);
PersistentHistogramData* histogram_data = PersistentHistogramData* histogram_data =
memory_allocator_->GetAsObject<PersistentHistogramData>(histogram_ref, memory_allocator_->GetAsObject<PersistentHistogramData>(
kTypeIdHistogram); histogram_ref, kTypeIdHistogramUnderConstruction);
if (histogram_data) { if (histogram_data) {
memcpy(histogram_data->name, name.c_str(), name.size() + 1); memcpy(histogram_data->name, name.c_str(), name.size() + 1);
histogram_data->histogram_type = histogram_type; histogram_data->histogram_type = histogram_type;
...@@ -365,6 +377,11 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( ...@@ -365,6 +377,11 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
// correct before commiting the new histogram to persistent space. // correct before commiting the new histogram to persistent space.
std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data); std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
DCHECK(histogram); DCHECK(histogram);
DCHECK_NE(0U, histogram_data->samples_metadata.id);
DCHECK_NE(0U, histogram_data->logged_metadata.id);
memory_allocator_->ChangeType(histogram_ref, kTypeIdHistogram,
kTypeIdHistogramUnderConstruction);
if (ref_ptr != nullptr) if (ref_ptr != nullptr)
*ref_ptr = histogram_ref; *ref_ptr = histogram_ref;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment