| Index: base/metrics/histogram.cc
|
| diff --git a/base/metrics/histogram.cc b/base/metrics/histogram.cc
|
| index 35197e26e395a9d08bd4bd9826938241e37754fe..b0f5e4e9aacf3f4434fc3ccaffe0536ea4f67786 100644
|
| --- a/base/metrics/histogram.cc
|
| +++ b/base/metrics/histogram.cc
|
| @@ -153,10 +153,21 @@ HistogramBase* Histogram::Factory::Build() {
|
| PersistentHistogramAllocator::ImportGlobalHistograms();
|
|
|
| HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
|
| +
|
| + // crbug.com/588946 debugging. See comment at end of function.
|
| + const BucketRanges* created_ranges =
|
| + reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
|
| + const BucketRanges* registered_ranges =
|
| + reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
|
| + scoped_ptr<HistogramBase> tentative_histogram;
|
| + PersistentHistogramAllocator* allocator =
|
| + reinterpret_cast<PersistentHistogramAllocator*>(0xDEADBEEF);
|
| + PersistentHistogramAllocator::Reference histogram_ref = 0xDEADBEEF;
|
| +
|
| if (!histogram) {
|
| // To avoid racy destruction at shutdown, the following will be leaked.
|
| - const BucketRanges* created_ranges = CreateRanges();
|
| - const BucketRanges* registered_ranges =
|
| + created_ranges = CreateRanges();
|
| + registered_ranges =
|
| StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges);
|
|
|
| // In most cases, the bucket-count, minimum, and maximum values are known
|
| @@ -169,15 +180,15 @@ HistogramBase* Histogram::Factory::Build() {
|
| minimum_ = registered_ranges->range(1);
|
| maximum_ = registered_ranges->range(bucket_count_ - 1);
|
| }
|
| + CHECK_LT(0, minimum_);
|
| + CHECK_LT(0, maximum_);
|
|
|
| // Try to create the histogram using a "persistent" allocator. As of
|
| // 2016-02-25, the availability of such is controlled by a base::Feature
|
| // that is off by default. If the allocator doesn't exist or if
|
| // allocating from it fails, code below will allocate the histogram from
|
| // the process heap.
|
| - PersistentHistogramAllocator::Reference histogram_ref = 0;
|
| - scoped_ptr<HistogramBase> tentative_histogram;
|
| - PersistentHistogramAllocator* allocator =
|
| + allocator =
|
| PersistentHistogramAllocator::GetGlobalAllocator();
|
| if (allocator) {
|
| tentative_histogram = allocator->AllocateHistogram(
|
| @@ -188,16 +199,33 @@ HistogramBase* Histogram::Factory::Build() {
|
| registered_ranges,
|
| flags_,
|
| &histogram_ref);
|
| + CHECK_LT(0, minimum_);
|
| + CHECK_LT(0, maximum_);
|
| + CHECK_EQ(
|
| + minimum_,
|
| + static_cast<Histogram*>(tentative_histogram.get())->declared_min_);
|
| + CHECK_EQ(
|
| + maximum_,
|
| + static_cast<Histogram*>(tentative_histogram.get())->declared_max_);
|
| }
|
|
|
| // Handle the case where no persistent allocator is present or the
|
| // persistent allocation fails (perhaps because it is full).
|
| if (!tentative_histogram) {
|
| - DCHECK(!histogram_ref); // Should never have been set.
|
| - DCHECK(!allocator); // Shouldn't have failed.
|
| + // DCHECK(!histogram_ref); // Should never have been set.
|
| + // DCHECK(!allocator); // Shouldn't have failed.
|
| flags_ &= ~HistogramBase::kIsPersistent;
|
| tentative_histogram = HeapAlloc(registered_ranges);
|
| tentative_histogram->SetFlags(flags_);
|
| +
|
| + CHECK_LT(0, minimum_);
|
| + CHECK_LT(0, maximum_);
|
| + CHECK_EQ(
|
| + minimum_,
|
| + static_cast<Histogram*>(tentative_histogram.get())->declared_min_);
|
| + CHECK_EQ(
|
| + maximum_,
|
| + static_cast<Histogram*>(tentative_histogram.get())->declared_max_);
|
| }
|
|
|
| FillHistogram(tentative_histogram.get());
|
| @@ -211,7 +239,7 @@ HistogramBase* Histogram::Factory::Build() {
|
| tentative_histogram.release());
|
|
|
| // Persistent histograms need some follow-up processing.
|
| - if (histogram_ref) {
|
| + if (histogram_ref != 0xDEADBEEF) {
|
| allocator->FinalizeHistogram(histogram_ref,
|
| histogram == tentative_histogram_ptr);
|
| }
|
| @@ -224,6 +252,15 @@ HistogramBase* Histogram::Factory::Build() {
|
| }
|
|
|
| DCHECK_EQ(histogram_type_, histogram->GetHistogramType()) << name_;
|
| + bool bad_args = false;
|
| + HistogramBase* existing_histogram = histogram;
|
| + HistogramType existing_type = histogram->GetHistogramType();
|
| + const char* existing_name = histogram->histogram_name().c_str();
|
| + Sample existing_minimum = static_cast<Histogram*>(histogram)->declared_min_;
|
| + Sample existing_maximum = static_cast<Histogram*>(histogram)->declared_max_;
|
| + uint32_t existing_bucket_count =
|
| + static_cast<Histogram*>(histogram)->bucket_count();
|
| +
|
| if (bucket_count_ != 0 &&
|
| !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) {
|
| // The construction arguments do not match the existing histogram. This can
|
| @@ -233,8 +270,45 @@ HistogramBase* Histogram::Factory::Build() {
|
| // on dereference, but extension/Pepper APIs will guard against NULL and not
|
| // crash.
|
| DLOG(ERROR) << "Histogram " << name_ << " has bad construction arguments";
|
| - return nullptr;
|
| + bad_args = true;
|
| + histogram = nullptr;
|
| + }
|
| +
|
| +#if !DCHECK_IS_ON() && defined(OS_WIN) // Affect only Windows release builds.
|
| + // For the moment, crash here so that collected crash reports have access
|
| + // to the construction values in order to figure out why this is failing.
|
| + // TODO(bcwhite): Remove this once crbug.com/588946 is resolved. Also remove
|
| + // from beta-branch because we don't want crashes due to misbehaving
|
| + // extensions (see comment above).
|
| + if (!histogram) {
|
| + HistogramType histogram_type = histogram_type_;
|
| + HistogramBase::Sample minimum = minimum_;
|
| + HistogramBase::Sample maximum = maximum_;
|
| + uint32_t bucket_count = bucket_count_;
|
| + int32_t flags = flags_;
|
| + CHECK(histogram) << name_ << ": bad-args=" << bad_args;
|
| + base::debug::Alias(&histogram_type);
|
| + base::debug::Alias(&minimum);
|
| + base::debug::Alias(&maximum);
|
| + base::debug::Alias(&bucket_count);
|
| + base::debug::Alias(&flags);
|
| + base::debug::Alias(&created_ranges);
|
| + base::debug::Alias(®istered_ranges);
|
| + base::debug::Alias(&histogram_ref);
|
| + base::debug::Alias(&tentative_histogram);
|
| + base::debug::Alias(&allocator);
|
| + base::debug::Alias(&tentative_histogram);
|
| }
|
| +#endif
|
| +
|
| + // Down here so vars are always "used".
|
| + base::debug::Alias(&bad_args);
|
| + base::debug::Alias(&existing_histogram);
|
| + base::debug::Alias(&existing_type);
|
| + base::debug::Alias(&existing_name);
|
| + base::debug::Alias(&existing_minimum);
|
| + base::debug::Alias(&existing_maximum);
|
| + base::debug::Alias(&existing_bucket_count);
|
| return histogram;
|
| }
|
|
|
| @@ -497,8 +571,12 @@ Histogram::Histogram(const std::string& name,
|
| bucket_ranges_(ranges),
|
| declared_min_(minimum),
|
| declared_max_(maximum) {
|
| + CHECK_LT(0, minimum);
|
| + CHECK_LT(0, maximum);
|
| if (ranges)
|
| samples_.reset(new SampleVector(HashMetricName(name), ranges));
|
| + CHECK_EQ(minimum, declared_min_);
|
| + CHECK_EQ(maximum, declared_max_);
|
| }
|
|
|
| Histogram::Histogram(const std::string& name,
|
| @@ -514,12 +592,16 @@ Histogram::Histogram(const std::string& name,
|
| bucket_ranges_(ranges),
|
| declared_min_(minimum),
|
| declared_max_(maximum) {
|
| + CHECK_LT(0, minimum);
|
| + CHECK_LT(0, maximum);
|
| if (ranges) {
|
| samples_.reset(new SampleVector(HashMetricName(name),
|
| counts, counts_size, meta, ranges));
|
| logged_samples_.reset(new SampleVector(samples_->id(), logged_counts,
|
| counts_size, logged_meta, ranges));
|
| }
|
| + CHECK_EQ(minimum, declared_min_);
|
| + CHECK_EQ(maximum, declared_max_);
|
| }
|
|
|
| Histogram::~Histogram() {
|
|
|