1 /*
2  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 /*
8  * NaCl service runtime, check macros.
9  */
10 
11 #ifndef NATIVE_CLIENT_SRC_SHARED_PLATFORM_NACL_CHECK_H_
12 #define NATIVE_CLIENT_SRC_SHARED_PLATFORM_NACL_CHECK_H_
13 
14 #include "native_client/src/shared/platform/nacl_log.h"
15 
16 EXTERN_C_BEGIN
17 
18 /*
19  * We cannot use variadic macros since not all preprocessors provide
20  * them.  Instead, we require uses of the CHECK and DCHECK macro write
21  * code in the following manner:
22  *
23  *   CHECK(a == b);
24  *
25  * or
26  *
27  *   VCHECK(a == b, ("a = %d, b = %d, c = %s\n", a, b, some_cstr));
28  *
29  * depending on whether a printf-like, more detailed message in
30  * addition to the invariance failure should be printed.
31  *
32  * NB: BEWARE of printf arguments the evaluation of which have
33  * side-effects.  Any such will cause the program to behave
34  * differently depending on whether debug mode is enabled or not.
35  */
36 #define CHECK(bool_expr) do {                                        \
37     if (!(bool_expr)) {                                              \
38       NaClLog(LOG_FATAL, "Fatal error in file %s, line %d: !(%s)\n", \
39               __FILE__, __LINE__, #bool_expr);                       \
40     }                                                                \
41   } while (0)
42 
43 #define DCHECK(bool_expr) do {                                       \
44     if (nacl_check_debug_mode && !(bool_expr)) {                     \
45       NaClLog(LOG_FATAL, "Fatal error in file %s, line %d: !(%s)\n", \
46               __FILE__, __LINE__, #bool_expr);                       \
47     }                                                                \
48   } while (0)
49 
50 #define VCHECK(bool_expr, fn_arg) do {                               \
51     if   (!(bool_expr)) {                                            \
52       NaClLog(LOG_ERROR, "Fatal error in file %s, line %d: !(%s)\n", \
53               __FILE__, __LINE__, #bool_expr);                       \
54       NaClCheckIntern fn_arg;                                        \
55     }                                                                \
56   } while (0)
57 
58 #define DVCHECK(bool_expr, fn_arg) do {                              \
59     if (nacl_check_debug_mode && !(bool_expr)) {                     \
60       NaClLog(LOG_ERROR, "Fatal error in file %s, line %d: !(%s)\n", \
61               __FILE__, __LINE__, #bool_expr);                       \
62       NaClCheckIntern fn_arg;                                        \
63     }                                                                \
64   } while (0)
65 
66 /*
67  * By default, nacl_check_debug mode is 0 in opt builds and 1 in dbg
68  * builds, so DCHECKs are only performed for dbg builds, though it's
69  * possible to change this (viz, as directed by a command line
70  * argument) by invoking NaClCheckSetDebugMode.  CHECKs are always
71  * performed.
72  */
73 extern void NaClCheckSetDebugMode(int mode);
74 
75 /*
76  * This is a private variable, needed for the macro.  Do not reference
77  * directly.
78  */
79 extern int nacl_check_debug_mode;
80 
81 /*
82  * This is a private function, used by the macros above.  Do not
83  * reference directly.
84  */
85 extern void NaClCheckIntern(const char *fmt, ...);
86 
87 EXTERN_C_END
88 
89 #endif
90