Assertions.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef WTF_Assertions_h
  26. #define WTF_Assertions_h
  27. /*
  28. no namespaces because this file has to be includable from C and Objective-C
  29. Note, this file uses many GCC extensions, but it should be compatible with
  30. C, Objective C, C++, and Objective C++.
  31. For non-debug builds, everything is disabled by default.
  32. Defining any of the symbols explicitly prevents this from having any effect.
  33. */
  34. #include <wtf/Platform.h>
  35. #include <stddef.h>
  36. #if !COMPILER(MSVC)
  37. #include <inttypes.h>
  38. #endif
  39. #ifdef NDEBUG
  40. /* Disable ASSERT* macros in release mode. */
  41. #define ASSERTIONS_DISABLED_DEFAULT 1
  42. #else
  43. #define ASSERTIONS_DISABLED_DEFAULT 0
  44. #endif
  45. #ifndef BACKTRACE_DISABLED
  46. #define BACKTRACE_DISABLED ASSERTIONS_DISABLED_DEFAULT
  47. #endif
  48. #ifndef ASSERT_DISABLED
  49. #define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT
  50. #endif
  51. #ifndef ASSERT_MSG_DISABLED
  52. #define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT
  53. #endif
  54. #ifndef ASSERT_ARG_DISABLED
  55. #define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT
  56. #endif
  57. #ifndef FATAL_DISABLED
  58. #define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT
  59. #endif
  60. #ifndef ERROR_DISABLED
  61. #define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT
  62. #endif
  63. #ifndef LOG_DISABLED
  64. #define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT
  65. #endif
  66. #if COMPILER(GCC)
  67. #define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__
  68. #else
  69. #define WTF_PRETTY_FUNCTION __FUNCTION__
  70. #endif
  71. /* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute
  72. emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include
  73. the attribute when being used from Objective-C code in case it decides to use %@. */
  74. #if COMPILER(GCC) && !defined(__OBJC__)
  75. #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments)))
  76. #else
  77. #define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments)
  78. #endif
  79. /* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */
  80. #ifdef __cplusplus
  81. extern "C" {
  82. #endif
  83. typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState;
  84. typedef struct {
  85. unsigned mask;
  86. const char *defaultName;
  87. WTFLogChannelState state;
  88. } WTFLogChannel;
  89. WTF_EXPORT_PRIVATE void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion);
  90. WTF_EXPORT_PRIVATE void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
  91. WTF_EXPORT_PRIVATE void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion);
  92. WTF_EXPORT_PRIVATE void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
  93. WTF_EXPORT_PRIVATE void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5);
  94. WTF_EXPORT_PRIVATE void WTFLog(WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
  95. WTF_EXPORT_PRIVATE void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel*, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6);
  96. WTF_EXPORT_PRIVATE void WTFLogAlways(const char* format, ...) WTF_ATTRIBUTE_PRINTF(1, 2);
  97. WTF_EXPORT_PRIVATE void WTFGetBacktrace(void** stack, int* size);
  98. WTF_EXPORT_PRIVATE void WTFReportBacktrace();
  99. WTF_EXPORT_PRIVATE void WTFPrintBacktrace(void** stack, int size);
  100. typedef void (*WTFCrashHookFunction)();
  101. WTF_EXPORT_PRIVATE void WTFSetCrashHook(WTFCrashHookFunction);
  102. WTF_EXPORT_PRIVATE void WTFInstallReportBacktraceOnCrashHook();
  103. // Exist for binary compatibility with older Safari. Do not use.
  104. WTF_EXPORT_PRIVATE void WTFInvokeCrashHook();
  105. #ifdef __cplusplus
  106. }
  107. #endif
  108. /* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter.
  109. Use CRASH() in response to known, unrecoverable errors like out-of-memory.
  110. Macro is enabled in both debug and release mode.
  111. To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds.
  112. Signals are ignored by the crash reporter on OS X so we must do better.
  113. */
  114. #if COMPILER(CLANG)
  115. #define NO_RETURN_DUE_TO_CRASH NO_RETURN
  116. #else
  117. #define NO_RETURN_DUE_TO_CRASH
  118. #endif
  119. #ifndef CRASH
  120. #define CRASH() WTFCrash()
  121. #endif
  122. #ifdef __cplusplus
  123. extern "C" {
  124. #endif
  125. WTF_EXPORT_PRIVATE void WTFCrash() NO_RETURN_DUE_TO_CRASH;
  126. #ifdef __cplusplus
  127. }
  128. #endif
  129. /* BACKTRACE
  130. Print a backtrace to the same location as ASSERT messages.
  131. */
  132. #if BACKTRACE_DISABLED
  133. #define BACKTRACE() ((void)0)
  134. #else
  135. #define BACKTRACE() do { \
  136. WTFReportBacktrace(); \
  137. } while(false)
  138. #endif
  139. /* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED
  140. These macros are compiled out of release builds.
  141. Expressions inside them are evaluated in debug builds only.
  142. */
  143. #if OS(WINCE)
  144. /* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */
  145. #include <windows.h>
  146. #undef min
  147. #undef max
  148. #undef ERROR
  149. #endif
  150. #if OS(WINDOWS)
  151. /* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */
  152. #undef ASSERT
  153. #endif
  154. #if ASSERT_DISABLED
  155. #define ASSERT(assertion) ((void)0)
  156. #define ASSERT_AT(assertion, file, line, function) ((void)0)
  157. #define ASSERT_NOT_REACHED() ((void)0)
  158. #define NO_RETURN_DUE_TO_ASSERT
  159. #if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
  160. template<typename T>
  161. inline void assertUnused(T& x) { (void)x; }
  162. #define ASSERT_UNUSED(variable, assertion) (assertUnused(variable))
  163. #else
  164. #define ASSERT_UNUSED(variable, assertion) ((void)variable)
  165. #endif
  166. #else
  167. #define ASSERT(assertion) \
  168. (!(assertion) ? \
  169. (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
  170. CRASH()) : \
  171. (void)0)
  172. #define ASSERT_AT(assertion, file, line, function) \
  173. (!(assertion) ? \
  174. (WTFReportAssertionFailure(file, line, function, #assertion), \
  175. CRASH()) : \
  176. (void)0)
  177. #define ASSERT_NOT_REACHED() do { \
  178. WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \
  179. CRASH(); \
  180. } while (0)
  181. #define ASSERT_UNUSED(variable, assertion) ASSERT(assertion)
  182. #define NO_RETURN_DUE_TO_ASSERT NO_RETURN_DUE_TO_CRASH
  183. #endif
  184. /* ASSERT_WITH_SECURITY_IMPLICATION
  185. Failure of this assertion indicates a possible security vulnerability.
  186. Class of vulnerabilities that it tests include bad casts, out of bounds
  187. accesses, use-after-frees, etc. Please file a bug using the security
  188. template - https://bugs.webkit.org/enter_bug.cgi?product=Security.
  189. */
  190. #ifdef ADDRESS_SANITIZER
  191. #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) \
  192. (!(assertion) ? \
  193. (WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion), \
  194. CRASH()) : \
  195. (void)0)
  196. #else
  197. #define ASSERT_WITH_SECURITY_IMPLICATION(assertion) ASSERT(assertion)
  198. #endif
  199. /* ASSERT_WITH_MESSAGE */
  200. #if ASSERT_MSG_DISABLED
  201. #define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0)
  202. #else
  203. #define ASSERT_WITH_MESSAGE(assertion, ...) do \
  204. if (!(assertion)) { \
  205. WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
  206. CRASH(); \
  207. } \
  208. while (0)
  209. #endif
  210. /* ASSERT_WITH_MESSAGE_UNUSED */
  211. #if ASSERT_MSG_DISABLED
  212. #if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT)
  213. template<typename T>
  214. inline void assertWithMessageUnused(T& x) { (void)x; }
  215. #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) (assertWithMessageUnused(variable))
  216. #else
  217. #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) ((void)variable)
  218. #endif
  219. #else
  220. #define ASSERT_WITH_MESSAGE_UNUSED(variable, assertion, ...) do \
  221. if (!(assertion)) { \
  222. WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \
  223. CRASH(); \
  224. } \
  225. while (0)
  226. #endif
  227. /* ASSERT_ARG */
  228. #if ASSERT_ARG_DISABLED
  229. #define ASSERT_ARG(argName, assertion) ((void)0)
  230. #else
  231. #define ASSERT_ARG(argName, assertion) do \
  232. if (!(assertion)) { \
  233. WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \
  234. CRASH(); \
  235. } \
  236. while (0)
  237. #endif
  238. /* COMPILE_ASSERT */
  239. #ifndef COMPILE_ASSERT
  240. #if COMPILER_SUPPORTS(C_STATIC_ASSERT)
  241. /* Unlike static_assert below, this also works in plain C code. */
  242. #define COMPILE_ASSERT(exp, name) _Static_assert((exp), #name)
  243. #elif COMPILER_SUPPORTS(CXX_STATIC_ASSERT)
  244. #define COMPILE_ASSERT(exp, name) static_assert((exp), #name)
  245. #else
  246. #define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1]
  247. #endif
  248. #endif
  249. /* FATAL */
  250. #if FATAL_DISABLED
  251. #define FATAL(...) ((void)0)
  252. #else
  253. #define FATAL(...) do { \
  254. WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \
  255. CRASH(); \
  256. } while (0)
  257. #endif
  258. /* LOG_ERROR */
  259. #if ERROR_DISABLED
  260. #define LOG_ERROR(...) ((void)0)
  261. #else
  262. #define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__)
  263. #endif
  264. /* LOG */
  265. #if LOG_DISABLED
  266. #define LOG(channel, ...) ((void)0)
  267. #else
  268. #define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
  269. #define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel)
  270. #define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel
  271. #endif
  272. /* LOG_VERBOSE */
  273. #if LOG_DISABLED
  274. #define LOG_VERBOSE(channel, ...) ((void)0)
  275. #else
  276. #define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__)
  277. #endif
  278. /* UNREACHABLE_FOR_PLATFORM */
  279. #if COMPILER(CLANG)
  280. // This would be a macro except that its use of #pragma works best around
  281. // a function. Hence it uses macro naming convention.
  282. #pragma clang diagnostic push
  283. #pragma clang diagnostic ignored "-Wmissing-noreturn"
  284. static inline void UNREACHABLE_FOR_PLATFORM()
  285. {
  286. ASSERT_NOT_REACHED();
  287. }
  288. #pragma clang diagnostic pop
  289. #else
  290. #define UNREACHABLE_FOR_PLATFORM() ASSERT_NOT_REACHED()
  291. #endif
  292. #if ASSERT_DISABLED
  293. #define RELEASE_ASSERT(assertion) (UNLIKELY(!(assertion)) ? (CRASH()) : (void)0)
  294. #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) RELEASE_ASSERT(assertion)
  295. #define RELEASE_ASSERT_NOT_REACHED() CRASH()
  296. #else
  297. #define RELEASE_ASSERT(assertion) ASSERT(assertion)
  298. #define RELEASE_ASSERT_WITH_MESSAGE(assertion, ...) ASSERT_WITH_MESSAGE(assertion, __VA_ARGS__)
  299. #define RELEASE_ASSERT_NOT_REACHED() ASSERT_NOT_REACHED()
  300. #endif
  301. #endif /* WTF_Assertions_h */