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

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

Issue 1825143002: Revert of Collect information about failing histogram factory calls. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « no previous file | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 }; 146 };
147 147
148 HistogramBase* Histogram::Factory::Build() { 148 HistogramBase* Histogram::Factory::Build() {
149 // Import histograms from known persistent storage. Histograms could have 149 // Import histograms from known persistent storage. Histograms could have
150 // been added by other processes and they must be fetched and recognized 150 // been added by other processes and they must be fetched and recognized
151 // locally in order to be found by FindHistograms() below. If the persistent 151 // locally in order to be found by FindHistograms() below. If the persistent
152 // memory segment is not shared between processes, this call does nothing. 152 // memory segment is not shared between processes, this call does nothing.
153 PersistentHistogramAllocator::ImportGlobalHistograms(); 153 PersistentHistogramAllocator::ImportGlobalHistograms();
154 154
155 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_); 155 HistogramBase* histogram = StatisticsRecorder::FindHistogram(name_);
156
157 // crbug.com/588946 debugging. See comment at end of function.
158 const BucketRanges* created_ranges =
159 reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
160 const BucketRanges* registered_ranges =
161 reinterpret_cast<const BucketRanges*>(0xDEADBEEF);
162 scoped_ptr<HistogramBase> tentative_histogram;
163 PersistentHistogramAllocator* allocator =
164 reinterpret_cast<PersistentHistogramAllocator*>(0xDEADBEEF);
165 PersistentHistogramAllocator::Reference histogram_ref = 0xDEADBEEF;
166
167 if (!histogram) { 156 if (!histogram) {
168 // To avoid racy destruction at shutdown, the following will be leaked. 157 // To avoid racy destruction at shutdown, the following will be leaked.
169 created_ranges = CreateRanges(); 158 const BucketRanges* created_ranges = CreateRanges();
170 registered_ranges = 159 const BucketRanges* registered_ranges =
171 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges); 160 StatisticsRecorder::RegisterOrDeleteDuplicateRanges(created_ranges);
172 161
173 // In most cases, the bucket-count, minimum, and maximum values are known 162 // In most cases, the bucket-count, minimum, and maximum values are known
174 // when the code is written and so are passed in explicitly. In other 163 // when the code is written and so are passed in explicitly. In other
175 // cases (such as with a CustomHistogram), they are calculated dynamically 164 // cases (such as with a CustomHistogram), they are calculated dynamically
176 // at run-time. In the latter case, those ctor parameters are zero and 165 // at run-time. In the latter case, those ctor parameters are zero and
177 // the results extracted from the result of CreateRanges(). 166 // the results extracted from the result of CreateRanges().
178 if (bucket_count_ == 0) { 167 if (bucket_count_ == 0) {
179 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count()); 168 bucket_count_ = static_cast<uint32_t>(registered_ranges->bucket_count());
180 minimum_ = registered_ranges->range(1); 169 minimum_ = registered_ranges->range(1);
181 maximum_ = registered_ranges->range(bucket_count_ - 1); 170 maximum_ = registered_ranges->range(bucket_count_ - 1);
182 } 171 }
183 CHECK_LT(0, minimum_);
184 CHECK_LT(0, maximum_);
185 172
186 // Try to create the histogram using a "persistent" allocator. As of 173 // Try to create the histogram using a "persistent" allocator. As of
187 // 2016-02-25, the availability of such is controlled by a base::Feature 174 // 2016-02-25, the availability of such is controlled by a base::Feature
188 // that is off by default. If the allocator doesn't exist or if 175 // that is off by default. If the allocator doesn't exist or if
189 // allocating from it fails, code below will allocate the histogram from 176 // allocating from it fails, code below will allocate the histogram from
190 // the process heap. 177 // the process heap.
191 allocator = 178 PersistentHistogramAllocator::Reference histogram_ref = 0;
179 scoped_ptr<HistogramBase> tentative_histogram;
180 PersistentHistogramAllocator* allocator =
192 PersistentHistogramAllocator::GetGlobalAllocator(); 181 PersistentHistogramAllocator::GetGlobalAllocator();
193 if (allocator) { 182 if (allocator) {
194 tentative_histogram = allocator->AllocateHistogram( 183 tentative_histogram = allocator->AllocateHistogram(
195 histogram_type_, 184 histogram_type_,
196 name_, 185 name_,
197 minimum_, 186 minimum_,
198 maximum_, 187 maximum_,
199 registered_ranges, 188 registered_ranges,
200 flags_, 189 flags_,
201 &histogram_ref); 190 &histogram_ref);
202 CHECK_LT(0, minimum_);
203 CHECK_LT(0, maximum_);
204 CHECK_EQ(
205 minimum_,
206 static_cast<Histogram*>(tentative_histogram.get())->declared_min_);
207 CHECK_EQ(
208 maximum_,
209 static_cast<Histogram*>(tentative_histogram.get())->declared_max_);
210 } 191 }
211 192
212 // Handle the case where no persistent allocator is present or the 193 // Handle the case where no persistent allocator is present or the
213 // persistent allocation fails (perhaps because it is full). 194 // persistent allocation fails (perhaps because it is full).
214 if (!tentative_histogram) { 195 if (!tentative_histogram) {
215 // DCHECK(!histogram_ref); // Should never have been set. 196 DCHECK(!histogram_ref); // Should never have been set.
216 // DCHECK(!allocator); // Shouldn't have failed. 197 DCHECK(!allocator); // Shouldn't have failed.
217 flags_ &= ~HistogramBase::kIsPersistent; 198 flags_ &= ~HistogramBase::kIsPersistent;
218 tentative_histogram = HeapAlloc(registered_ranges); 199 tentative_histogram = HeapAlloc(registered_ranges);
219 tentative_histogram->SetFlags(flags_); 200 tentative_histogram->SetFlags(flags_);
220
221 CHECK_LT(0, minimum_);
222 CHECK_LT(0, maximum_);
223 CHECK_EQ(
224 minimum_,
225 static_cast<Histogram*>(tentative_histogram.get())->declared_min_);
226 CHECK_EQ(
227 maximum_,
228 static_cast<Histogram*>(tentative_histogram.get())->declared_max_);
229 } 201 }
230 202
231 FillHistogram(tentative_histogram.get()); 203 FillHistogram(tentative_histogram.get());
232 204
233 // Register this histogram with the StatisticsRecorder. Keep a copy of 205 // Register this histogram with the StatisticsRecorder. Keep a copy of
234 // the pointer value to tell later whether the locally created histogram 206 // the pointer value to tell later whether the locally created histogram
235 // was registered or deleted. The type is "void" because it could point 207 // was registered or deleted. The type is "void" because it could point
236 // to released memory after the following line. 208 // to released memory after the following line.
237 const void* tentative_histogram_ptr = tentative_histogram.get(); 209 const void* tentative_histogram_ptr = tentative_histogram.get();
238 histogram = StatisticsRecorder::RegisterOrDeleteDuplicate( 210 histogram = StatisticsRecorder::RegisterOrDeleteDuplicate(
239 tentative_histogram.release()); 211 tentative_histogram.release());
240 212
241 // Persistent histograms need some follow-up processing. 213 // Persistent histograms need some follow-up processing.
242 if (histogram_ref != 0xDEADBEEF) { 214 if (histogram_ref) {
243 allocator->FinalizeHistogram(histogram_ref, 215 allocator->FinalizeHistogram(histogram_ref,
244 histogram == tentative_histogram_ptr); 216 histogram == tentative_histogram_ptr);
245 } 217 }
246 218
247 // Update report on created histograms. 219 // Update report on created histograms.
248 ReportHistogramActivity(*histogram, HISTOGRAM_CREATED); 220 ReportHistogramActivity(*histogram, HISTOGRAM_CREATED);
249 } else { 221 } else {
250 // Update report on lookup histograms. 222 // Update report on lookup histograms.
251 ReportHistogramActivity(*histogram, HISTOGRAM_LOOKUP); 223 ReportHistogramActivity(*histogram, HISTOGRAM_LOOKUP);
252 } 224 }
253 225
254 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()) << name_; 226 DCHECK_EQ(histogram_type_, histogram->GetHistogramType()) << name_;
255 bool bad_args = false;
256 HistogramBase* existing_histogram = histogram;
257 HistogramType existing_type = histogram->GetHistogramType();
258 const char* existing_name = histogram->histogram_name().c_str();
259 Sample existing_minimum = static_cast<Histogram*>(histogram)->declared_min_;
260 Sample existing_maximum = static_cast<Histogram*>(histogram)->declared_max_;
261 uint32_t existing_bucket_count =
262 static_cast<Histogram*>(histogram)->bucket_count();
263
264 if (bucket_count_ != 0 && 227 if (bucket_count_ != 0 &&
265 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) { 228 !histogram->HasConstructionArguments(minimum_, maximum_, bucket_count_)) {
266 // The construction arguments do not match the existing histogram. This can 229 // The construction arguments do not match the existing histogram. This can
267 // come about if an extension updates in the middle of a chrome run and has 230 // come about if an extension updates in the middle of a chrome run and has
268 // changed one of them, or simply by bad code within Chrome itself. We 231 // changed one of them, or simply by bad code within Chrome itself. We
269 // return NULL here with the expectation that bad code in Chrome will crash 232 // return NULL here with the expectation that bad code in Chrome will crash
270 // on dereference, but extension/Pepper APIs will guard against NULL and not 233 // on dereference, but extension/Pepper APIs will guard against NULL and not
271 // crash. 234 // crash.
272 DLOG(ERROR) << "Histogram " << name_ << " has bad construction arguments"; 235 DLOG(ERROR) << "Histogram " << name_ << " has bad construction arguments";
273 bad_args = true; 236 return nullptr;
274 histogram = nullptr;
275 } 237 }
276
277 #if !DCHECK_IS_ON() && defined(OS_WIN) // Affect only Windows release builds.
278 // For the moment, crash here so that collected crash reports have access
279 // to the construction values in order to figure out why this is failing.
280 // TODO(bcwhite): Remove this once crbug.com/588946 is resolved. Also remove
281 // from beta-branch because we don't want crashes due to misbehaving
282 // extensions (see comment above).
283 if (!histogram) {
284 HistogramType histogram_type = histogram_type_;
285 HistogramBase::Sample minimum = minimum_;
286 HistogramBase::Sample maximum = maximum_;
287 uint32_t bucket_count = bucket_count_;
288 int32_t flags = flags_;
289 CHECK(histogram) << name_ << ": bad-args=" << bad_args;
290 base::debug::Alias(&histogram_type);
291 base::debug::Alias(&minimum);
292 base::debug::Alias(&maximum);
293 base::debug::Alias(&bucket_count);
294 base::debug::Alias(&flags);
295 base::debug::Alias(&created_ranges);
296 base::debug::Alias(&registered_ranges);
297 base::debug::Alias(&histogram_ref);
298 base::debug::Alias(&tentative_histogram);
299 base::debug::Alias(&allocator);
300 base::debug::Alias(&tentative_histogram);
301 }
302 #endif
303
304 // Down here so vars are always "used".
305 base::debug::Alias(&bad_args);
306 base::debug::Alias(&existing_histogram);
307 base::debug::Alias(&existing_type);
308 base::debug::Alias(&existing_name);
309 base::debug::Alias(&existing_minimum);
310 base::debug::Alias(&existing_maximum);
311 base::debug::Alias(&existing_bucket_count);
312 return histogram; 238 return histogram;
313 } 239 }
314 240
315 HistogramBase* Histogram::FactoryGet(const std::string& name, 241 HistogramBase* Histogram::FactoryGet(const std::string& name,
316 Sample minimum, 242 Sample minimum,
317 Sample maximum, 243 Sample maximum,
318 uint32_t bucket_count, 244 uint32_t bucket_count,
319 int32_t flags) { 245 int32_t flags) {
320 bool valid_arguments = 246 bool valid_arguments =
321 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count); 247 InspectConstructionArguments(name, &minimum, &maximum, &bucket_count);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 } 490 }
565 491
566 Histogram::Histogram(const std::string& name, 492 Histogram::Histogram(const std::string& name,
567 Sample minimum, 493 Sample minimum,
568 Sample maximum, 494 Sample maximum,
569 const BucketRanges* ranges) 495 const BucketRanges* ranges)
570 : HistogramBase(name), 496 : HistogramBase(name),
571 bucket_ranges_(ranges), 497 bucket_ranges_(ranges),
572 declared_min_(minimum), 498 declared_min_(minimum),
573 declared_max_(maximum) { 499 declared_max_(maximum) {
574 CHECK_LT(0, minimum);
575 CHECK_LT(0, maximum);
576 if (ranges) 500 if (ranges)
577 samples_.reset(new SampleVector(HashMetricName(name), ranges)); 501 samples_.reset(new SampleVector(HashMetricName(name), ranges));
578 CHECK_EQ(minimum, declared_min_);
579 CHECK_EQ(maximum, declared_max_);
580 } 502 }
581 503
582 Histogram::Histogram(const std::string& name, 504 Histogram::Histogram(const std::string& name,
583 Sample minimum, 505 Sample minimum,
584 Sample maximum, 506 Sample maximum,
585 const BucketRanges* ranges, 507 const BucketRanges* ranges,
586 HistogramBase::AtomicCount* counts, 508 HistogramBase::AtomicCount* counts,
587 HistogramBase::AtomicCount* logged_counts, 509 HistogramBase::AtomicCount* logged_counts,
588 uint32_t counts_size, 510 uint32_t counts_size,
589 HistogramSamples::Metadata* meta, 511 HistogramSamples::Metadata* meta,
590 HistogramSamples::Metadata* logged_meta) 512 HistogramSamples::Metadata* logged_meta)
591 : HistogramBase(name), 513 : HistogramBase(name),
592 bucket_ranges_(ranges), 514 bucket_ranges_(ranges),
593 declared_min_(minimum), 515 declared_min_(minimum),
594 declared_max_(maximum) { 516 declared_max_(maximum) {
595 CHECK_LT(0, minimum);
596 CHECK_LT(0, maximum);
597 if (ranges) { 517 if (ranges) {
598 samples_.reset(new SampleVector(HashMetricName(name), 518 samples_.reset(new SampleVector(HashMetricName(name),
599 counts, counts_size, meta, ranges)); 519 counts, counts_size, meta, ranges));
600 logged_samples_.reset(new SampleVector(samples_->id(), logged_counts, 520 logged_samples_.reset(new SampleVector(samples_->id(), logged_counts,
601 counts_size, logged_meta, ranges)); 521 counts_size, logged_meta, ranges));
602 } 522 }
603 CHECK_EQ(minimum, declared_min_);
604 CHECK_EQ(maximum, declared_max_);
605 } 523 }
606 524
607 Histogram::~Histogram() { 525 Histogram::~Histogram() {
608 } 526 }
609 527
610 bool Histogram::PrintEmptyBucket(uint32_t index) const { 528 bool Histogram::PrintEmptyBucket(uint32_t index) const {
611 return true; 529 return true;
612 } 530 }
613 531
614 // Use the actual bucket widths (like a linear histogram) until the widths get 532 // Use the actual bucket widths (like a linear histogram) until the widths get
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 Sample sample = custom_ranges[i]; 1168 Sample sample = custom_ranges[i];
1251 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1) 1169 if (sample < 0 || sample > HistogramBase::kSampleType_MAX - 1)
1252 return false; 1170 return false;
1253 if (sample != 0) 1171 if (sample != 0)
1254 has_valid_range = true; 1172 has_valid_range = true;
1255 } 1173 }
1256 return has_valid_range; 1174 return has_valid_range;
1257 } 1175 }
1258 1176
1259 } // namespace base 1177 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | base/metrics/histogram_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698