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

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: Remove Author label from new files; Check type in LeakDetectorValueType comparators; Add missing fi… Created 5 years, 5 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 (c) 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 "call_stack_table.h"
6
7 #include <cstring>
8
9 #include "base/commandlineflags.h"
10 #include "heap-profile-stats.h"
11
12 // A call stack must be suspected this many times to be reported as a leak
13 // suspect.
14 DECLARE_int32(call_stack_suspicion_threshold);
15
16 namespace leak_detector {
17
18 namespace {
19
20 using CallStack = CallStackTable::CallStack;
21 using ValueType = LeakDetectorValueType;
22
23 // Get the top |kRankedListSize| entries.
24 const int kRankedListSize = 16;
25
26 // Initial number of hash table buckets.
27 const int kInitialHashTableSize = 1999;
28
29 // Used for printing call stacks in LeakAnalyzer.
30 class StringPrint : public LeakAnalyzer::StringPrint {
31 public:
32 // Gets the string representation of a value.
33 virtual const char* ValueToString(const ValueType& value, bool spacing_on) {
34 const CallStack* call_stack = value.call_stack();
35 snprintf(buffer_, sizeof(buffer_), spacing_on ? "%16p" : "%p", call_stack);
36 return buffer_;
37 }
38
39 // Gets the word that describes the value type.
40 virtual const char* ValueTypeName(bool is_plural) {
41 return is_plural ? "call stacks" : "call stack";
42 }
43 } string_print;
44
45 } // namespace
46
47 CallStackTable::CallStackTable()
48 : num_allocs_(0),
49 num_frees_(0),
50 entry_map_(kInitialHashTableSize),
51 leak_analyzer_(kRankedListSize, FLAGS_call_stack_suspicion_threshold,
52 &string_print) {
53 }
54
55 CallStackTable::~CallStackTable() {}
56
57 void CallStackTable::Add(const CallStack* call_stack) {
58 auto iter = entry_map_.find(call_stack);
59 Entry* entry = NULL;
60 if (iter == entry_map_.end()) {
61 entry = &entry_map_[call_stack];
62 } else {
63 entry = &iter->second;
64 }
65
66 ++entry->num_allocs;
67 ++num_allocs_;
68 }
69
70 void CallStackTable::Remove(const CallStack* call_stack) {
71 auto iter = entry_map_.find(call_stack);
72 if (iter == entry_map_.end())
73 return;
74 Entry* entry = &iter->second;
75 ++entry->num_frees;
76 ++num_frees_;
77
78 // If there are no net allocs, delete the entry.
79 if (entry->num_allocs == entry->num_frees)
80 entry_map_.erase(iter);
81 }
82
83 int CallStackTable::Dump(char* buffer, const int buffer_size) const {
84 int size_left = buffer_size;
85
86 if (entry_map_.empty())
87 return size_left;
88
89 int attempted_size =
90 snprintf(buffer, size_left,
91 "Total number of allocations: %u\n"
92 "Total number of frees: %u\n"
93 "Net number of allocations: %u\n"
94 "Total number of distinct stack traces: %lu\n",
95 num_allocs_, num_frees_, num_allocs_ - num_frees_,
96 entry_map_.size());
97 size_left -= attempted_size;
98 buffer += attempted_size;
99
100 if (size_left > 0) {
101 int attempted_size = leak_analyzer_.Dump(buffer, size_left);
102 size_left -= attempted_size;
103 buffer += attempted_size;
104 }
105
106 if (size_left > 0)
107 return buffer_size - size_left;
108
109 return buffer_size;
110 }
111
112 void CallStackTable::TestForLeaks() {
113 // Add all entries to the ranked list.
114 RankedList ranked_list(kRankedListSize);
115
116 for (const auto& entry_pair : entry_map_) {
117 const Entry& entry = entry_pair.second;
118 if (entry.num_allocs != entry.num_frees) {
119 LeakDetectorValueType call_stack_value(entry_pair.first);
120 ranked_list.Add(call_stack_value, entry.num_allocs - entry.num_frees);
121 }
122 }
123 leak_analyzer_.AddSample(ranked_list);
124 }
125
126 } // namespace leak_detector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698