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

Side by Side 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, 2 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 | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #include "base/metrics/persistent_histogram_allocator.h" 5 #include "base/metrics/persistent_histogram_allocator.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
(...skipping 20 matching lines...) Expand all
31 31
32 // Type identifiers used when storing in persistent memory so they can be 32 // Type identifiers used when storing in persistent memory so they can be
33 // identified during extraction; the first 4 bytes of the SHA1 of the name 33 // identified during extraction; the first 4 bytes of the SHA1 of the name
34 // is used as a unique integer. A "version number" is added to the base 34 // is used as a unique integer. A "version number" is added to the base
35 // so that, if the structure of that object changes, stored older versions 35 // so that, if the structure of that object changes, stored older versions
36 // will be safely ignored. 36 // will be safely ignored.
37 enum : uint32_t { 37 enum : uint32_t {
38 kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2 38 kTypeIdHistogram = 0xF1645910 + 2, // SHA1(Histogram) v2
39 kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1 39 kTypeIdRangesArray = 0xBCEA225A + 1, // SHA1(RangesArray) v1
40 kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1 40 kTypeIdCountsArray = 0x53215530 + 1, // SHA1(CountsArray) v1
41
42 kTypeIdHistogramUnderConstruction = ~kTypeIdHistogram,
41 }; 43 };
42 44
43 // The current globally-active persistent allocator for all new histograms. 45 // The current globally-active persistent allocator for all new histograms.
44 // The object held here will obviously not be destructed at process exit 46 // The object held here will obviously not be destructed at process exit
45 // but that's best since PersistentMemoryAllocator objects (that underlie 47 // but that's best since PersistentMemoryAllocator objects (that underlie
46 // GlobalHistogramAllocator objects) are explicitly forbidden from doing 48 // GlobalHistogramAllocator objects) are explicitly forbidden from doing
47 // anything essential at exit anyway due to the fact that they depend on data 49 // anything essential at exit anyway due to the fact that they depend on data
48 // managed elsewhere and which could be destructed first. 50 // managed elsewhere and which could be destructed first.
49 GlobalHistogramAllocator* g_allocator = nullptr; 51 GlobalHistogramAllocator* g_allocator = nullptr;
50 52
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 Reference ref) { 269 Reference ref) {
268 // Unfortunately, the histogram "pickle" methods cannot be used as part of 270 // Unfortunately, the histogram "pickle" methods cannot be used as part of
269 // the persistance because the deserialization methods always create local 271 // the persistance because the deserialization methods always create local
270 // count data (while these must reference the persistent counts) and always 272 // count data (while these must reference the persistent counts) and always
271 // add it to the local list of known histograms (while these may be simple 273 // add it to the local list of known histograms (while these may be simple
272 // references to histograms in other processes). 274 // references to histograms in other processes).
273 PersistentHistogramData* histogram_data = 275 PersistentHistogramData* histogram_data =
274 memory_allocator_->GetAsObject<PersistentHistogramData>( 276 memory_allocator_->GetAsObject<PersistentHistogramData>(
275 ref, kTypeIdHistogram); 277 ref, kTypeIdHistogram);
276 size_t length = memory_allocator_->GetAllocSize(ref); 278 size_t length = memory_allocator_->GetAllocSize(ref);
279
280 // Check that metadata is reasonable: name is NUL terminated and non-empty,
281 // ID fields have been loaded with a hash of the name (0 is considered
282 // unset/invalid).
277 if (!histogram_data || 283 if (!histogram_data ||
278 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0') { 284 reinterpret_cast<char*>(histogram_data)[length - 1] != '\0' ||
285 histogram_data->name[0] == '\0' ||
286 histogram_data->samples_metadata.id == 0 ||
287 histogram_data->logged_metadata.id == 0) {
279 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA); 288 RecordCreateHistogramResult(CREATE_HISTOGRAM_INVALID_METADATA);
280 NOTREACHED(); 289 NOTREACHED();
281 return nullptr; 290 return nullptr;
282 } 291 }
283 return CreateHistogram(histogram_data); 292 return CreateHistogram(histogram_data);
284 } 293 }
285 294
286 std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram( 295 std::unique_ptr<HistogramBase> PersistentHistogramAllocator::AllocateHistogram(
287 HistogramType histogram_type, 296 HistogramType histogram_type,
288 const std::string& name, 297 const std::string& name,
289 int minimum, 298 int minimum,
290 int maximum, 299 int maximum,
291 const BucketRanges* bucket_ranges, 300 const BucketRanges* bucket_ranges,
292 int32_t flags, 301 int32_t flags,
293 Reference* ref_ptr) { 302 Reference* ref_ptr) {
294 // If the allocator is corrupt, don't waste time trying anything else. 303 // If the allocator is corrupt, don't waste time trying anything else.
295 // This also allows differentiating on the dashboard between allocations 304 // This also allows differentiating on the dashboard between allocations
296 // failed due to a corrupt allocator and the number of process instances 305 // failed due to a corrupt allocator and the number of process instances
297 // with one, the latter being idicated by "newly corrupt", below. 306 // with one, the latter being idicated by "newly corrupt", below.
298 if (memory_allocator_->IsCorrupt()) { 307 if (memory_allocator_->IsCorrupt()) {
299 RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_CORRUPT); 308 RecordCreateHistogramResult(CREATE_HISTOGRAM_ALLOCATOR_CORRUPT);
300 return nullptr; 309 return nullptr;
301 } 310 }
302 311
303 // Create the metadata necessary for a persistent sparse histogram. This 312 // Create the metadata necessary for a persistent sparse histogram. This
304 // is done first because it is a small subset of what is required for 313 // is done first because it is a small subset of what is required for
305 // other histograms. 314 // other histograms. The type is "under construction" so that a crash
315 // during the datafill doesn't leave a bad record around that could cause
316 // confusion by another process trying to read it. It will be corrected
317 // once histogram construction is complete.
306 PersistentMemoryAllocator::Reference histogram_ref = 318 PersistentMemoryAllocator::Reference histogram_ref =
307 memory_allocator_->Allocate( 319 memory_allocator_->Allocate(
308 offsetof(PersistentHistogramData, name) + name.length() + 1, 320 offsetof(PersistentHistogramData, name) + name.length() + 1,
309 kTypeIdHistogram); 321 kTypeIdHistogramUnderConstruction);
310 PersistentHistogramData* histogram_data = 322 PersistentHistogramData* histogram_data =
311 memory_allocator_->GetAsObject<PersistentHistogramData>(histogram_ref, 323 memory_allocator_->GetAsObject<PersistentHistogramData>(
312 kTypeIdHistogram); 324 histogram_ref, kTypeIdHistogramUnderConstruction);
313 if (histogram_data) { 325 if (histogram_data) {
314 memcpy(histogram_data->name, name.c_str(), name.size() + 1); 326 memcpy(histogram_data->name, name.c_str(), name.size() + 1);
315 histogram_data->histogram_type = histogram_type; 327 histogram_data->histogram_type = histogram_type;
316 histogram_data->flags = flags | HistogramBase::kIsPersistent; 328 histogram_data->flags = flags | HistogramBase::kIsPersistent;
317 } 329 }
318 330
319 // Create the remaining metadata necessary for regular histograms. 331 // Create the remaining metadata necessary for regular histograms.
320 if (histogram_type != SPARSE_HISTOGRAM) { 332 if (histogram_type != SPARSE_HISTOGRAM) {
321 size_t bucket_count = bucket_ranges->bucket_count(); 333 size_t bucket_count = bucket_ranges->bucket_count();
322 size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count); 334 size_t counts_bytes = CalculateRequiredCountsBytes(bucket_count);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 } 370 }
359 371
360 if (histogram_data) { 372 if (histogram_data) {
361 // Create the histogram using resources in persistent memory. This ends up 373 // Create the histogram using resources in persistent memory. This ends up
362 // resolving the "ref" values stored in histogram_data instad of just 374 // resolving the "ref" values stored in histogram_data instad of just
363 // using what is already known above but avoids duplicating the switch 375 // using what is already known above but avoids duplicating the switch
364 // statement here and serves as a double-check that everything is 376 // statement here and serves as a double-check that everything is
365 // correct before commiting the new histogram to persistent space. 377 // correct before commiting the new histogram to persistent space.
366 std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data); 378 std::unique_ptr<HistogramBase> histogram = CreateHistogram(histogram_data);
367 DCHECK(histogram); 379 DCHECK(histogram);
380 DCHECK_NE(0U, histogram_data->samples_metadata.id);
381 DCHECK_NE(0U, histogram_data->logged_metadata.id);
382 memory_allocator_->ChangeType(histogram_ref, kTypeIdHistogram,
383 kTypeIdHistogramUnderConstruction);
384
368 if (ref_ptr != nullptr) 385 if (ref_ptr != nullptr)
369 *ref_ptr = histogram_ref; 386 *ref_ptr = histogram_ref;
370 387
371 // By storing the reference within the allocator to this histogram, the 388 // By storing the reference within the allocator to this histogram, the
372 // next import (which will happen before the next histogram creation) 389 // next import (which will happen before the next histogram creation)
373 // will know to skip it. 390 // will know to skip it.
374 // See also the comment in ImportHistogramsToStatisticsRecorder(). 391 // See also the comment in ImportHistogramsToStatisticsRecorder().
375 subtle::NoBarrier_Store(&last_created_, histogram_ref); 392 subtle::NoBarrier_Store(&last_created_, histogram_ref);
376 return histogram; 393 return histogram;
377 } 394 }
(...skipping 536 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 while (true) { 931 while (true) {
915 std::unique_ptr<HistogramBase> histogram = 932 std::unique_ptr<HistogramBase> histogram =
916 import_iterator_.GetNextWithIgnore(record_to_ignore); 933 import_iterator_.GetNextWithIgnore(record_to_ignore);
917 if (!histogram) 934 if (!histogram)
918 break; 935 break;
919 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release()); 936 StatisticsRecorder::RegisterOrDeleteDuplicate(histogram.release());
920 } 937 }
921 } 938 }
922 939
923 } // namespace base 940 } // namespace base
OLDNEW
« 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