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

Side by Side Diff: base/metrics/histogram.cc

Issue 141393002: Return a NULL histogram pointer on construction error (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add construction param to restore old CHECK for non-API calls Created 6 years, 11 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Histogram is an object that aggregates statistics, and can summarize them in 5 // Histogram is an object that aggregates statistics, and can summarize them in
6 // various forms, including ASCII graphical, HTML, and numerically (as a 6 // various forms, including ASCII graphical, HTML, and numerically (as a
7 // vector of numbers corresponding to each of the aggregating buckets). 7 // vector of numbers corresponding to each of the aggregating buckets).
8 // See header file for details and examples. 8 // See header file for details and examples.
9 9
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 } 69 }
70 70
71 bool ValidateRangeChecksum(const HistogramBase& histogram, 71 bool ValidateRangeChecksum(const HistogramBase& histogram,
72 uint32 range_checksum) { 72 uint32 range_checksum) {
73 const Histogram& casted_histogram = 73 const Histogram& casted_histogram =
74 static_cast<const Histogram&>(histogram); 74 static_cast<const Histogram&>(histogram);
75 75
76 return casted_histogram.bucket_ranges()->checksum() == range_checksum; 76 return casted_histogram.bucket_ranges()->checksum() == range_checksum;
77 } 77 }
78 78
79 // DummyHistogram is an object that overrides Histogram's Add* functions
80 // to provide no functionality. This can be returned in the case of mismatched
81 // construction arguments to any of the other Histograms' FactoryGet calls.
82 class DummyHistogram : public Histogram {
83 public:
84 virtual void Add(Sample value) OVERRIDE {}
85 virtual void AddSamples(const HistogramSamples& samples) OVERRIDE {}
86 virtual bool AddSamplesFromPickle(PickleIterator* iter) OVERRIDE {
87 return false;
88 }
89
90 DummyHistogram() : Histogram("Dummy", 0, 1, NULL) {}
91
92 private:
93 DISALLOW_COPY_AND_ASSIGN(DummyHistogram);
94 };
95
79 } // namespace 96 } // namespace
80 97
81 typedef HistogramBase::Count Count; 98 typedef HistogramBase::Count Count;
82 typedef HistogramBase::Sample Sample; 99 typedef HistogramBase::Sample Sample;
83 100
84 // static 101 // static
85 const size_t Histogram::kBucketCount_MAX = 16384u; 102 const size_t Histogram::kBucketCount_MAX = 16384u;
86 103
87 HistogramBase* Histogram::FactoryGet(const string& name, 104 HistogramBase* Histogram::FactoryGet(const string& name,
88 Sample minimum, 105 Sample minimum,
89 Sample maximum, 106 Sample maximum,
90 size_t bucket_count, 107 size_t bucket_count,
91 int32 flags) { 108 int32 flags,
109 int32 construction_behavior) {
92 bool valid_arguments = 110 bool valid_arguments =
93 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); 111 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
94 DCHECK(valid_arguments); 112 DCHECK(valid_arguments);
95 113
96 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 114 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
97 if (!histogram) { 115 if (!histogram) {
98 // To avoid racy destruction at shutdown, the following will be leaked. 116 // To avoid racy destruction at shutdown, the following will be leaked.
99 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 117 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
100 InitializeBucketRanges(minimum, maximum, ranges); 118 InitializeBucketRanges(minimum, maximum, ranges);
101 const BucketRanges* registered_ranges = 119 const BucketRanges* registered_ranges =
102 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 120 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
103 121
104 Histogram* tentative_histogram = 122 Histogram* tentative_histogram =
105 new Histogram(name, minimum, maximum, registered_ranges); 123 new Histogram(name, minimum, maximum, registered_ranges);
106 124
107 tentative_histogram->SetFlags(flags); 125 tentative_histogram->SetFlags(flags);
108 histogram = 126 histogram =
109 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 127 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
110 } 128 }
111 129
112 DCHECK_EQ(HISTOGRAM, histogram->GetHistogramType()); 130 DCHECK_EQ(HISTOGRAM, histogram->GetHistogramType());
113 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 131 if (construction_behavior == kAllowBadConstruction) {
132 if (!histogram->HasConstructionArguments(minimum, maximum, bucket_count)) {
133 // The construction arguments do not match the existing histogram. This
134 // can come about if an extension updates in the middle of a chrome run
135 // and has changed one of them. We return a dummy object here instead of
136 // crashing so poor use of extension/Pepper APIs do not cause crashes in
137 // Chrome.
138 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments";
139 DummyHistogram* tentative_histogram = new DummyHistogram;
140 histogram =
141 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
142 }
143 } else {
144 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
145 }
114 return histogram; 146 return histogram;
115 } 147 }
116 148
117 HistogramBase* Histogram::FactoryTimeGet(const string& name, 149 HistogramBase* Histogram::FactoryTimeGet(const string& name,
118 TimeDelta minimum, 150 TimeDelta minimum,
119 TimeDelta maximum, 151 TimeDelta maximum,
120 size_t bucket_count, 152 size_t bucket_count,
121 int32 flags) { 153 int32 flags,
154 int32 construction_behavior) {
122 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), 155 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
123 bucket_count, flags); 156 bucket_count, flags, construction_behavior);
124 } 157 }
125 158
126 TimeTicks Histogram::DebugNow() { 159 TimeTicks Histogram::DebugNow() {
127 #ifndef NDEBUG 160 #ifndef NDEBUG
128 return TimeTicks::Now(); 161 return TimeTicks::Now();
129 #else 162 #else
130 return TimeTicks(); 163 return TimeTicks();
131 #endif 164 #endif
132 } 165 }
133 166
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 // LinearHistogram: This histogram uses a traditional set of evenly spaced 543 // LinearHistogram: This histogram uses a traditional set of evenly spaced
511 // buckets. 544 // buckets.
512 //------------------------------------------------------------------------------ 545 //------------------------------------------------------------------------------
513 546
514 LinearHistogram::~LinearHistogram() {} 547 LinearHistogram::~LinearHistogram() {}
515 548
516 HistogramBase* LinearHistogram::FactoryGet(const string& name, 549 HistogramBase* LinearHistogram::FactoryGet(const string& name,
517 Sample minimum, 550 Sample minimum,
518 Sample maximum, 551 Sample maximum,
519 size_t bucket_count, 552 size_t bucket_count,
520 int32 flags) { 553 int32 flags,
554 int32 construction_behavior) {
521 return FactoryGetWithRangeDescription( 555 return FactoryGetWithRangeDescription(
522 name, minimum, maximum, bucket_count, flags, NULL); 556 name, minimum, maximum, bucket_count, flags, NULL, construction_behavior);
523 } 557 }
524 558
525 HistogramBase* LinearHistogram::FactoryTimeGet(const string& name, 559 HistogramBase* LinearHistogram::FactoryTimeGet(const string& name,
526 TimeDelta minimum, 560 TimeDelta minimum,
527 TimeDelta maximum, 561 TimeDelta maximum,
528 size_t bucket_count, 562 size_t bucket_count,
529 int32 flags) { 563 int32 flags,
564 int32 construction_behavior) {
530 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(), 565 return FactoryGet(name, minimum.InMilliseconds(), maximum.InMilliseconds(),
531 bucket_count, flags); 566 bucket_count, flags, construction_behavior);
532 } 567 }
533 568
534 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription( 569 HistogramBase* LinearHistogram::FactoryGetWithRangeDescription(
535 const std::string& name, 570 const std::string& name,
536 Sample minimum, 571 Sample minimum,
537 Sample maximum, 572 Sample maximum,
538 size_t bucket_count, 573 size_t bucket_count,
539 int32 flags, 574 int32 flags,
540 const DescriptionPair descriptions[]) { 575 const DescriptionPair descriptions[],
576 int32 construction_behavior) {
541 bool valid_arguments = Histogram::InspectConstructionArguments( 577 bool valid_arguments = Histogram::InspectConstructionArguments(
542 name, &minimum, &maximum, &bucket_count); 578 name, &minimum, &maximum, &bucket_count);
543 DCHECK(valid_arguments); 579 DCHECK(valid_arguments);
544 580
545 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name); 581 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name);
546 if (!histogram) { 582 if (!histogram) {
547 // To avoid racy destruction at shutdown, the following will be leaked. 583 // To avoid racy destruction at shutdown, the following will be leaked.
548 BucketRanges* ranges = new BucketRanges(bucket_count + 1); 584 BucketRanges* ranges = new BucketRanges(bucket_count + 1);
549 InitializeBucketRanges(minimum, maximum, ranges); 585 InitializeBucketRanges(minimum, maximum, ranges);
550 const BucketRanges* registered_ranges = 586 const BucketRanges* registered_ranges =
551 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges); 587 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(ranges);
552 588
553 LinearHistogram* tentative_histogram = 589 LinearHistogram* tentative_histogram =
554 new LinearHistogram(name, minimum, maximum, registered_ranges); 590 new LinearHistogram(name, minimum, maximum, registered_ranges);
555 591
556 // Set range descriptions. 592 // Set range descriptions.
557 if (descriptions) { 593 if (descriptions) {
558 for (int i = 0; descriptions[i].description; ++i) { 594 for (int i = 0; descriptions[i].description; ++i) {
559 tentative_histogram->bucket_description_[descriptions[i].sample] = 595 tentative_histogram->bucket_description_[descriptions[i].sample] =
560 descriptions[i].description; 596 descriptions[i].description;
561 } 597 }
562 } 598 }
563 599
564 tentative_histogram->SetFlags(flags); 600 tentative_histogram->SetFlags(flags);
565 histogram = 601 histogram =
566 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram); 602 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
567 } 603 }
568 604
569 DCHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType()); 605 DCHECK_EQ(LINEAR_HISTOGRAM, histogram->GetHistogramType());
570 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count)); 606 if (construction_behavior == kAllowBadConstruction) {
607 if (!histogram->HasConstructionArguments(minimum, maximum, bucket_count)) {
608 // The construction arguments do not match the existing histogram. This
609 // can come about if an extension updates in the middle of a chrome run
610 // and has changed one of them. We return a dummy object here instead of
611 // crashing so poor use of extension/Pepper APIs do not cause crashes in
612 // Chrome.
613 DLOG(ERROR) << "Histogram " << name << " has bad construction arguments";
614 DummyHistogram* tentative_histogram = new DummyHistogram;
615 histogram =
616 StatisticsRecorder::RegisterOrDeleteDuplicate(tentative_histogram);
617 }
618 } else {
619 CHECK(histogram->HasConstructionArguments(minimum, maximum, bucket_count));
620 }
571 return histogram; 621 return histogram;
572 } 622 }
573 623
574 HistogramType LinearHistogram::GetHistogramType() const { 624 HistogramType LinearHistogram::GetHistogramType() const {
575 return LINEAR_HISTOGRAM; 625 return LINEAR_HISTOGRAM;
576 } 626 }
577 627
578 LinearHistogram::LinearHistogram(const string& name, 628 LinearHistogram::LinearHistogram(const string& name,
579 Sample minimum, 629 Sample minimum,
580 Sample maximum, 630 Sample maximum,
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 875
826 BucketRanges* bucket_ranges = new BucketRanges(ranges.size()); 876 BucketRanges* bucket_ranges = new BucketRanges(ranges.size());
827 for (size_t i = 0; i < ranges.size(); i++) { 877 for (size_t i = 0; i < ranges.size(); i++) {
828 bucket_ranges->set_range(i, ranges[i]); 878 bucket_ranges->set_range(i, ranges[i]);
829 } 879 }
830 bucket_ranges->ResetChecksum(); 880 bucket_ranges->ResetChecksum();
831 return bucket_ranges; 881 return bucket_ranges;
832 } 882 }
833 883
834 } // namespace base 884 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698