/src/abseil-cpp/absl/debugging/leak_check.h
Line  | Count  | Source  | 
1  |  | // Copyright 2018 The Abseil Authors.  | 
2  |  | //  | 
3  |  | // Licensed under the Apache License, Version 2.0 (the "License");  | 
4  |  | // you may not use this file except in compliance with the License.  | 
5  |  | // You may obtain a copy of the License at  | 
6  |  | //  | 
7  |  | //      https://www.apache.org/licenses/LICENSE-2.0  | 
8  |  | //  | 
9  |  | // Unless required by applicable law or agreed to in writing, software  | 
10  |  | // distributed under the License is distributed on an "AS IS" BASIS,  | 
11  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  | 
12  |  | // See the License for the specific language governing permissions and  | 
13  |  | // limitations under the License.  | 
14  |  | //  | 
15  |  | // -----------------------------------------------------------------------------  | 
16  |  | // File: leak_check.h  | 
17  |  | // -----------------------------------------------------------------------------  | 
18  |  | //  | 
19  |  | // This file contains functions that affect leak checking behavior within  | 
20  |  | // targets built with the LeakSanitizer (LSan), a memory leak detector that is  | 
21  |  | // integrated within the AddressSanitizer (ASan) as an additional component, or  | 
22  |  | // which can be used standalone. LSan and ASan are included (or can be provided)  | 
23  |  | // as additional components for most compilers such as Clang, gcc and MSVC.  | 
24  |  | // Note: this leak checking API is not yet supported in MSVC.  | 
25  |  | // Leak checking is enabled by default in all ASan builds.  | 
26  |  | //  | 
27  |  | // https://clang.llvm.org/docs/LeakSanitizer.html  | 
28  |  | // https://github.com/google/sanitizers/wiki/AddressSanitizerLeakSanitizer  | 
29  |  | //  | 
30  |  | // GCC and Clang both automatically enable LeakSanitizer when AddressSanitizer  | 
31  |  | // is enabled. To use the mode, simply pass `-fsanitize=address` to both the  | 
32  |  | // compiler and linker. An example Bazel command could be  | 
33  |  | //  | 
34  |  | //   $ bazel test --copt=-fsanitize=address --linkopt=-fsanitize=address ...  | 
35  |  | //  | 
36  |  | // GCC and Clang auto support a standalone LeakSanitizer mode (a mode which does  | 
37  |  | // not also use AddressSanitizer). To use the mode, simply pass  | 
38  |  | // `-fsanitize=leak` to both the compiler and linker. Since GCC does not  | 
39  |  | // currently provide a way of detecting this mode at compile-time, GCC users  | 
40  |  | // must also pass -DLEAK_SANITIZER to the compiler. An example Bazel command  | 
41  |  | // could be  | 
42  |  | //  | 
43  |  | //   $ bazel test --copt=-DLEAK_SANITIZER --copt=-fsanitize=leak  | 
44  |  | //     --linkopt=-fsanitize=leak ...  | 
45  |  | //  | 
46  |  | // -----------------------------------------------------------------------------  | 
47  |  | #ifndef ABSL_DEBUGGING_LEAK_CHECK_H_  | 
48  |  | #define ABSL_DEBUGGING_LEAK_CHECK_H_  | 
49  |  |  | 
50  |  | #include <cstddef>  | 
51  |  |  | 
52  |  | #include "absl/base/config.h"  | 
53  |  |  | 
54  |  | namespace absl { | 
55  |  | ABSL_NAMESPACE_BEGIN  | 
56  |  |  | 
57  |  | // HaveLeakSanitizer()  | 
58  |  | //  | 
59  |  | // Returns true if a leak-checking sanitizer (either ASan or standalone LSan) is  | 
60  |  | // currently built into this target.  | 
61  |  | bool HaveLeakSanitizer();  | 
62  |  |  | 
63  |  | // LeakCheckerIsActive()  | 
64  |  | //  | 
65  |  | // Returns true if a leak-checking sanitizer (either ASan or standalone LSan) is  | 
66  |  | // currently built into this target and is turned on.  | 
67  |  | bool LeakCheckerIsActive();  | 
68  |  |  | 
69  |  | // DoIgnoreLeak()  | 
70  |  | //  | 
71  |  | // Implements `IgnoreLeak()` below. This function should usually  | 
72  |  | // not be called directly; calling `IgnoreLeak()` is preferred.  | 
73  |  | void DoIgnoreLeak(const void* ptr);  | 
74  |  |  | 
75  |  | // IgnoreLeak()  | 
76  |  | //  | 
77  |  | // Instruct the leak sanitizer to ignore leak warnings on the object referenced  | 
78  |  | // by the passed pointer, as well as all heap objects transitively referenced  | 
79  |  | // by it. The passed object pointer can point to either the beginning of the  | 
80  |  | // object or anywhere within it.  | 
81  |  | //  | 
82  |  | // Example:  | 
83  |  | //  | 
84  |  | //   static T* obj = IgnoreLeak(new T(...));  | 
85  |  | //  | 
86  |  | // If the passed `ptr` does not point to an actively allocated object at the  | 
87  |  | // time `IgnoreLeak()` is called, the call is a no-op; if it is actively  | 
88  |  | // allocated, leak sanitizer will assume this object is referenced even if  | 
89  |  | // there is no actual reference in user memory.  | 
90  |  | //  | 
91  |  | template <typename T>  | 
92  | 0  | T* IgnoreLeak(T* ptr) { | 
93  | 0  |   DoIgnoreLeak(ptr);  | 
94  | 0  |   return ptr;  | 
95  | 0  | }  | 
96  |  |  | 
97  |  | // FindAndReportLeaks()  | 
98  |  | //  | 
99  |  | // If any leaks are detected, prints a leak report and returns true.  This  | 
100  |  | // function may be called repeatedly, and does not affect end-of-process leak  | 
101  |  | // checking.  | 
102  |  | //  | 
103  |  | // Example:  | 
104  |  | // if (FindAndReportLeaks()) { | 
105  |  | //   ... diagnostic already printed. Exit with failure code.  | 
106  |  | //   exit(1)  | 
107  |  | // }  | 
108  |  | bool FindAndReportLeaks();  | 
109  |  |  | 
110  |  | // LeakCheckDisabler  | 
111  |  | //  | 
112  |  | // This helper class indicates that any heap allocations done in the code block  | 
113  |  | // covered by the scoped object, which should be allocated on the stack, will  | 
114  |  | // not be reported as leaks. Leak check disabling will occur within the code  | 
115  |  | // block and any nested function calls within the code block.  | 
116  |  | //  | 
117  |  | // Example:  | 
118  |  | //  | 
119  |  | //   void Foo() { | 
120  |  | //     LeakCheckDisabler disabler;  | 
121  |  | //     ... code that allocates objects whose leaks should be ignored ...  | 
122  |  | //   }  | 
123  |  | //  | 
124  |  | // REQUIRES: Destructor runs in same thread as constructor  | 
125  |  | class LeakCheckDisabler { | 
126  |  |  public:  | 
127  |  |   LeakCheckDisabler();  | 
128  |  |   LeakCheckDisabler(const LeakCheckDisabler&) = delete;  | 
129  |  |   LeakCheckDisabler& operator=(const LeakCheckDisabler&) = delete;  | 
130  |  |   ~LeakCheckDisabler();  | 
131  |  | };  | 
132  |  |  | 
133  |  | // RegisterLivePointers()  | 
134  |  | //  | 
135  |  | // Registers `ptr[0,size-1]` as pointers to memory that is still actively being  | 
136  |  | // referenced and for which leak checking should be ignored. This function is  | 
137  |  | // useful if you store pointers in mapped memory, for memory ranges that we know  | 
138  |  | // are correct but for which normal analysis would flag as leaked code.  | 
139  |  | void RegisterLivePointers(const void* ptr, size_t size);  | 
140  |  |  | 
141  |  | // UnRegisterLivePointers()  | 
142  |  | //  | 
143  |  | // Deregisters the pointers previously marked as active in  | 
144  |  | // `RegisterLivePointers()`, enabling leak checking of those pointers.  | 
145  |  | void UnRegisterLivePointers(const void* ptr, size_t size);  | 
146  |  |  | 
147  |  | ABSL_NAMESPACE_END  | 
148  |  | }  // namespace absl  | 
149  |  |  | 
150  |  | #endif  // ABSL_DEBUGGING_LEAK_CHECK_H_  |