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

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

Issue 986503002: components/metrics: Add runtime memory leak detector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix portability issues for sizes and addresses Created 5 years, 4 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "components/metrics/leak_detector/call_stack_table.h"
6
7 namespace leak_detector {
8
9 namespace {
10
11 using ValueType = LeakDetectorValueType;
12
13 // Get the top |kRankedListSize| entries.
14 const int kRankedListSize = 16;
15
16 // Initial number of hash table buckets.
17 const int kInitialHashTableSize = 1999;
18
19 // Used for printing call stacks in LeakAnalyzer.
20 class StringPrint : public LeakAnalyzer::StringPrint {
21 public:
22 // Gets the string representation of a value.
23 virtual const char* ValueToString(const ValueType& value, bool spacing_on) {
24 const CallStack* call_stack = value.call_stack();
25 snprintf(buffer_, sizeof(buffer_), spacing_on ? "%16p" : "%p", call_stack);
26 return buffer_;
27 }
28
29 // Gets the word that describes the value type.
30 virtual const char* ValueTypeName(bool is_plural) {
31 return is_plural ? "call stacks" : "call stack";
32 }
33 } string_print;
34
35 } // namespace
36
37 long CallStackTable::Hash::operator() (const CallStack* call_stack) const {
38 // The call stack object should already have a hash computed when it was
39 // created.
40 return call_stack->hash;
jar (doing other things) 2015/08/15 03:29:01 Does this give a warning as a hash of type uint64_
Simon Que 2015/08/15 23:28:30 No, but this should all be size_t, according to th
41 }
42
43 CallStackTable::CallStackTable(int call_stack_suspicion_threshold)
44 : num_allocs_(0),
45 num_frees_(0),
46 entry_map_(kInitialHashTableSize),
47 leak_analyzer_(kRankedListSize, call_stack_suspicion_threshold,
48 &string_print) {
49 }
50
51 CallStackTable::~CallStackTable() {}
52
53 void CallStackTable::Add(const CallStack* call_stack) {
54 auto iter = entry_map_.find(call_stack);
55 Entry* entry = nullptr;
56 if (iter == entry_map_.end()) {
57 entry = &entry_map_[call_stack];
58 } else {
59 entry = &iter->second;
60 }
61
62 ++entry->num_allocs;
63 ++num_allocs_;
64 }
65
66 void CallStackTable::Remove(const CallStack* call_stack) {
67 auto iter = entry_map_.find(call_stack);
68 if (iter == entry_map_.end())
jar (doing other things) 2015/08/15 03:29:01 Is this an internal error, or a regular occurrence
Simon Que 2015/08/15 23:28:30 This should not happen unless there was an error e
69 return;
70 Entry* entry = &iter->second;
71 ++entry->num_frees;
72 ++num_frees_;
73
74 // If there are no net allocs, delete the entry.
75 if (entry->num_allocs == entry->num_frees)
76 entry_map_.erase(iter);
77 }
78
79 int CallStackTable::Dump(char* buffer, const int buffer_size) const {
80 int size_left = buffer_size;
81
82 if (entry_map_.empty())
83 return size_left;
84
85 int attempted_size =
86 snprintf(buffer, size_left,
87 "Total number of allocations: %u\n"
88 "Total number of frees: %u\n"
89 "Net number of allocations: %u\n"
90 "Total number of distinct stack traces: %zu\n",
91 num_allocs_, num_frees_, num_allocs_ - num_frees_,
92 entry_map_.size());
93 size_left -= attempted_size;
94 buffer += attempted_size;
95
96 if (size_left > 0) {
jar (doing other things) 2015/08/15 03:29:01 Please correct this throughout this CL. This shou
Simon Que 2015/08/15 23:28:30 Done.
97 int attempted_size = leak_analyzer_.Dump(buffer, size_left);
98 size_left -= attempted_size;
99 buffer += attempted_size;
100 }
101
102 if (size_left > 0)
jar (doing other things) 2015/08/15 03:29:01 This is always true.
Simon Que 2015/08/15 23:28:30 Done.
103 return buffer_size - size_left;
104
105 return buffer_size;
106 }
107
108 void CallStackTable::TestForLeaks() {
109 // Add all entries to the ranked list.
110 RankedList ranked_list(kRankedListSize);
111
112 for (const auto& entry_pair : entry_map_) {
113 const Entry& entry = entry_pair.second;
114 if (entry.num_allocs != entry.num_frees) {
115 LeakDetectorValueType call_stack_value(entry_pair.first);
116 ranked_list.Add(call_stack_value, entry.num_allocs - entry.num_frees);
117 }
118 }
119 leak_analyzer_.AddSample(ranked_list);
120 }
121
122 } // namespace leak_detector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698