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

Side by Side Diff: components/metrics/leak_detector/leak_detector_impl.cc

Issue 1892283004: Add cooldown to LeakDetectorImpl leak report generation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased; remove JuliaSet history comparison Created 4 years, 8 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "leak_detector_impl.h" 5 #include "leak_detector_impl.h"
6 6
7 #include <inttypes.h> 7 #include <inttypes.h>
8 #include <stddef.h> 8 #include <stddef.h>
9 9
10 #include <algorithm> // For std::move 10 #include <algorithm> // For std::move
11 #include <iterator> // For std::advance 11 #include <iterator> // For std::advance
12 #include <new> 12 #include <new>
13 #include <utility>
13 14
14 #include "base/hash.h" 15 #include "base/hash.h"
15 #include "base/process/process_handle.h" 16 #include "base/process/process_handle.h"
16 #include "components/metrics/leak_detector/call_stack_table.h" 17 #include "components/metrics/leak_detector/call_stack_table.h"
17 #include "components/metrics/leak_detector/custom_allocator.h" 18 #include "components/metrics/leak_detector/custom_allocator.h"
18 #include "components/metrics/leak_detector/ranked_set.h" 19 #include "components/metrics/leak_detector/ranked_set.h"
19 20
20 namespace metrics { 21 namespace metrics {
21 namespace leak_detector { 22 namespace leak_detector {
22 23
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 RankedSet size_ranked_set(kRankedSetSize); 178 RankedSet size_ranked_set(kRankedSetSize);
178 for (size_t i = 0; i < size_entries_.size(); ++i) { 179 for (size_t i = 0; i < size_entries_.size(); ++i) {
179 const AllocSizeEntry& entry = size_entries_[i]; 180 const AllocSizeEntry& entry = size_entries_[i];
180 ValueType size_value(IndexToSize(i)); 181 ValueType size_value(IndexToSize(i));
181 size_ranked_set.Add(size_value, entry.GetNetAllocs()); 182 size_ranked_set.Add(size_value, entry.GetNetAllocs());
182 } 183 }
183 size_leak_analyzer_.AddSample(std::move(size_ranked_set)); 184 size_leak_analyzer_.AddSample(std::move(size_ranked_set));
184 185
185 RecordCurrentAllocationDataInHistory(); 186 RecordCurrentAllocationDataInHistory();
186 187
188 UpdateLeakCooldowns();
189
187 // Get suspected leaks by size. 190 // Get suspected leaks by size.
188 for (const ValueType& size_value : size_leak_analyzer_.suspected_leaks()) { 191 for (const ValueType& size_value : size_leak_analyzer_.suspected_leaks()) {
189 uint32_t size = size_value.size(); 192 uint32_t size = size_value.size();
190 AllocSizeEntry* entry = &size_entries_[SizeToIndex(size)]; 193 AllocSizeEntry* entry = &size_entries_[SizeToIndex(size)];
191 if (entry->stack_table) 194 if (entry->stack_table)
192 continue; 195 continue;
193 entry->stack_table = new (CustomAllocator::Allocate(sizeof(CallStackTable))) 196 entry->stack_table = new (CustomAllocator::Allocate(sizeof(CallStackTable)))
194 CallStackTable(call_stack_suspicion_threshold_); 197 CallStackTable(call_stack_suspicion_threshold_);
195 ++num_stack_tables_; 198 ++num_stack_tables_;
196 } 199 }
(...skipping 11 matching lines...) Expand all
208 continue; 211 continue;
209 212
210 size_t size = IndexToSize(i); 213 size_t size = IndexToSize(i);
211 214
212 // Get suspected leaks by call stack. 215 // Get suspected leaks by call stack.
213 stack_table->TestForLeaks(); 216 stack_table->TestForLeaks();
214 const LeakAnalyzer& leak_analyzer = stack_table->leak_analyzer(); 217 const LeakAnalyzer& leak_analyzer = stack_table->leak_analyzer();
215 for (const ValueType& call_stack_value : leak_analyzer.suspected_leaks()) { 218 for (const ValueType& call_stack_value : leak_analyzer.suspected_leaks()) {
216 const CallStack* call_stack = call_stack_value.call_stack(); 219 const CallStack* call_stack = call_stack_value.call_stack();
217 220
221 if (!ReadyToGenerateReport(size, call_stack))
222 continue;
223
218 // Return reports by storing in |*reports|. 224 // Return reports by storing in |*reports|.
219 reports->resize(reports->size() + 1); 225 reports->resize(reports->size() + 1);
220 LeakReport* report = &reports->back(); 226 LeakReport* report = &reports->back();
221 report->alloc_size_bytes_ = size; 227 report->alloc_size_bytes_ = size;
222 report->call_stack_.resize(call_stack->depth); 228 report->call_stack_.resize(call_stack->depth);
223 for (size_t j = 0; j < call_stack->depth; ++j) { 229 for (size_t j = 0; j < call_stack->depth; ++j) {
224 report->call_stack_[j] = GetOffset(call_stack->stack[j]); 230 report->call_stack_[j] = GetOffset(call_stack->stack[j]);
225 } 231 }
226 232
227 StoreHistoricalDataInReport(size, call_stack, report); 233 StoreHistoricalDataInReport(size, call_stack, report);
234 ResetLeakCooldown(size, call_stack);
228 } 235 }
229 } 236 }
230 } 237 }
231 238
232 LeakDetectorImpl::AllocSizeEntry::AllocSizeEntry() : num_allocs(0), 239 LeakDetectorImpl::AllocSizeEntry::AllocSizeEntry() : num_allocs(0),
233 num_frees(0), 240 num_frees(0),
234 stack_table(nullptr) {} 241 stack_table(nullptr) {}
235 242
236 LeakDetectorImpl::AllocSizeEntry::~AllocSizeEntry() {} 243 LeakDetectorImpl::AllocSizeEntry::~AllocSizeEntry() {}
237 244
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 while (src_iter != src.end() && dest_iter != dest->end()) { 312 while (src_iter != src.end() && dest_iter != dest->end()) {
306 const RankedSet& ranked_call_sites = *src_iter; 313 const RankedSet& ranked_call_sites = *src_iter;
307 auto find_call_site_iter = ranked_call_sites.FindCallStack(call_site); 314 auto find_call_site_iter = ranked_call_sites.FindCallStack(call_site);
308 if (find_call_site_iter != ranked_call_sites.end()) 315 if (find_call_site_iter != ranked_call_sites.end())
309 dest_iter->count_for_call_stack = find_call_site_iter->count; 316 dest_iter->count_for_call_stack = find_call_site_iter->count;
310 ++src_iter; 317 ++src_iter;
311 ++dest_iter; 318 ++dest_iter;
312 } 319 }
313 } 320 }
314 321
322 bool LeakDetectorImpl::ReadyToGenerateReport(
323 size_t size,
324 const CallStack* call_stack) const {
325 return cooldowns_per_leak_.find(std::make_pair(size, call_stack)) ==
326 cooldowns_per_leak_.end();
327 }
328
329 void LeakDetectorImpl::ResetLeakCooldown(size_t size,
330 const CallStack* call_stack) {
331 cooldowns_per_leak_[std::make_pair(size, call_stack)] =
332 kNumSizeEntriesInHistory;
333 }
334
335 void LeakDetectorImpl::UpdateLeakCooldowns() {
336 for (auto iter = cooldowns_per_leak_.begin();
337 iter != cooldowns_per_leak_.end();
338 /* No iterating here */) {
339 if (--iter->second > 0) {
340 ++iter;
341 } else {
342 cooldowns_per_leak_.erase(iter++);
343 }
344 }
345 }
346
315 } // namespace leak_detector 347 } // namespace leak_detector
316 } // namespace metrics 348 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698