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