xpcom/glue/nsDebug.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsDebug_h___
michael@0 7 #define nsDebug_h___
michael@0 8
michael@0 9 #include "nscore.h"
michael@0 10 #include "nsError.h"
michael@0 11
michael@0 12 #include "nsXPCOM.h"
michael@0 13 #include "mozilla/Assertions.h"
michael@0 14 #include "mozilla/Likely.h"
michael@0 15 #include <stdarg.h>
michael@0 16
michael@0 17 #ifdef DEBUG
michael@0 18 #include "prprf.h"
michael@0 19 #endif
michael@0 20
michael@0 21 /**
michael@0 22 * Warn if the given condition is true. The condition is evaluated in both
michael@0 23 * release and debug builds, and the result is an expression which can be
michael@0 24 * used in subsequent expressions, such as:
michael@0 25 *
michael@0 26 * if (NS_WARN_IF(NS_FAILED(rv))
michael@0 27 * return rv;
michael@0 28 *
michael@0 29 * This explicit warning and return is preferred to the NS_ENSURE_* macros
michael@0 30 * which hide the warning and the return control flow.
michael@0 31 *
michael@0 32 * @note This is C++-only
michael@0 33 */
michael@0 34 #ifdef __cplusplus
michael@0 35 #ifdef DEBUG
michael@0 36 inline bool NS_warn_if_impl(bool condition, const char* expr, const char* file,
michael@0 37 int32_t line)
michael@0 38 {
michael@0 39 if (MOZ_UNLIKELY(condition)) {
michael@0 40 NS_DebugBreak(NS_DEBUG_WARNING, nullptr, expr, file, line);
michael@0 41 }
michael@0 42 return condition;
michael@0 43 }
michael@0 44 #define NS_WARN_IF(condition) \
michael@0 45 NS_warn_if_impl(condition, #condition, __FILE__, __LINE__)
michael@0 46 #else
michael@0 47 #define NS_WARN_IF(condition) (bool)(condition)
michael@0 48 #endif
michael@0 49 #endif
michael@0 50
michael@0 51 /**
michael@0 52 * Abort the execution of the program if the expression evaluates to
michael@0 53 * false.
michael@0 54 *
michael@0 55 * There is no status value returned from the macro.
michael@0 56 *
michael@0 57 * Note that the non-debug version of this macro does <b>not</b>
michael@0 58 * evaluate the expression argument. Hence side effect statements
michael@0 59 * as arguments to the macro will yield improper execution in a
michael@0 60 * non-debug build. For example:
michael@0 61 *
michael@0 62 * NS_ABORT_IF_FALSE(0 == foo++, "yikes foo should be zero");
michael@0 63 *
michael@0 64 * Note also that the non-debug version of this macro does <b>not</b>
michael@0 65 * evaluate the message argument.
michael@0 66 */
michael@0 67 #ifdef DEBUG
michael@0 68 #define NS_ABORT_IF_FALSE(_expr, _msg) \
michael@0 69 do { \
michael@0 70 if (!(_expr)) { \
michael@0 71 NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_expr, __FILE__, __LINE__); \
michael@0 72 } \
michael@0 73 } while(0)
michael@0 74 #else
michael@0 75 #define NS_ABORT_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0)
michael@0 76 #endif
michael@0 77
michael@0 78 /**
michael@0 79 * Warn if a given condition is false.
michael@0 80 *
michael@0 81 * Program execution continues past the usage of this macro.
michael@0 82 *
michael@0 83 * Note also that the non-debug version of this macro does <b>not</b>
michael@0 84 * evaluate the message argument.
michael@0 85 */
michael@0 86 #ifdef DEBUG
michael@0 87 #define NS_WARN_IF_FALSE(_expr,_msg) \
michael@0 88 do { \
michael@0 89 if (!(_expr)) { \
michael@0 90 NS_DebugBreak(NS_DEBUG_WARNING, _msg, #_expr, __FILE__, __LINE__); \
michael@0 91 } \
michael@0 92 } while(0)
michael@0 93 #else
michael@0 94 #define NS_WARN_IF_FALSE(_expr, _msg) do { /* nothing */ } while(0)
michael@0 95 #endif
michael@0 96
michael@0 97
michael@0 98 /**
michael@0 99 * Test an assertion for truth. If the expression is not true then
michael@0 100 * trigger a program failure.
michael@0 101 *
michael@0 102 * Note that the non-debug version of this macro does <b>not</b>
michael@0 103 * evaluate the message argument.
michael@0 104 */
michael@0 105 #ifdef DEBUG
michael@0 106 #define NS_ASSERTION(expr, str) \
michael@0 107 do { \
michael@0 108 if (!(expr)) { \
michael@0 109 NS_DebugBreak(NS_DEBUG_ASSERTION, str, #expr, __FILE__, __LINE__); \
michael@0 110 } \
michael@0 111 } while(0)
michael@0 112 #else
michael@0 113 #define NS_ASSERTION(expr, str) do { /* nothing */ } while(0)
michael@0 114 #endif
michael@0 115
michael@0 116 /**
michael@0 117 * NS_PRECONDITION/POSTCONDITION are synonyms for NS_ASSERTION.
michael@0 118 */
michael@0 119 #define NS_PRECONDITION(expr, str) NS_ASSERTION(expr, str)
michael@0 120 #define NS_POSTCONDITION(expr, str) NS_ASSERTION(expr, str)
michael@0 121
michael@0 122 /**
michael@0 123 * This macros triggers a program failure if executed. It indicates that
michael@0 124 * an attempt was made to execute some unimplemented functionality.
michael@0 125 */
michael@0 126 #ifdef DEBUG
michael@0 127 #define NS_NOTYETIMPLEMENTED(str) \
michael@0 128 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "NotYetImplemented", __FILE__, __LINE__)
michael@0 129 #else
michael@0 130 #define NS_NOTYETIMPLEMENTED(str) do { /* nothing */ } while(0)
michael@0 131 #endif
michael@0 132
michael@0 133 /**
michael@0 134 * This macros triggers a program failure if executed. It indicates that
michael@0 135 * an attempt was made to execute a codepath which should not be reachable.
michael@0 136 */
michael@0 137 #ifdef DEBUG
michael@0 138 #define NS_NOTREACHED(str) \
michael@0 139 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Not Reached", __FILE__, __LINE__)
michael@0 140 #else
michael@0 141 #define NS_NOTREACHED(str) do { /* nothing */ } while(0)
michael@0 142 #endif
michael@0 143
michael@0 144 /**
michael@0 145 * Log an error message.
michael@0 146 */
michael@0 147 #ifdef DEBUG
michael@0 148 #define NS_ERROR(str) \
michael@0 149 NS_DebugBreak(NS_DEBUG_ASSERTION, str, "Error", __FILE__, __LINE__)
michael@0 150 #else
michael@0 151 #define NS_ERROR(str) do { /* nothing */ } while(0)
michael@0 152 #endif
michael@0 153
michael@0 154 /**
michael@0 155 * Log a warning message.
michael@0 156 */
michael@0 157 #ifdef DEBUG
michael@0 158 #define NS_WARNING(str) \
michael@0 159 NS_DebugBreak(NS_DEBUG_WARNING, str, nullptr, __FILE__, __LINE__)
michael@0 160 #else
michael@0 161 #define NS_WARNING(str) do { /* nothing */ } while(0)
michael@0 162 #endif
michael@0 163
michael@0 164 /**
michael@0 165 * Trigger an debug-only abort.
michael@0 166 *
michael@0 167 * @see NS_RUNTIMEABORT for release-mode asserts.
michael@0 168 */
michael@0 169 #ifdef DEBUG
michael@0 170 #define NS_ABORT() \
michael@0 171 NS_DebugBreak(NS_DEBUG_ABORT, nullptr, nullptr, __FILE__, __LINE__)
michael@0 172 #else
michael@0 173 #define NS_ABORT() do { /* nothing */ } while(0)
michael@0 174 #endif
michael@0 175
michael@0 176 /**
michael@0 177 * Trigger a debugger breakpoint, only in debug builds.
michael@0 178 */
michael@0 179 #ifdef DEBUG
michael@0 180 #define NS_BREAK() \
michael@0 181 NS_DebugBreak(NS_DEBUG_BREAK, nullptr, nullptr, __FILE__, __LINE__)
michael@0 182 #else
michael@0 183 #define NS_BREAK() do { /* nothing */ } while(0)
michael@0 184 #endif
michael@0 185
michael@0 186 /******************************************************************************
michael@0 187 ** Macros for static assertions. These are used by the sixgill tool.
michael@0 188 ** When the tool is not running these macros are no-ops.
michael@0 189 ******************************************************************************/
michael@0 190
michael@0 191 /* Avoid name collision if included with other headers defining annotations. */
michael@0 192 #ifndef HAVE_STATIC_ANNOTATIONS
michael@0 193 #define HAVE_STATIC_ANNOTATIONS
michael@0 194
michael@0 195 #ifdef XGILL_PLUGIN
michael@0 196
michael@0 197 #define STATIC_PRECONDITION(COND) __attribute__((precondition(#COND)))
michael@0 198 #define STATIC_PRECONDITION_ASSUME(COND) __attribute__((precondition_assume(#COND)))
michael@0 199 #define STATIC_POSTCONDITION(COND) __attribute__((postcondition(#COND)))
michael@0 200 #define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND)))
michael@0 201 #define STATIC_INVARIANT(COND) __attribute__((invariant(#COND)))
michael@0 202 #define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND)))
michael@0 203
michael@0 204 /* Used to make identifiers for assert/assume annotations in a function. */
michael@0 205 #define STATIC_PASTE2(X,Y) X ## Y
michael@0 206 #define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y)
michael@0 207
michael@0 208 #define STATIC_ASSERT(COND) \
michael@0 209 do { \
michael@0 210 __attribute__((assert_static(#COND), unused)) \
michael@0 211 int STATIC_PASTE1(assert_static_, __COUNTER__); \
michael@0 212 } while(0)
michael@0 213
michael@0 214 #define STATIC_ASSUME(COND) \
michael@0 215 do { \
michael@0 216 __attribute__((assume_static(#COND), unused)) \
michael@0 217 int STATIC_PASTE1(assume_static_, __COUNTER__); \
michael@0 218 } while(0)
michael@0 219
michael@0 220 #define STATIC_ASSERT_RUNTIME(COND) \
michael@0 221 do { \
michael@0 222 __attribute__((assert_static_runtime(#COND), unused)) \
michael@0 223 int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \
michael@0 224 } while(0)
michael@0 225
michael@0 226 #else /* XGILL_PLUGIN */
michael@0 227
michael@0 228 #define STATIC_PRECONDITION(COND) /* nothing */
michael@0 229 #define STATIC_PRECONDITION_ASSUME(COND) /* nothing */
michael@0 230 #define STATIC_POSTCONDITION(COND) /* nothing */
michael@0 231 #define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */
michael@0 232 #define STATIC_INVARIANT(COND) /* nothing */
michael@0 233 #define STATIC_INVARIANT_ASSUME(COND) /* nothing */
michael@0 234
michael@0 235 #define STATIC_ASSERT(COND) do { /* nothing */ } while(0)
michael@0 236 #define STATIC_ASSUME(COND) do { /* nothing */ } while(0)
michael@0 237 #define STATIC_ASSERT_RUNTIME(COND) do { /* nothing */ } while(0)
michael@0 238
michael@0 239 #endif /* XGILL_PLUGIN */
michael@0 240
michael@0 241 #define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference())
michael@0 242
michael@0 243 #endif /* HAVE_STATIC_ANNOTATIONS */
michael@0 244
michael@0 245 #ifdef XGILL_PLUGIN
michael@0 246
michael@0 247 /* Redefine runtime assertion macros to perform static assertions, for both
michael@0 248 * debug and release builds. Don't include the original runtime assertions;
michael@0 249 * this ensures the tool will consider cases where the assertion fails. */
michael@0 250
michael@0 251 #undef NS_PRECONDITION
michael@0 252 #undef NS_ASSERTION
michael@0 253 #undef NS_POSTCONDITION
michael@0 254
michael@0 255 #define NS_PRECONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
michael@0 256 #define NS_ASSERTION(expr, str) STATIC_ASSERT_RUNTIME(expr)
michael@0 257 #define NS_POSTCONDITION(expr, str) STATIC_ASSERT_RUNTIME(expr)
michael@0 258
michael@0 259 #endif /* XGILL_PLUGIN */
michael@0 260
michael@0 261 /******************************************************************************
michael@0 262 ** Macros for terminating execution when an unrecoverable condition is
michael@0 263 ** reached. These need to be compiled regardless of the DEBUG flag.
michael@0 264 ******************************************************************************/
michael@0 265
michael@0 266 /**
michael@0 267 * Terminate execution <i>immediately</i>, and if possible on the current
michael@0 268 * platform, in such a way that execution can't be continued by other
michael@0 269 * code (e.g., by intercepting a signal).
michael@0 270 */
michael@0 271 #define NS_RUNTIMEABORT(msg) \
michael@0 272 NS_DebugBreak(NS_DEBUG_ABORT, msg, nullptr, __FILE__, __LINE__)
michael@0 273
michael@0 274
michael@0 275 /* Macros for checking the trueness of an expression passed in within an
michael@0 276 * interface implementation. These need to be compiled regardless of the
michael@0 277 * DEBUG flag. New code should use NS_WARN_IF(condition) instead!
michael@0 278 * @status deprecated
michael@0 279 */
michael@0 280
michael@0 281 #define NS_ENSURE_TRUE(x, ret) \
michael@0 282 do { \
michael@0 283 if (MOZ_UNLIKELY(!(x))) { \
michael@0 284 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed"); \
michael@0 285 return ret; \
michael@0 286 } \
michael@0 287 } while(0)
michael@0 288
michael@0 289 #define NS_ENSURE_FALSE(x, ret) \
michael@0 290 NS_ENSURE_TRUE(!(x), ret)
michael@0 291
michael@0 292 #define NS_ENSURE_TRUE_VOID(x) \
michael@0 293 do { \
michael@0 294 if (MOZ_UNLIKELY(!(x))) { \
michael@0 295 NS_WARNING("NS_ENSURE_TRUE(" #x ") failed"); \
michael@0 296 return; \
michael@0 297 } \
michael@0 298 } while(0)
michael@0 299
michael@0 300 #define NS_ENSURE_FALSE_VOID(x) \
michael@0 301 NS_ENSURE_TRUE_VOID(!(x))
michael@0 302
michael@0 303 /******************************************************************************
michael@0 304 ** Macros for checking results
michael@0 305 ******************************************************************************/
michael@0 306
michael@0 307 #if defined(DEBUG) && !defined(XPCOM_GLUE_AVOID_NSPR)
michael@0 308
michael@0 309 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
michael@0 310 char *msg = PR_smprintf("NS_ENSURE_SUCCESS(%s, %s) failed with " \
michael@0 311 "result 0x%X", #res, #ret, __rv); \
michael@0 312 NS_WARNING(msg); \
michael@0 313 PR_smprintf_free(msg);
michael@0 314
michael@0 315 #define NS_ENSURE_SUCCESS_BODY_VOID(res) \
michael@0 316 char *msg = PR_smprintf("NS_ENSURE_SUCCESS_VOID(%s) failed with " \
michael@0 317 "result 0x%X", #res, __rv); \
michael@0 318 NS_WARNING(msg); \
michael@0 319 PR_smprintf_free(msg);
michael@0 320
michael@0 321 #else
michael@0 322
michael@0 323 #define NS_ENSURE_SUCCESS_BODY(res, ret) \
michael@0 324 NS_WARNING("NS_ENSURE_SUCCESS(" #res ", " #ret ") failed");
michael@0 325
michael@0 326 #define NS_ENSURE_SUCCESS_BODY_VOID(res) \
michael@0 327 NS_WARNING("NS_ENSURE_SUCCESS_VOID(" #res ") failed");
michael@0 328
michael@0 329 #endif
michael@0 330
michael@0 331 #define NS_ENSURE_SUCCESS(res, ret) \
michael@0 332 do { \
michael@0 333 nsresult __rv = res; /* Don't evaluate |res| more than once */ \
michael@0 334 if (NS_FAILED(__rv)) { \
michael@0 335 NS_ENSURE_SUCCESS_BODY(res, ret) \
michael@0 336 return ret; \
michael@0 337 } \
michael@0 338 } while(0)
michael@0 339
michael@0 340 #define NS_ENSURE_SUCCESS_VOID(res) \
michael@0 341 do { \
michael@0 342 nsresult __rv = res; \
michael@0 343 if (NS_FAILED(__rv)) { \
michael@0 344 NS_ENSURE_SUCCESS_BODY_VOID(res) \
michael@0 345 return; \
michael@0 346 } \
michael@0 347 } while(0)
michael@0 348
michael@0 349 /******************************************************************************
michael@0 350 ** Macros for checking state and arguments upon entering interface boundaries
michael@0 351 ******************************************************************************/
michael@0 352
michael@0 353 #define NS_ENSURE_ARG(arg) \
michael@0 354 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_ARG)
michael@0 355
michael@0 356 #define NS_ENSURE_ARG_POINTER(arg) \
michael@0 357 NS_ENSURE_TRUE(arg, NS_ERROR_INVALID_POINTER)
michael@0 358
michael@0 359 #define NS_ENSURE_ARG_MIN(arg, min) \
michael@0 360 NS_ENSURE_TRUE((arg) >= min, NS_ERROR_INVALID_ARG)
michael@0 361
michael@0 362 #define NS_ENSURE_ARG_MAX(arg, max) \
michael@0 363 NS_ENSURE_TRUE((arg) <= max, NS_ERROR_INVALID_ARG)
michael@0 364
michael@0 365 #define NS_ENSURE_ARG_RANGE(arg, min, max) \
michael@0 366 NS_ENSURE_TRUE(((arg) >= min) && ((arg) <= max), NS_ERROR_INVALID_ARG)
michael@0 367
michael@0 368 #define NS_ENSURE_STATE(state) \
michael@0 369 NS_ENSURE_TRUE(state, NS_ERROR_UNEXPECTED)
michael@0 370
michael@0 371 #define NS_ENSURE_NO_AGGREGATION(outer) \
michael@0 372 NS_ENSURE_FALSE(outer, NS_ERROR_NO_AGGREGATION)
michael@0 373
michael@0 374 /*****************************************************************************/
michael@0 375
michael@0 376 #ifdef XPCOM_GLUE
michael@0 377 #define NS_CheckThreadSafe(owningThread, msg)
michael@0 378 #else
michael@0 379 #define NS_CheckThreadSafe(owningThread, msg) \
michael@0 380 if (MOZ_UNLIKELY(owningThread != PR_GetCurrentThread())) { \
michael@0 381 MOZ_CRASH(msg); \
michael@0 382 }
michael@0 383 #endif
michael@0 384
michael@0 385 #ifdef MOZILLA_INTERNAL_API
michael@0 386 void NS_ABORT_OOM(size_t size);
michael@0 387 #else
michael@0 388 inline void NS_ABORT_OOM(size_t)
michael@0 389 {
michael@0 390 MOZ_CRASH();
michael@0 391 }
michael@0 392 #endif
michael@0 393
michael@0 394 /* When compiling the XPCOM Glue on Windows, we pretend that it's going to
michael@0 395 * be linked with a static CRT (-MT) even when it's not. This means that we
michael@0 396 * cannot link to data exports from the CRT, only function exports. So,
michael@0 397 * instead of referencing "stderr" directly, use fdopen.
michael@0 398 */
michael@0 399 #ifdef __cplusplus
michael@0 400 extern "C" {
michael@0 401 #endif
michael@0 402
michael@0 403 NS_COM_GLUE void
michael@0 404 printf_stderr(const char *fmt, ...);
michael@0 405
michael@0 406 NS_COM_GLUE void
michael@0 407 vprintf_stderr(const char *fmt, va_list args);
michael@0 408
michael@0 409 // fprintf with special handling for stderr to print to the console
michael@0 410 NS_COM_GLUE void
michael@0 411 fprintf_stderr(FILE* aFile, const char *fmt, ...);
michael@0 412
michael@0 413 #ifdef __cplusplus
michael@0 414 }
michael@0 415 #endif
michael@0 416
michael@0 417 #endif /* nsDebug_h___ */

mercurial