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

Unified Diff: base/metrics/persistent_histogram_allocator.cc

Issue 2367503002: Fix problem with persistent histograms getting ID of zero. (Closed)
Patch Set: added comment about metadata check 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/metrics/persistent_histogram_allocator.cc
diff --git a/base/metrics/persistent_histogram_allocator.cc b/base/metrics/persistent_histogram_allocator.cc
index 5320d3fa45920353dc272d0a4fab3a376208673e..c6197873708f180fc4239f41f0b0995613a59765 100644
--- a/base/metrics/persistent_histogram_allocator.cc
+++ b/base/metrics/persistent_histogram_allocator.cc
@@ -38,6 +38,8 @@ enum : uint32_t {
kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2
kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1
kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1
+
+ kTypeIdHistogramUnderConstruction = ~kTypeIdHistogram,
};
// The current globally-active persistent allocator for all new histograms.
@@ -274,8 +276,15 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::GetHistogram(
memory_allocator_->GetAsObject<PersistentHistogramData>(
ref, kTypeIdHistogram);
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 ||
- 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);
NOTREACHED();
return nullptr;
@@ -302,14 +311,17 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
// Create the metadata necessary for a persistent sparse histogram. This
// 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 =
memory_allocator_->Allocate(
offsetof(PersistentHistogramData, name) + name.length() + 1,
- kTypeIdHistogram);
+ kTypeIdHistogramUnderConstruction);
PersistentHistogramData* histogram_data =
- memory_allocator_->GetAsObject<PersistentHistogramData>(histogram_ref,
- kTypeIdHistogram);
+ memory_allocator_->GetAsObject<PersistentHistogramData>(
+ histogram_ref, kTypeIdHistogramUnderConstruction);
if (histogram_data) {
memcpy(histogram_data->name, name.c_str(), name.size() + 1);
histogram_data->histogram_type = histogram_type;
@@ -365,6 +377,11 @@ std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
// correct before commiting the new histogram to persistent space.
std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
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)
*ref_ptr = histogram_ref;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698