Skip to content

Commit c570ca3

Browse files
asvitkine-chromiumchromeos-ci-prod
authored andcommitted
Make non-matching histograms between parent and child process dump.
This follows up https://chromium-review.googlesource.com/5866873, which updated the notreached logic around non-matching buckets. Bug: 367379194 Change-Id: I383154cf5a62e68a4d382cb3fa0ccc063762ae26 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5891286 Commit-Queue: Alexei Svitkine <[email protected]> Reviewed-by: Luc Nguyen <[email protected]> Cr-Commit-Position: refs/heads/main@{#1363290} CrOS-Libchrome-Original-Commit: 1e86b0c896af21d2a2aee2545513c2af23e0b980
1 parent f39b4a3 commit c570ca3

11 files changed

+56
-67
lines changed

base/metrics/dummy_histogram.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ bool DummyHistogram::HasConstructionArguments(
8585
return true;
8686
}
8787

88+
bool DummyHistogram::AddSamples(const HistogramSamples& samples) {
89+
return true;
90+
}
91+
8892
bool DummyHistogram::AddSamplesFromPickle(PickleIterator* iter) {
8993
return true;
9094
}

base/metrics/dummy_histogram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class BASE_EXPORT DummyHistogram : public HistogramBase {
3636
size_t expected_bucket_count) const override;
3737
void Add(Sample value) override {}
3838
void AddCount(Sample value, int count) override {}
39-
void AddSamples(const HistogramSamples& samples) override {}
39+
bool AddSamples(const HistogramSamples& samples) override;
4040
bool AddSamplesFromPickle(PickleIterator* iter) override;
4141
std::unique_ptr<HistogramSamples> SnapshotSamples() const override;
4242
std::unique_ptr<HistogramSamples> SnapshotUnloggedSamples() const override;

base/metrics/histogram.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,8 @@ std::unique_ptr<HistogramSamples> Histogram::SnapshotFinalDelta() const {
589589
return SnapshotUnloggedSamples();
590590
}
591591

