LCOV - code coverage report
Current view: top level - xpcom/base - nsDebug.h (source / functions) Hit Total Coverage
Test: output.info Lines: 4 6 66.7 %
Date: 2017-07-14 16:53:18 Functions: 1 2 50.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13