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 which can be used to annotate intentional memory | 35 // This file defines macros for working with LeakSanitizer, allowing memory |
36 // leaks. Support for annotations is implemented in HeapChecker and | 36 // and allocations to be registered as exempted from LSan consideration. |
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. | |
40 // | 37 // |
41 // WTF_ANNOTATE_SCOPED_MEMORY_LEAK: all allocations made in the current scope | 38 // LSan exempted memory will be treated as a source of live pointers, |
42 // will be annotated as leaks. | 39 // i.e. heap objects reachable by following pointers from an exempted |
43 // WTF_ANNOTATE_LEAKING_OBJECT_PTR(X): the heap object referenced by pointer X | 40 // object will not be reported as leaks. |
44 // will be annotated as a leak. | |
45 // | 41 // |
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 | |
50 #include "wtf/Noncopyable.h" | 42 #include "wtf/Noncopyable.h" |
| 43 #if USE(LEAK_SANITIZER) |
| 44 #include "wtf/AddressSanitizer.h" |
| 45 #include "wtf/TypeTraits.h" |
| 46 #endif |
51 | 47 |
52 namespace WTF { | 48 namespace WTF { |
53 | 49 |
54 #if USE(LEAK_SANITIZER) | 50 #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 | |
61 class LeakSanitizerDisabler { | 51 class LeakSanitizerDisabler { |
62 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); | 52 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); |
63 public: | 53 public: |
64 LeakSanitizerDisabler() | 54 LeakSanitizerDisabler() |
65 { | 55 { |
66 __lsan_disable(); | 56 __lsan_disable(); |
67 } | 57 } |
68 | 58 |
69 ~LeakSanitizerDisabler() | 59 ~LeakSanitizerDisabler() |
70 { | 60 { |
71 __lsan_enable(); | 61 __lsan_enable(); |
72 } | 62 } |
73 }; | 63 }; |
74 | 64 |
75 #define WTF_ANNOTATE_SCOPED_MEMORY_LEAK \ | 65 // WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the |
| 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 \ |
76 WTF::LeakSanitizerDisabler leakSanitizerDisabler; static_cast<void>(0) | 73 WTF::LeakSanitizerDisabler leakSanitizerDisabler; static_cast<void>(0) |
77 | 74 |
78 #define WTF_ANNOTATE_LEAKING_OBJECT_PTR(X) \ | 75 // LEAK_SANITIZER_IGNORE_OBJECT(X): the heap object referenced by pointer X |
79 WTF::__lsan_ignore_object(X) | 76 // will be ignored by LSan. |
| 77 #define LEAK_SANITIZER_IGNORE_OBJECT(X) __lsan_ignore_object(X) |
80 | 78 |
81 #else // USE(LEAK_SANITIZER) | 79 // If the object pointed to by the static local is on the Oilpan heap, a strong |
| 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; |
82 | 102 |
83 // If Leak Sanitizer is not being used, the annotations should be no-ops. | 103 // Check if class T has public method "T* registerAsStaticReference()". |
84 #define WTF_ANNOTATE_SCOPED_MEMORY_LEAK | 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); |
85 #define WTF_ANNOTATE_LEAKING_OBJECT_PTR(X) | 105 template<typename V> static NoType checkHasRegisterAsStaticReferenceMethod(.
..); |
86 | 106 |
| 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 |
87 #endif // USE(LEAK_SANITIZER) | 134 #endif // USE(LEAK_SANITIZER) |
88 | 135 |
89 } // namespace WTF | 136 } // namespace WTF |
90 | 137 |
91 #endif // WTF_LeakAnnotations_h | 138 #endif // WTF_LeakAnnotations_h |
OLD | NEW |