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

Side by Side Diff: third_party/tcmalloc/chromium/src/leak_detector_impl.h

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 // 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 // ---
6 // Author: Simon Que
7
8 #ifndef _LEAK_DETECTOR_IMPL_H_
9 #define _LEAK_DETECTOR_IMPL_H_
10
11 #include "addressmap-inl.h"
12 #include "base/basictypes.h"
13 #include "heap-profile-stats.h"
14 #include "leak_analyzer.h"
15
16 namespace leak_detector {
17
18 class CallStackTable;
19
20 //----------------------------------------------------------------------
21 // Class that contains the actual leak detection mechanism.
22 //----------------------------------------------------------------------
23 class LeakDetectorImpl {
24 public:
25 // Memory (de)allocator interface we'll use.
26 typedef void* (*Allocator)(size_t size);
27 typedef void (*DeAllocator)(void* ptr);
28
29 // Used for tracking allocation stats.
30 using Stats = HeapProfileStats;
31
32 LeakDetectorImpl(Allocator alloc, DeAllocator dealloc, uint64 mapping_addr,
33 uint64 mapping_size);
34 ~LeakDetectorImpl();
35
36 // Indicates whether the given allocation size has an associated call stack
37 // table, and thus requires a stack unwind.
38 bool ShouldGetStackTraceForSize(size_t size) const;
39
40 // Record allocs and frees.
41 void RecordAlloc(const void* ptr, size_t size,
42 int stack_depth, const void* const call_stack[]);
43 void RecordFree(const void* ptr);
44
45 const Stats& stats() const {
46 return stats_;
47 }
48
49 // Run check for possible leaks based on the current profiling data.
50 void TestForLeaks();
51
52 // Dump current profiling statistics to log.
53 void DumpStats() const;
54
55 private:
56 // Used for tracking unique call stacks.
57 using Bucket = HeapProfileBucket;
58
59 // A record of allocations for a particular size.
60 struct AllocSizeEntry {
61 // Number of allocations and frees for this size.
62 uint32 num_allocs;
63 uint32 num_frees;
64
65 // A stack table, if this size is being profiled for stack as well.
66 CallStackTable* stack_table;
67 };
68
69 // Info stored in the address map
70 struct AllocInfo {
71 AllocInfo() : bucket(NULL) {}
72
73 // Number of bytes in this allocation.
74 size_t bytes;
75
76 // Points to a hash table bucket for a unique call stack.
77 Bucket* bucket;
78 };
79
80 // Used for recording size and call stack info for each allocation.
81 using AllocationMap = AddressMap<AllocInfo>;
82
83 // Number of entries in the alloc size table. As sizes are aligned to 32-bits
84 // the max supported allocation size is (kNumSizeEntries * 4 - 1). Any larger
85 // sizes are ignored. This value is chosen high enough that such large sizes
86 // are rare if not nonexistent.
87 static const int kNumSizeEntries = 2048;
88
89 // The number of entries in the hash table for storing call stack buckets.
90 // This does not represent the maximum number of unique call stacks that can
91 // be supported. If there is a collision, multiple call stacks can be stored
92 // in the same slot as a linked list.
93 static const int kHashTableSize = 9973;
94
95 // Converts an allocation size to/from the array index used for |entries_|.
96 static int SizeToIndex(size_t size);
97 static size_t IndexToSize(int index);
98
99 // Accessor for the entry table.
100 inline AllocSizeEntry* GetEntryForSize(size_t size) {
101 return &entries_[SizeToIndex(size)];
102 }
103 inline const AllocSizeEntry& GetConstEntryForSize(size_t size) const {
104 return entries_[SizeToIndex(size)];
105 }
106
107 // Returns a hash table bucket for a call stack. Each unique call stack has a
108 // unique bucket. If the given call stack bucket has already been created by a
109 // previous call to GetBucket(), return a pointer to that same call stack
110 // bucket.
111 Bucket* GetBucket(int depth, const void* const key[]);
112
113 // Returns the offset of |ptr| within the current binary. If it is not in the
114 // current binary, just return |ptr| as an integer.
115 uint64 GetOffset(const void *ptr) const;
116
117 // Functions for local allocations.
118 Allocator alloc_;
119 DeAllocator dealloc_;
120
121 // Bucket hash table for tracking unique call stacks.
122 Bucket* bucket_table_[kHashTableSize];
123 // Counter for the number of unique call stacks.
124 int num_buckets_;
125
126 // For tracking allocation stats.
127 Stats stats_;
128 Stats call_stack_stats_;
129 int num_stack_tables_;
130
131 // Stores all individual recorded allocations.
132 AllocationMap address_map_;
133
134 // Used to analyze potential leak patterns in the allocation sizes.
135 LeakAnalyzer<uint32> size_leak_analyzer_;
136
137 // Allocation stats for each size.
138 AllocSizeEntry entries_[kNumSizeEntries];
139
140 // Address mapping info of the current binary.
141 uint64 mapping_addr_;
142 uint64 mapping_size_;
143
144 DISALLOW_COPY_AND_ASSIGN(LeakDetectorImpl);
145 };
146
147 } // namespace leak_detector
148
149 #endif // _LEAK_DETECTOR_IMPL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698