| 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 |