592-
void Histogram::AddSamples(const HistogramSamples& samples) {
593-
unlogged_samples_->Add(samples);
592+
bool Histogram::AddSamples(const HistogramSamples& samples) {
593+
return unlogged_samples_->Add(samples);
594594
}
595595

596596
bool Histogram::AddSamplesFromPickle(PickleIterator* iter) {

base/metrics/histogram.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class BASE_EXPORT Histogram : public HistogramBase {
236236
void MarkSamplesAsLogged(const HistogramSamples& samples) final;
237237
std::unique_ptr<HistogramSamples> SnapshotDelta() override;
238238
std::unique_ptr<HistogramSamples> SnapshotFinalDelta() const override;
239-
void AddSamples(const HistogramSamples& samples) override;
239+
bool AddSamples(const HistogramSamples& samples) override;
240240
bool AddSamplesFromPickle(base::PickleIterator* iter) override;
241241
base::Value::Dict ToGraphDict() const override;
242242

base/metrics/histogram_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class BASE_EXPORT HistogramBase {
202202
void AddTimeMicrosecondsGranularity(const TimeDelta& time);
203203
void AddBoolean(bool value);
204204

205-
virtual void AddSamples(const HistogramSamples& samples) = 0;
205+
virtual bool AddSamples(const HistogramSamples& samples) = 0;
206206
virtual bool AddSamplesFromPickle(base::PickleIterator* iter) = 0;
207207

208208
// Serialize the histogram info into |pickle|.

base/metrics/histogram_samples.cc

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,10 @@ HistogramSamples::HistogramSamples(uint64_t id, std::unique_ptr<Metadata> meta)
237237
// be invalid by the time this dtor gets called.
238238
HistogramSamples::~HistogramSamples() = default;
239239

240-
void HistogramSamples::Add(const HistogramSamples& other) {
240+
bool HistogramSamples::Add(const HistogramSamples& other) {
241241
IncreaseSumAndCount(other.sum(), other.redundant_count());
242242
std::unique_ptr<SampleCountIterator> it = other.Iterator();
243-
bool success = AddSubtractImpl(it.get(), ADD);
244-
DCHECK(success);
243+
return AddSubtractImpl(it.get(), ADD);
245244
}
246245

247246
bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
@@ -257,14 +256,13 @@ bool HistogramSamples::AddFromPickle(PickleIterator* iter) {
257256
return AddSubtractImpl(&pickle_iter, ADD);
258257
}
259258

260-
void HistogramSamples::Subtract(const HistogramSamples& other) {
259+
bool HistogramSamples::Subtract(const HistogramSamples& other) {
261260
IncreaseSumAndCount(-other.sum(), -other.redundant_count());
262261
std::unique_ptr<SampleCountIterator> it = other.Iterator();
263-
bool success = AddSubtractImpl(it.get(), SUBTRACT);
264-
DCHECK(success);
262+
return AddSubtractImpl(it.get(), SUBTRACT);
265263
}
266264

267-
void HistogramSamples::Extract(HistogramSamples& other) {
265+
bool HistogramSamples::Extract(HistogramSamples& other) {
268266
static_assert(sizeof(other.meta_->sum) == 8);
269267

270268
#ifdef ARCH_CPU_64_BITS
@@ -294,8 +292,7 @@ void HistogramSamples::Extract(HistogramSamples& other) {
294292
subtle::NoBarrier_AtomicExchange(&other.meta_->redundant_count, 0);
295293
IncreaseSumAndCount(other_sum, other_redundant_count);
296294
std::unique_ptr<SampleCountIterator> it = other.ExtractingIterator();
297-
bool success = AddSubtractImpl(it.get(), ADD);
298-
DCHECK(success);
295+
return AddSubtractImpl(it.get(), ADD);
299296
}
300297

301298
bool HistogramSamples::IsDefinitelyEmpty() const {

base/metrics/histogram_samples.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,16 +147,16 @@ class BASE_EXPORT HistogramSamples {
147147
virtual HistogramBase::Count GetCount(HistogramBase::Sample value) const = 0;
148148
virtual HistogramBase::Count TotalCount() const = 0;
149149

150-
void Add(const HistogramSamples& other);
150+
bool Add(const HistogramSamples& other);
151151

152152
// Add from serialized samples.
153153
bool AddFromPickle(PickleIterator* iter);
154154

155-
void Subtract(const HistogramSamples& other);
155+
bool Subtract(const HistogramSamples& other);
156156

157157
// Adds the samples from |other| while also resetting |other|'s sample counts
158158
// to 0.
159-
void Extract(HistogramSamples& other);
159+
bool Extract(HistogramSamples& other);
160160

161161
// Returns an iterator to read the sample counts.
162162
virtual std::unique_ptr<SampleCountIterator> Iterator() const = 0;

base/metrics/persistent_histogram_allocator.cc

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -104,60 +104,41 @@ size_t CalculateRequiredCountsBytes(size_t bucket_count) {
104104
return bucket_count * kBytesPerBucket;
105105
}
106106

107-
void MergeSamplesToExistingHistogram(
107+
bool MergeSamplesToExistingHistogram(
108108
HistogramBase* existing,
109109
const HistogramBase* histogram,
110110
std::unique_ptr<HistogramSamples> samples) {
111-
#if !BUILDFLAG(IS_NACL)
112-
// If the passed |histogram| does not match with |existing| (i.e. the one
113-
// registered with the global StatisticsRecorder) due to not being the same
114-
// type of histogram or due to specifying different buckets, then unexpected
115-
// things may happen further down the line. This may be indicative that a
116-
// child process is emitting a histogram with different parameters than the
117-
// browser process, for example.
118-
// TODO(crbug.com/40064026): Remove this. Used to investigate failures when
119-
// merging histograms from an allocator to the global StatisticsRecorder.
120-
bool histograms_match = true;
111+
// Check if the histograms match, which is necessary for merging their data.
121112
HistogramType existing_type = existing->GetHistogramType();
122113
if (histogram->GetHistogramType() != existing_type) {
123-
// Different histogram types.
124-
histograms_match = false;
125-
} else if (existing_type == HistogramType::HISTOGRAM ||
126-
existing_type == HistogramType::LINEAR_HISTOGRAM ||
127-
existing_type == HistogramType::BOOLEAN_HISTOGRAM ||
128-
existing_type == HistogramType::CUSTOM_HISTOGRAM) {
114+
return false; // Merge failed due to different histogram types.
115+
}
116+
117+
if (existing_type == HistogramType::HISTOGRAM ||
118+
existing_type == HistogramType::LINEAR_HISTOGRAM ||
119+
existing_type == HistogramType::BOOLEAN_HISTOGRAM ||
120+
existing_type == HistogramType::CUSTOM_HISTOGRAM) {
129121
// Only numeric histograms make use of BucketRanges.
130122
const BucketRanges* existing_buckets =
131123
static_cast<const Histogram*>(existing)->bucket_ranges();
132124
const BucketRanges* histogram_buckets =
133125
static_cast<const Histogram*>(histogram)->bucket_ranges();
134126
// DCHECK because HasValidChecksum() recomputes the checksum which can be
135127
// expensive to do in a loop.
136-
DCHECK(existing_buckets->HasValidChecksum() &&
137-
histogram_buckets->HasValidChecksum());
128+
DCHECK(existing_buckets->HasValidChecksum());
129+
DCHECK(histogram_buckets->HasValidChecksum());
138130

139131
if (existing_buckets->checksum() != histogram_buckets->checksum()) {
140-
// Different buckets.
141-
histograms_match = false;
132+
return false; // Merge failed due to different buckets.
142133
}
143134
}
144135

145-
if (!histograms_match) {
146-
// If the histograms do not match, then the call to AddSamples() below might
147-
// trigger a NOTREACHED(). Include the histogram name here for
148-
// debugging purposes. This is not done in
149-
// GetOrCreateStatisticsRecorderHistogram() directly, since that could
150-
// incorrectly create crash reports for enum histograms that have newly
151-
// appended entries (different bucket max and count).
152-
SCOPED_CRASH_KEY_STRING256("PersistentHistogramAllocator", "histogram",
153-
existing->histogram_name());
154-
existing->AddSamples(*samples);
155-
return;
156-
}
157-
#endif // !BUILDFLAG(IS_NACL)
158-
159136
// Merge the delta from the passed object to the one in the SR.
160-
existing->AddSamples(*samples);
137+
138+
// It's possible for the buckets to differ but their checksums to match due
139+
// to a collision, in which case AddSamples() will return false, which we
140+
// propagate to the caller (indicating histogram mismatch).
141+
return existing->AddSamples(*samples);
161142
}
162143

163144
} // namespace
@@ -504,7 +485,7 @@ void PersistentHistogramAllocator::FinalizeHistogram(Reference ref,
504485
}
505486
}
506487

507-
void PersistentHistogramAllocator::MergeHistogramDeltaToStatisticsRecorder(
488+
bool PersistentHistogramAllocator::MergeHistogramDeltaToStatisticsRecorder(
508489
HistogramBase* histogram) {
509490
DCHECK(histogram);
510491

@@ -513,20 +494,21 @@ void PersistentHistogramAllocator::MergeHistogramDeltaToStatisticsRecorder(
513494
// the StatisticsRecorder, which requires acquiring a lock.
514495
std::unique_ptr<HistogramSamples> samples = histogram->SnapshotDelta();
515496
if (samples->IsDefinitelyEmpty()) {
516-
return;
497+
return true;
517498
}
518499

519500
HistogramBase* existing = GetOrCreateStatisticsRecorderHistogram(histogram);
520501
if (!existing) {
521502
// The above should never fail but if it does, no real harm is done.
522503
// Some metric data will be lost but that is better than crashing.
523-
return;
504+
return false;
524505
}
525506

526-
MergeSamplesToExistingHistogram(existing, histogram, std::move(samples));
507+
return MergeSamplesToExistingHistogram(existing, histogram,
508+
std::move(samples));
527509
}
528510

529-
void PersistentHistogramAllocator::MergeHistogramFinalDeltaToStatisticsRecorder(
511+
bool PersistentHistogramAllocator::MergeHistogramFinalDeltaToStatisticsRecorder(
530512
const HistogramBase* histogram) {
531513
DCHECK(histogram);
532514

@@ -535,17 +517,18 @@ void PersistentHistogramAllocator::MergeHistogramFinalDeltaToStatisticsRecorder(
535517
// requires acquiring a lock.
536518
std::unique_ptr<HistogramSamples> samples = histogram->SnapshotFinalDelta();
537519
if (samples->IsDefinitelyEmpty()) {
538-
return;
520+
return true;
539521
}
540522

541523
HistogramBase* existing = GetOrCreateStatisticsRecorderHistogram(histogram);
542524
if (!existing) {
543525
// The above should never fail but if it does, no real harm is done.
544526
// Some metric data will be lost but that is better than crashing.
545-
return;
527+
return false;
546528
}
547529

548-
MergeSamplesToExistingHistogram(existing, histogram, std::move(samples));
530+
return MergeSamplesToExistingHistogram(existing, histogram,
531+
std::move(samples));
549532
}
550533

551534
std::unique_ptr<PersistentSampleMapRecords>

base/metrics/persistent_histogram_allocator.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,13 +264,18 @@ class BASE_EXPORT PersistentHistogramAllocator {
264264
// StatisticsRecorder, updating the "logged" samples within the passed
265265
// object so that repeated merges are allowed. Don't call this on a "global"
266266
// allocator because histograms created there will already be in the SR.
267-
void MergeHistogramDeltaToStatisticsRecorder(HistogramBase* histogram);
267+
// Returns whether the merge was successful; if false, the histogram did not
268+
// have the same shape (different types or buckets), or we couldn't get a
269+
// target histogram from the statistic recorder.
270+
bool MergeHistogramDeltaToStatisticsRecorder(HistogramBase* histogram);
268271

269272
// As above but merge the "final" delta. No update of "logged" samples is
270273
// done which means it can operate on read-only objects. It's essential,
271274
// however, not to call this more than once or those final samples will
272-
// get recorded again.
273-
void MergeHistogramFinalDeltaToStatisticsRecorder(
275+
// get recorded again. Returns whether the merge was successful; if false, the
276+
// histogram did not have the same shape (different types or buckets), or we
277+
// couldn't get a target histogram from the statistic recorder.
278+
bool MergeHistogramFinalDeltaToStatisticsRecorder(
274279
const HistogramBase* histogram);
275280

276281
// Returns an object that manages persistent-sample-map records for a given

base/metrics/sparse_histogram.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ std::unique_ptr<HistogramSamples> SparseHistogram::SnapshotFinalDelta() const {
181181
return std::move(snapshot);
182182
}
183183

184-
void SparseHistogram::AddSamples(const HistogramSamples& samples) {
184+
bool SparseHistogram::AddSamples(const HistogramSamples& samples) {
185185
base::AutoLock auto_lock(lock_);
186-
unlogged_samples_->Add(samples);
186+
return unlogged_samples_->Add(samples);
187187
}
188188

189189
bool SparseHistogram::AddSamplesFromPickle(PickleIterator* iter) {

0 commit comments

Comments
 (0)