OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. | 3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 14 matching lines...) Expand all Loading... |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 #ifndef WTF_LeakAnnotations_h | 32 #ifndef WTF_LeakAnnotations_h |
33 #define WTF_LeakAnnotations_h | 33 #define WTF_LeakAnnotations_h |
34 | 34 |
35 // This file defines macros for working with LeakSanitizer, allowing memory | 35 // This file defines macros which can be used to annotate intentional memory |
36 // and allocations to be registered as exempted from LSan consideration. | 36 // leaks. Support for annotations is implemented in HeapChecker and |
| 37 // LeakSanitizer. Annotated objects will be treated as a source of live |
| 38 // pointers, i.e. any heap objects reachable by following pointers from an |
| 39 // annotated object will not be reported as leaks. |
37 // | 40 // |
38 // LSan exempted memory will be treated as a source of live pointers, | 41 // WTF_ANNOTATE_SCOPED_MEMORY_LEAK: all allocations made in the current scope |
39 // i.e. heap objects reachable by following pointers from an exempted | 42 // will be annotated as leaks. |
40 // object will not be reported as leaks. | 43 // WTF_ANNOTATE_LEAKING_OBJECT_PTR(X): the heap object referenced by pointer X |
| 44 // will be annotated as a leak. |
41 // | 45 // |
| 46 // Note that HeapChecker will report a fatal error if an object which has been |
| 47 // annotated with ANNOTATE_LEAKING_OBJECT_PTR is later deleted (but |
| 48 // LeakSanitizer won't). |
| 49 |
42 #include "wtf/Noncopyable.h" | 50 #include "wtf/Noncopyable.h" |
43 #if USE(LEAK_SANITIZER) | |
44 #include "wtf/AddressSanitizer.h" | |
45 #include "wtf/TypeTraits.h" | |
46 #endif | |
47 | 51 |
48 namespace WTF { | 52 namespace WTF { |
49 | 53 |
50 #if USE(LEAK_SANITIZER) | 54 #if USE(LEAK_SANITIZER) |
| 55 extern "C" { |
| 56 void __lsan_disable(); |
| 57 void __lsan_enable(); |
| 58 void __lsan_ignore_object(const void* p); |
| 59 } // extern "C" |
| 60 |
51 class LeakSanitizerDisabler { | 61 class LeakSanitizerDisabler { |
52 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); | 62 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); |
53 public: | 63 public: |
54 LeakSanitizerDisabler() | 64 LeakSanitizerDisabler() |
55 { | 65 { |
56 __lsan_disable(); | 66 __lsan_disable(); |
57 } | 67 } |
58 | 68 |
59 ~LeakSanitizerDisabler() | 69 ~LeakSanitizerDisabler() |
60 { | 70 { |
61 __lsan_enable(); | 71 __lsan_enable(); |
62 } | 72 } |
63 }; | 73 }; |
64 | 74 |
65 // WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the | 75 #define WTF_ANNOTATE_SCOPED_MEMORY_LEAK \ |
66 // current scope will be exempted from LSan consideration. Only to be | |
67 // used internal to wtf/, Blink should use LEAK_SANITIZER_DISABLED_SCOPE | |
68 // elsewhere. | |
69 // | |
70 // TODO(sof): once layering rules allow wtf/ to make use of the Oilpan | |
71 // infrastructure, remove this macro. | |
72 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE \ | |
73 WTF::LeakSanitizerDisabler leakSanitizerDisabler; static_cast<void>(0) | 76 WTF::LeakSanitizerDisabler leakSanitizerDisabler; static_cast<void>(0) |
74 | 77 |
75 // LEAK_SANITIZER_IGNORE_OBJECT(X): the heap object referenced by pointer X | 78 #define WTF_ANNOTATE_LEAKING_OBJECT_PTR(X) \ |
76 // will be ignored by LSan. | 79 WTF::__lsan_ignore_object(X) |
77 #define LEAK_SANITIZER_IGNORE_OBJECT(X) __lsan_ignore_object(X) | |
78 | 80 |
79 // If the object pointed to by the static local is on the Oilpan heap, a strong | 81 #else // USE(LEAK_SANITIZER) |
80 // Persistent<> is created to keep the pointed-to heap object alive. This makes | |
81 // both the Persistent<> and the heap object _reachable_ by LeakSanitizer's leak | |
82 // detection pass. We do not want these intentional leaks to be reported by LSan
, | |
83 // hence the static local is registered with Oilpan | |
84 // (see RegisterStaticLocalReference<> below.) | |
85 // | |
86 // Upon Blink shutdown, all the registered statics are released and a final roun
d | |
87 // of GCs are performed to sweep out their now-unreachable object graphs. The en
d | |
88 // result being a tidied heap that the LeakSanitizer can then scan to report rea
l leaks. | |
89 // | |
90 // The CanRegisterStaticLocalReference<> and RegisterStaticLocalReference<> temp
lates | |
91 // arrange for this -- for a class type T, a registerStatic() implementation is | |
92 // provided if "T* T::registerAsStaticReference(T*)" is a method on T | |
93 // (inherited or otherwise.) | |
94 // | |
95 // An empty, trivial registerStatic() method is provided for all other class typ
es T. | |
96 template<typename T> | |
97 class CanRegisterStaticLocalReference { | |
98 typedef char YesType; | |
99 typedef struct NoType { | |
100 char padding[8]; | |
101 } NoType; | |
102 | 82 |
103 // Check if class T has public method "T* registerAsStaticReference()". | 83 // If Leak Sanitizer is not being used, the annotations should be no-ops. |
104 template<typename V> static YesType checkHasRegisterAsStaticReferenceMethod(
V* p, typename EnableIf<IsSubclass<V, typename std::remove_pointer<decltype(p->r
egisterAsStaticReference())>::type>::value>::Type* = 0); | 84 #define WTF_ANNOTATE_SCOPED_MEMORY_LEAK |
105 template<typename V> static NoType checkHasRegisterAsStaticReferenceMethod(.
..); | 85 #define WTF_ANNOTATE_LEAKING_OBJECT_PTR(X) |
106 | 86 |
107 public: | |
108 static const bool value = sizeof(YesType) + sizeof(T) == sizeof(checkHasRegi
sterAsStaticReferenceMethod<T>(nullptr)) + sizeof(T); | |
109 }; | |
110 | |
111 template<typename T, bool = CanRegisterStaticLocalReference<T>::value> | |
112 class RegisterStaticLocalReference { | |
113 public: | |
114 static T* registerStatic(T* ptr) | |
115 { | |
116 return ptr; | |
117 } | |
118 }; | |
119 | |
120 template<typename T> | |
121 class RegisterStaticLocalReference<T, true> { | |
122 public: | |
123 static T* registerStatic(T* ptr) | |
124 { | |
125 return static_cast<T*>(ptr->registerAsStaticReference()); | |
126 } | |
127 }; | |
128 | |
129 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) WTF::RegisterStaticLo
calReference<Type>::registerStatic(Object) | |
130 #else | |
131 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE | |
132 #define LEAK_SANITIZER_IGNORE_OBJECT | |
133 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) Object | |
134 #endif // USE(LEAK_SANITIZER) | 87 #endif // USE(LEAK_SANITIZER) |
135 | 88 |
136 } // namespace WTF | 89 } // namespace WTF |
137 | 90 |
138 #endif // WTF_LeakAnnotations_h | 91 #endif // WTF_LeakAnnotations_h |
OLD | NEW |