OLD | NEW |
1 /* | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. | 2 // Use of this source code is governed by a BSD-style license that can be |
3 * Copyright (C) 2013 Google Inc. 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 | |
7 * are met: | |
8 * 1. Redistributions of source code must retain the above copyright | |
9 * notice, this list of conditions and the following disclaimer. | |
10 * 2. Redistributions in binary form must reproduce the above copyright | |
11 * notice, this list of conditions and the following disclaimer in the | |
12 * documentation and/or other materials provided with the distribution. | |
13 * | |
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY | |
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR | |
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | |
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 */ | |
26 | 4 |
27 #ifndef WTF_Assertions_h | 5 #include "platform/wtf/Assertions.h" |
28 #define WTF_Assertions_h | |
29 | 6 |
30 // This file uses some GCC extensions, but it should be compatible with C++ and | 7 // The contents of this header was moved to platform/wtf as part of |
31 // Objective C++. | 8 // WTF migration project. See the following post for details: |
32 // | 9 // https://groups.google.com/a/chromium.org/d/msg/blink-dev/tLdAZCTlcAA/bYXVT8gY
CAAJ |
33 // For non-debug builds, everything is disabled by default, except for the | |
34 // RELEASE_ASSERT family of macros. | |
35 | |
36 #include <stdarg.h> | |
37 #include "base/allocator/partition_allocator/oom.h" | |
38 #include "base/gtest_prod_util.h" | |
39 #include "base/logging.h" | |
40 #include "wtf/Compiler.h" | |
41 #include "wtf/Noncopyable.h" | |
42 #include "wtf/WTFExport.h" | |
43 #include "wtf/build_config.h" | |
44 | |
45 #if OS(WIN) | |
46 #include <windows.h> | |
47 #endif | |
48 | |
49 #ifndef LOG_DISABLED | |
50 #define LOG_DISABLED !DCHECK_IS_ON() | |
51 #endif | |
52 | |
53 // WTFLogAlways() is deprecated. crbug.com/638849 | |
54 WTF_EXPORT PRINTF_FORMAT(1, 2) void WTFLogAlways(const char* format, ...); | |
55 | |
56 namespace WTF { | |
57 | |
58 #if LOG_DISABLED | |
59 | |
60 #define WTF_CREATE_SCOPED_LOGGER(...) ((void)0) | |
61 #define WTF_CREATE_SCOPED_LOGGER_IF(...) ((void)0) | |
62 #define WTF_APPEND_SCOPED_LOGGER(...) ((void)0) | |
63 | |
64 #else | |
65 | |
66 // ScopedLogger wraps log messages in parentheses, with indentation proportional | |
67 // to the number of instances. This makes it easy to see the flow of control in | |
68 // the output, particularly when instrumenting recursive functions. | |
69 // | |
70 // NOTE: This class is a debugging tool, not intended for use by checked-in | |
71 // code. Please do not remove it. | |
72 // | |
73 class WTF_EXPORT ScopedLogger { | |
74 WTF_MAKE_NONCOPYABLE(ScopedLogger); | |
75 | |
76 public: | |
77 // The first message is passed to the constructor. Additional messages for | |
78 // the same scope can be added with log(). If condition is false, produce no | |
79 // output and do not create a scope. | |
80 PRINTF_FORMAT(3, 4) ScopedLogger(bool condition, const char* format, ...); | |
81 ~ScopedLogger(); | |
82 PRINTF_FORMAT(2, 3) void log(const char* format, ...); | |
83 | |
84 private: | |
85 FRIEND_TEST_ALL_PREFIXES(AssertionsTest, ScopedLogger); | |
86 using PrintFunctionPtr = void (*)(const char* format, va_list args); | |
87 static void setPrintFuncForTests(PrintFunctionPtr p) { | |
88 m_printFunc = p; | |
89 } // Note: not thread safe. | |
90 | |
91 void init(const char* format, va_list args); | |
92 void writeNewlineIfNeeded(); | |
93 void indent(); | |
94 void print(const char* format, ...); | |
95 void printIndent(); | |
96 static ScopedLogger*& current(); | |
97 | |
98 ScopedLogger* const m_parent; | |
99 bool m_multiline; // The ')' will go on the same line if there is only one | |
100 // entry. | |
101 static PrintFunctionPtr m_printFunc; | |
102 }; | |
103 | |
104 #define WTF_CREATE_SCOPED_LOGGER(name, ...) \ | |
105 WTF::ScopedLogger name(true, __VA_ARGS__) | |
106 #define WTF_CREATE_SCOPED_LOGGER_IF(name, condition, ...) \ | |
107 WTF::ScopedLogger name(condition, __VA_ARGS__) | |
108 #define WTF_APPEND_SCOPED_LOGGER(name, ...) (name.log(__VA_ARGS__)) | |
109 | |
110 #endif // LOG_DISABLED | |
111 | |
112 } // namespace WTF | |
113 | |
114 // CRASH() - Raises a fatal error resulting in program termination and | |
115 // triggering either the debugger or the crash reporter. | |
116 // | |
117 // Use CRASH() in response to known, unrecoverable errors like out-of-memory. | |
118 // Macro is enabled in both debug and release mode. | |
119 // To test for unknown errors and verify assumptions, use ASSERT instead, to | |
120 // avoid impacting performance in release builds. | |
121 #ifndef CRASH | |
122 #define CRASH() IMMEDIATE_CRASH() | |
123 #endif | |
124 | |
125 // ASSERT and ASSERT_NOT_REACHED | |
126 // These macros are compiled out of release builds. | |
127 // Expressions inside them are evaluated in debug builds only. | |
128 // They are deprecated. We should use: | |
129 // - DCHECK() for ASSERT() | |
130 // - NOTREACHED() for ASSERT_NOT_REACHED() | |
131 #if OS(WIN) | |
132 // FIXME: Change to use something other than ASSERT to avoid this conflict with | |
133 // the underlying platform. | |
134 #undef ASSERT | |
135 #endif | |
136 | |
137 #define DCHECK_AT(assertion, file, line) \ | |
138 LAZY_STREAM(logging::LogMessage(file, line, #assertion).stream(), \ | |
139 DCHECK_IS_ON() ? !(assertion) : false) | |
140 | |
141 #if DCHECK_IS_ON() | |
142 #define ASSERT(assertion) DCHECK(assertion) | |
143 #define ASSERT_NOT_REACHED() NOTREACHED() | |
144 #else | |
145 #define ASSERT(assertion) ((void)0) | |
146 #define ASSERT_NOT_REACHED() ((void)0) | |
147 #endif | |
148 | |
149 // Users must test "#if ENABLE(SECURITY_ASSERT)", which helps ensure | |
150 // that code testing this macro has included this header. | |
151 #if defined(ADDRESS_SANITIZER) || DCHECK_IS_ON() | |
152 #define ENABLE_SECURITY_ASSERT 1 | |
153 #else | |
154 #define ENABLE_SECURITY_ASSERT 0 | |
155 #endif | |
156 | |
157 // SECURITY_DCHECK and SECURITY_CHECK | |
158 // Use in places where failure of the assertion indicates a possible security | |
159 // vulnerability. Classes of these vulnerabilities include bad casts, out of | |
160 // bounds accesses, use-after-frees, etc. Please be sure to file bugs for these | |
161 // failures using the security template: | |
162 // https://bugs.chromium.org/p/chromium/issues/entry?template=Security%20Bug | |
163 #if ENABLE_SECURITY_ASSERT | |
164 #define SECURITY_DCHECK(condition) \ | |
165 LOG_IF(FATAL, !(condition)) << "Security DCHECK failed: " #condition ". " | |
166 // A SECURITY_CHECK failure is actually not vulnerable. | |
167 #define SECURITY_CHECK(condition) \ | |
168 LOG_IF(FATAL, !(condition)) << "Security CHECK failed: " #condition ". " | |
169 #else | |
170 #define SECURITY_DCHECK(condition) ((void)0) | |
171 #define SECURITY_CHECK(condition) CHECK(condition) | |
172 #endif | |
173 | |
174 // RELEASE_ASSERT | |
175 // Use in places where failure of an assertion indicates a definite security | |
176 // vulnerability from which execution must not continue even in a release build. | |
177 // Please sure to file bugs for these failures using the security template: | |
178 // http://code.google.com/p/chromium/issues/entry?template=Security%20Bug | |
179 #if defined(ADDRESS_SANITIZER) | |
180 #define RELEASE_ASSERT(condition) SECURITY_CHECK(condition) | |
181 #else | |
182 #define RELEASE_ASSERT(condition) CHECK(condition) | |
183 #endif | |
184 | |
185 // DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES | |
186 // Allow equality comparisons of Objects by reference or pointer, | |
187 // interchangeably. This can be only used on types whose equality makes no | |
188 // other sense than pointer equality. | |
189 #define DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(thisType) \ | |
190 inline bool operator==(const thisType& a, const thisType& b) { \ | |
191 return &a == &b; \ | |
192 } \ | |
193 inline bool operator==(const thisType& a, const thisType* b) { \ | |
194 return &a == b; \ | |
195 } \ | |
196 inline bool operator==(const thisType* a, const thisType& b) { \ | |
197 return a == &b; \ | |
198 } \ | |
199 inline bool operator!=(const thisType& a, const thisType& b) { \ | |
200 return !(a == b); \ | |
201 } \ | |
202 inline bool operator!=(const thisType& a, const thisType* b) { \ | |
203 return !(a == b); \ | |
204 } \ | |
205 inline bool operator!=(const thisType* a, const thisType& b) { \ | |
206 return !(a == b); \ | |
207 } | |
208 | |
209 // DEFINE_TYPE_CASTS | |
210 // | |
211 // toType() functions are static_cast<> wrappers with SECURITY_DCHECK. It's | |
212 // helpful to find bad casts. | |
213 // | |
214 // toTypeOrDie() has a runtime type check, and it crashes if the specified | |
215 // object is not an instance of the destination type. It is used if | |
216 // * it's hard to prevent from passing unexpected objects, | |
217 // * proceeding with the following code doesn't make sense, and | |
218 // * cost of runtime type check is acceptable. | |
219 #define DEFINE_TYPE_CASTS(thisType, argumentType, argument, pointerPredicate, \ | |
220 referencePredicate) \ | |
221 inline thisType* to##thisType(argumentType* argument) { \ | |
222 SECURITY_DCHECK(!argument || (pointerPredicate)); \ | |
223 return static_cast<thisType*>(argument); \ | |
224 } \ | |
225 inline const thisType* to##thisType(const argumentType* argument) { \ | |
226 SECURITY_DCHECK(!argument || (pointerPredicate)); \ | |
227 return static_cast<const thisType*>(argument); \ | |
228 } \ | |
229 inline thisType& to##thisType(argumentType& argument) { \ | |
230 SECURITY_DCHECK(referencePredicate); \ | |
231 return static_cast<thisType&>(argument); \ | |
232 } \ | |
233 inline const thisType& to##thisType(const argumentType& argument) { \ | |
234 SECURITY_DCHECK(referencePredicate); \ | |
235 return static_cast<const thisType&>(argument); \ | |
236 } \ | |
237 void to##thisType(const thisType*); \ | |
238 void to##thisType(const thisType&); \ | |
239 inline thisType* to##thisType##OrDie(argumentType* argument) { \ | |
240 CHECK(!argument || (pointerPredicate)); \ | |
241 return static_cast<thisType*>(argument); \ | |
242 } \ | |
243 inline const thisType* to##thisType##OrDie(const argumentType* argument) { \ | |
244 CHECK(!argument || (pointerPredicate)); \ | |
245 return static_cast<const thisType*>(argument); \ | |
246 } \ | |
247 inline thisType& to##thisType##OrDie(argumentType& argument) { \ | |
248 CHECK(referencePredicate); \ | |
249 return static_cast<thisType&>(argument); \ | |
250 } \ | |
251 inline const thisType& to##thisType##OrDie(const argumentType& argument) { \ | |
252 CHECK(referencePredicate); \ | |
253 return static_cast<const thisType&>(argument); \ | |
254 } \ | |
255 void to##thisType##OrDie(const thisType*); \ | |
256 void to##thisType##OrDie(const thisType&) | |
257 | |
258 #endif // WTF_Assertions_h | |
OLD | NEW |