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

Side by Side Diff: third_party/tcmalloc/chromium/src/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 error in leak analyzer logic Created 5 years, 6 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 #include "call_stack_table.h"
2
3 #include <cstring>
4
5 #include "base/commandlineflags.h"
6 #include "heap-profile-stats.h"
7
8 // A call stack must be suspected this many times to be reported as a leak
9 // suspect.
10 DECLARE_int32(call_stack_size_suspicion_threshold);
11
12 namespace leak_detector {
13
14 namespace {
15
16 using Bucket = CallStackTable::Bucket;
17
18 // Get the top |kRankedListSize| entries.
19 const int kRankedListSize = 16;
20
21 // Initial number of hash table buckets.
22 const int kInitialHashTableSize = 1999;
23
24 // Used for printing call stacks in LeakAnalyzer.
25 class StringPrint : public LeakAnalyzer<const Bucket*>::StringPrint {
26 public:
27 // Gets the string representation of a value.
28 virtual const char* ValueToString(const Bucket* const& ptr, bool spacing_on) {
29 snprintf(buffer_, sizeof(buffer_), spacing_on ? "%16p" : "%p", ptr);
30 return buffer_;
31 }
32
33 // Gets the word that describes the value type.
34 virtual const char* ValueTypeName(bool is_plural) {
35 return is_plural ? "buckets" : "bucket";
36 }
37 } string_print;
38
39 } // namespace
40
41 CallStackTable::CallStackTable(Allocator alloc, DeAllocator dealloc)
42 : num_allocs_(0),
43 num_frees_(0),
44 alloc_(alloc),
45 dealloc_(dealloc),
46 entry_map_(kInitialHashTableSize),
47 leak_analyzer_(kRankedListSize, FLAGS_call_stack_size_suspicion_threshold,
48 alloc, dealloc, &string_print) {
49 }
50
51 CallStackTable::~CallStackTable() {}
52
53 void CallStackTable::Add(const Bucket* ptr) {
54 auto iter = entry_map_.find(ptr);
55 Entry* entry = NULL;
56 if (iter == entry_map_.end()) {
57 entry = &entry_map_[ptr];
58 } else {
59 entry = &iter->second;
60 }
61
62 ++entry->num_allocs;
63 ++num_allocs_;
64 }
65
66 void CallStackTable::Remove(const Bucket* ptr) {
67 auto iter = entry_map_.find(ptr);
68 if (iter == entry_map_.end())
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: %u\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) {
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)
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<const Bucket*> ranked_list(kRankedListSize, alloc_, dealloc_);
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 ranked_list.Add(entry_pair.first, entry.num_allocs - entry.num_frees);
116 }
117 leak_analyzer_.AddSample(ranked_list);
118 }
119
120 // static
121 void CallStackTable::Alloc::Init(Allocator alloc, DeAllocator dealloc) {
122 alloc_ = alloc;
123 dealloc_ = dealloc;
124 }
125
126 // static
127 void* CallStackTable::Alloc::Allocate(size_t size) {
128 if (alloc_)
129 return alloc_(size);
130 return NULL;
131 }
132
133 // static
134 void CallStackTable::Alloc::Free(void* ptr, size_t size) {
135 if (free)
gpike 2015/07/01 21:38:21 why free?
Simon Que 2015/07/10 00:09:06 Meant dealloc_.
136 dealloc_(ptr);
137 }
138
139 // static
140 CallStackTable::Allocator CallStackTable::Alloc::alloc_ = NULL;
141 // static
142 CallStackTable::DeAllocator CallStackTable::Alloc::dealloc_ = NULL;
143
144
145 } // namespace leak_detector
OLDNEW
« no previous file with comments | « third_party/tcmalloc/chromium/src/call_stack_table.h ('k') | third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698