OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * Copyright (C) 2013 Samsung Electronics. All rights reserved. | 3 // found in the LICENSE file. |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions are | |
7 * met: | |
8 * | |
9 * * Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * * Redistributions in binary form must reproduce the above | |
12 * copyright notice, this list of conditions and the following disclaimer | |
13 * in the documentation and/or other materials provided with the | |
14 * distribution. | |
15 * * Neither the name of Google Inc. nor the names of its | |
16 * contributors may be used to endorse or promote products derived from | |
17 * this software without specific prior written permission. | |
18 * | |
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
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. | |
30 */ | |
31 | 4 |
32 #ifndef WTF_LeakAnnotations_h | 5 #include "platform/wtf/LeakAnnotations.h" |
33 #define WTF_LeakAnnotations_h | |
34 | 6 |
35 // This file defines macros for working with LeakSanitizer, allowing memory | 7 // The contents of this header was moved to platform/wtf as part of |
36 // and allocations to be registered as exempted from LSan consideration. | 8 // WTF migration project. See the following post for details: |
37 | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
38 #include "wtf/Noncopyable.h" | |
39 #if defined(LEAK_SANITIZER) | |
40 #include "wtf/AddressSanitizer.h" | |
41 #include "wtf/TypeTraits.h" | |
42 #endif | |
43 | |
44 namespace WTF { | |
45 | |
46 #if defined(LEAK_SANITIZER) | |
47 class LeakSanitizerDisabler { | |
48 WTF_MAKE_NONCOPYABLE(LeakSanitizerDisabler); | |
49 | |
50 public: | |
51 LeakSanitizerDisabler() { __lsan_disable(); } | |
52 | |
53 ~LeakSanitizerDisabler() { __lsan_enable(); } | |
54 }; | |
55 | |
56 // WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE: all allocations made in the | |
57 // current scope will be exempted from LSan consideration. Only to be | |
58 // used internal to wtf/, Blink should use LEAK_SANITIZER_DISABLED_SCOPE | |
59 // elsewhere. | |
60 // | |
61 // TODO(sof): once layering rules allow wtf/ to make use of the Oilpan | |
62 // infrastructure, remove this macro. | |
63 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE \ | |
64 WTF::LeakSanitizerDisabler leakSanitizerDisabler; \ | |
65 static_cast<void>(0) | |
66 | |
67 // LEAK_SANITIZER_IGNORE_OBJECT(X): the heap object referenced by pointer X | |
68 // will be ignored by LSan. | |
69 // | |
70 // "Ignorance" means that LSan's reachability traversal is stopped short | |
71 // upon encountering an ignored memory chunk. Consequently, LSan will not | |
72 // scan an ignored memory chunk for live, reachable pointers. However, should | |
73 // those embedded pointers be reachable by some other path, they will be | |
74 // reported as leaking. | |
75 #define LEAK_SANITIZER_IGNORE_OBJECT(X) __lsan_ignore_object(X) | |
76 | |
77 // If the object pointed to by the static local is on the Oilpan heap, a strong | |
78 // Persistent<> is created to keep the pointed-to heap object alive. This makes | |
79 // both the Persistent<> and the heap object _reachable_ by LeakSanitizer's leak | |
80 // detection pass. We do not want these intentional leaks to be reported by | |
81 // LSan, hence the static local is registered with Oilpan | |
82 // (see RegisterStaticLocalReference<> below.) | |
83 // | |
84 // Upon Blink shutdown, all the registered statics are released and a final | |
85 // round of GCs are performed to sweep out their now-unreachable object graphs. | |
86 // The end result being a tidied heap that the LeakSanitizer can then scan to | |
87 // report real leaks. | |
88 // | |
89 // The CanRegisterStaticLocalReference<> and RegisterStaticLocalReference<> | |
90 // templates arrange for this -- for a class type T, a registerStatic() | |
91 // implementation is provided if "T* T::registerAsStaticReference(T*)" is a | |
92 // method on T (inherited or otherwise.) | |
93 // | |
94 // An empty, trivial registerStatic() method is provided for all other class | |
95 // types T. | |
96 template <typename T> | |
97 class CanRegisterStaticLocalReference { | |
98 typedef char YesType; | |
99 typedef struct NoType { char padding[8]; } NoType; | |
100 | |
101 // Check if class T has public method "T* registerAsStaticReference()". | |
102 template <typename V> | |
103 static YesType checkHasRegisterAsStaticReferenceMethod( | |
104 V* p, | |
105 typename std::enable_if<IsSubclass< | |
106 V, | |
107 typename std::remove_pointer<decltype( | |
108 p->registerAsStaticReference())>::type>::value>::type* = 0); | |
109 template <typename V> | |
110 static NoType checkHasRegisterAsStaticReferenceMethod(...); | |
111 | |
112 public: | |
113 static const bool value = | |
114 sizeof(YesType) + sizeof(T) == | |
115 sizeof(checkHasRegisterAsStaticReferenceMethod<T>(nullptr)) + sizeof(T); | |
116 }; | |
117 | |
118 template <typename T, bool = CanRegisterStaticLocalReference<T>::value> | |
119 class RegisterStaticLocalReference { | |
120 public: | |
121 static T* registerStatic(T* ptr) { return ptr; } | |
122 }; | |
123 | |
124 template <typename T> | |
125 class RegisterStaticLocalReference<T, true> { | |
126 public: | |
127 static T* registerStatic(T* ptr) { | |
128 return static_cast<T*>(ptr->registerAsStaticReference()); | |
129 } | |
130 }; | |
131 | |
132 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) \ | |
133 WTF::RegisterStaticLocalReference<Type>::registerStatic(Object) | |
134 #else | |
135 #define WTF_INTERNAL_LEAK_SANITIZER_DISABLED_SCOPE | |
136 #define LEAK_SANITIZER_IGNORE_OBJECT(X) ((void)0) | |
137 #define LEAK_SANITIZER_REGISTER_STATIC_LOCAL(Type, Object) Object | |
138 #endif // defined(LEAK_SANITIZER) | |
139 | |
140 } // namespace WTF | |
141 | |
142 #endif // WTF_LeakAnnotations_h | |
OLD | NEW |