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

Side by Side Diff: components/metrics/leak_detector/leak_detector.h

Issue 1665553002: metrics: Connect leak detector to allocator (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: primiano's feedback; Register observer sooner Created 4 years, 9 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 #ifndef COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_ 5 #ifndef COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_
6 #define COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_ 6 #define COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_
7 7
8 #include <stddef.h> 8 #include <stddef.h>
9 #include <stdint.h> 9 #include <stdint.h>
10 10
11 #include <list> 11 #include <list>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/feature_list.h" 14 #include "base/feature_list.h"
15 #include "base/gtest_prod_util.h" 15 #include "base/gtest_prod_util.h"
16 #include "base/macros.h" 16 #include "base/macros.h"
17 #include "base/memory/weak_ptr.h" 17 #include "base/memory/scoped_ptr.h"
18 #include "base/observer_list.h" 18 #include "base/observer_list.h"
19 #include "base/synchronization/lock.h"
19 #include "base/threading/thread_checker.h" 20 #include "base/threading/thread_checker.h"
20 21
22 namespace base {
23 template <typename T>
24 struct DefaultLazyInstanceTraits;
25 }
26
21 namespace metrics { 27 namespace metrics {
22 28
29 namespace leak_detector {
30 class LeakDetectorImpl;
31 }
32
23 // LeakDetector is an interface layer that connects the allocator 33 // LeakDetector is an interface layer that connects the allocator
24 // (base::allocator), the leak detector logic (LeakDetectorImpl), and any 34 // (base::allocator), the leak detector logic (LeakDetectorImpl), and any
25 // external classes interested in receiving leak reports (extend the Observer 35 // external classes interested in receiving leak reports (extend the Observer
26 // class). 36 // class).
27 // 37 //
28 // Currently it is stubbed out and only provides an interface for registering 38 // Only one instance of this class can exist. Access this instance using
29 // observers to receive leak reports. 39 // GetInstance(). Do not create an instance of this class directly.
30 // TODO(sque): Add the full functionality and allow only one instance.
31 // 40 //
32 // This class is not thread-safe, and it should always be called on the same 41 // These member functions are thread-safe:
33 // thread that instantiated it. 42 // - AllocHook
43 // - FreeHook
44 // - AddObserver
45 // - RemoveObserver
46 //
47 // All other functions must always be called from the same thread. This is
48 // enforced with a DCHECK.
34 class LeakDetector { 49 class LeakDetector {
35 public: 50 public:
36 // Contains a report of a detected memory leak. 51 // Contains a report of a detected memory leak.
37 struct LeakReport { 52 struct LeakReport {
38 LeakReport(); 53 LeakReport();
39 ~LeakReport(); 54 ~LeakReport();
40 55
41 size_t alloc_size_bytes; 56 size_t alloc_size_bytes;
42 57
43 // Unlike the CallStack struct, which consists of addresses, this call stack 58 // Unlike the CallStack struct, which consists of addresses, this call stack
44 // will contain offsets in the executable binary. 59 // will contain offsets in the executable binary.
45 std::vector<uintptr_t> call_stack; 60 std::vector<uintptr_t> call_stack;
46 }; 61 };
47 62
48 // Interface for receiving leak reports. 63 // Interface for receiving leak reports.
49 class Observer { 64 class Observer {
50 public: 65 public:
51 virtual ~Observer() {} 66 virtual ~Observer() {}
52 67
53 // Called by leak detector to report a leak. 68 // Called by leak detector to report a leak.
54 virtual void OnLeakFound(const LeakReport& report) = 0; 69 virtual void OnLeakFound(const LeakReport& report) = 0;
55 }; 70 };
56 71
57 // Constructor arguments: 72 // Returns the sole instance, or creates it if it hasn't already been created.
73 static LeakDetector* GetInstance();
74
75 // Initializer arguments:
58 // sampling_rate: 76 // sampling_rate:
59 // Pseudorandomly sample a fraction of the incoming allocations and frees, 77 // Pseudorandomly sample a fraction of the incoming allocations and frees,
60 // based on hash values. Setting to 0 means no allocs/frees are sampled. 78 // based on hash values. Setting to 0 means no allocs/frees are sampled.
61 // Setting to 1.0 or more means all allocs/frees are sampled. Anything in 79 // Setting to 1.0 or more means all allocs/frees are sampled. Anything in
62 // between will result in an approximately that fraction of allocs/frees 80 // between will result in an approximately that fraction of allocs/frees
63 // being sampled. 81 // being sampled.
64 // max_call_stack_unwind_depth: 82 // max_call_stack_unwind_depth:
65 // The max number of call stack frames to unwind. 83 // The max number of call stack frames to unwind.
66 // analysis_interval_bytes: 84 // analysis_interval_bytes:
67 // Perform a leak analysis each time this many bytes have been allocated 85 // Perform a leak analysis each time this many bytes have been allocated
68 // since the previous analysis. 86 // since the previous analysis.
69 // size_suspicion_threshold, call_stack_suspicion_threshold: 87 // size_suspicion_threshold, call_stack_suspicion_threshold:
70 // A possible leak should be suspected this many times to take action on i 88 // A possible leak should be suspected this many times to take action on i
71 // For size analysis, the action is to start profiling by call stack. 89 // For size analysis, the action is to start profiling by call stack.
72 // For call stack analysis, the action is to generate a leak report. 90 // For call stack analysis, the action is to generate a leak report.
73 LeakDetector(float sampling_rate, 91 void Init(float sampling_rate,
74 size_t max_call_stack_unwind_depth, 92 size_t max_call_stack_unwind_depth,
75 uint64_t analysis_interval_bytes, 93 uint64_t analysis_interval_bytes,
76 uint32_t size_suspicion_threshold, 94 uint32_t size_suspicion_threshold,
77 uint32_t call_stack_suspicion_threshold); 95 uint32_t call_stack_suspicion_threshold);
78
79 ~LeakDetector();
80 96
81 // Add |observer| to the list of stored Observers, i.e. |observers_|, to which 97 // Add |observer| to the list of stored Observers, i.e. |observers_|, to which
82 // the leak detector will report leaks. 98 // the leak detector will report leaks.
83 void AddObserver(Observer* observer); 99 void AddObserver(Observer* observer);
84 100
85 // Remove |observer| from |observers_|. 101 // Remove |observer| from |observers_|.
86 void RemoveObserver(Observer* observer); 102 void RemoveObserver(Observer* observer);
87 103
88 private: 104 private:
105 friend base::DefaultLazyInstanceTraits<LeakDetector>;
89 FRIEND_TEST_ALL_PREFIXES(LeakDetectorTest, NotifyObservers); 106 FRIEND_TEST_ALL_PREFIXES(LeakDetectorTest, NotifyObservers);
90 107
108 // Keep these private, as this class is meant to be initialized only through
109 // the lazy instance, and never destroyed.
110 LeakDetector();
111 ~LeakDetector();
112
113 // Allocator hook function that processes each alloc. Performs sampling and
114 // unwinds call stack if necessary. Passes the allocated memory |ptr| and
115 // allocation size |size| along with call stack info to RecordAlloc().
116 static void AllocHook(const void* ptr, size_t size);
117
118 // Allocator hook function that processes each free. Performs sampling and
119 // passes the allocation address |ptr| to |impl_|.
120 static void FreeHook(const void* ptr);
121
122 // Give an pointer |ptr|, computes a hash of the pointer value and compares it
123 // against |sampling_factor_| to determine if it should be sampled. This
124 // allows the same pointer to be sampled during both alloc and free.
125 bool ShouldSample(const void* ptr) const;
126
91 // Notifies all Observers in |observers_| with the given vector of leak 127 // Notifies all Observers in |observers_| with the given vector of leak
92 // reports. 128 // reports.
93 void NotifyObservers(const std::vector<LeakReport>& reports); 129 void NotifyObservers(const std::vector<LeakReport>& reports);
94 130
95 // List of observers to notify when there's a leak report. 131 // List of observers to notify when there's a leak report.
132 // TODO(sque): Consider using ObserverListThreadSafe instead.
96 base::ObserverList<Observer> observers_; 133 base::ObserverList<Observer> observers_;
97 134
135 // For atomic access to |observers_|.
136 base::Lock observers_lock_;
137
138 // Handles leak detection logic. Must be called under lock as LeakDetectorImpl
139 // uses shared resources.
140 scoped_ptr<leak_detector::LeakDetectorImpl> impl_;
141
98 // For thread safety. 142 // For thread safety.
99 base::ThreadChecker thread_checker_; 143 base::ThreadChecker thread_checker_;
100 144
101 // For generating closures containing objects of this class. 145 // Total number of bytes allocated, computed before sampling.
102 base::WeakPtrFactory<LeakDetector> weak_factory_; 146 size_t total_alloc_size_;
147
148 // The value of |total_alloc_size_| the last time there was a leak analysis,
149 // rounded down to the nearest multiple of |analysis_interval_bytes_|.
150 size_t last_analysis_alloc_size_;
151
152 // For atomic access to |impl_|, |total_alloc_size_| and
153 // |last_analysis_alloc_size_|.
154 base::Lock recording_lock_;
155
156 // Perform a leak analysis each time this many bytes have been allocated since
157 // the previous analysis.
158 size_t analysis_interval_bytes_;
159
160 // When unwinding call stacks, unwind no more than this number of frames.
161 size_t max_call_stack_unwind_depth_;
162
163 // Sampling factor used by ShouldSample(). It's full range of values
164 // corresponds to the allowable range of |sampling_rate| passed in during
165 // initialization: [0.0f, 1.0f] -> [0, UINT64_MAX].
166 uint64_t sampling_factor_;
103 167
104 DISALLOW_COPY_AND_ASSIGN(LeakDetector); 168 DISALLOW_COPY_AND_ASSIGN(LeakDetector);
105 }; 169 };
106 170
107 } // namespace metrics 171 } // namespace metrics
108 172
109 #endif // COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_ 173 #endif // COMPONENTS_METRICS_LEAK_DETECTOR_LEAK_DETECTOR_H_
OLDNEW
« no previous file with comments | « chrome/browser/metrics/leak_detector_controller.cc ('k') | components/metrics/leak_detector/leak_detector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698