Do not require logging support for BT_[CTF_]ASSERT_PRE()
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Wed, 26 Jun 2019 18:39:42 +0000 (14:39 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 27 Jun 2019 01:39:06 +0000 (21:39 -0400)
This patch makes the BT_ASSERT_PRE(), BT_ASSERT_PRE_MSG(),
BT_CTF_ASSERT_PRE(), and BT_CTF_ASSERT_PRE_MSG() not use BT_LIB_LOGF()
and BT_LOGF() directly to not rely on the active log level to print the
messages.

This makes it possible to configure the build with
`BABELTRACE_DEV_MODE=1` and `BABELTRACE_MINIMAL_LOG_LEVEL=NONE` and
still get the precondition failure messages. This removes some code
in `configure.ac` and `src/lib/logging.c` which ensured that the log
level could not be NONE when developer mode is enabled.

The macros now use _bt_log_write_d() (which does not check the active
log level) and bt_lib_log() (which uses _bt_log_write_d() without
checking the active log level) instead of BT_LOGF() and BT_LIB_LOGF().

The `assert-pre.h` header still require that you include
`"lib/logging.h"` or `"logging/log.h"` before because this is where the
logging tag and logging functions are found.

Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Change-Id: If98a1c074d211cf257742d55960b379bbe9c6cf0
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1546
Tested-by: jenkins <jenkins@lttng.org>
configure.ac
src/ctf-writer/assert-pre.h
src/lib/assert-pre.h
src/lib/logging.c

index c265be674393e9202eb46320f010ba3675e0558b..b88bcbb75d1cd6af7a2a7ccb6bb1766e7b3d1044 100644 (file)
@@ -402,9 +402,6 @@ AC_DEFINE_UNQUOTED([BT_LOG_LEVEL], [BT_LOG_$BABELTRACE_MINIMAL_LOG_LEVEL], [Mini
 # BABELTRACE_DEV_MODE:
 AC_ARG_VAR([BABELTRACE_DEV_MODE], [Set to 1 to enable the Babeltrace developer mode (enables run-time checks for plugin developers)])
 AS_IF([test "x$BABELTRACE_DEV_MODE" = x1], [
-       AS_IF([test "x$BABELTRACE_MINIMAL_LOG_LEVEL" = "xNONE"], [
-               AC_MSG_ERROR([Babeltrace developer mode (\$BABELTRACE_DEV_MODE) needs \$BABELTRACE_MINIMAL_LOG_LEVEL to be at least FATAL.])
-       ])
        AC_DEFINE([BT_DEV_MODE], 1, [Babeltrace developer mode])
 ], [BABELTRACE_DEV_MODE=0])
 
index 5444760d77d7bf994c09e0d2c1b234368a126977..c0a24614c10d90905b6fef7c85b6d77513e401e7 100644 (file)
 #include "common/macros.h"
 
 #ifdef BT_DEV_MODE
+/*
+ * Prints the details of an unsatisfied precondition without immediately
+ * aborting. You should use this within a function which checks
+ * preconditions, but which is called from a BT_CTF_ASSERT_PRE()
+ * context, so that the function can still return its result for
+ * BT_CTF_ASSERT_PRE() to evaluate it.
+ *
+ * Example:
+ *
+ *     BT_CTF_ASSERT_PRE_FUNC
+ *     static inline bool check_complex_precond(...)
+ *     {
+ *         ...
+ *
+ *         if (...) {
+ *             BT_CTF_ASSERT_PRE_MSG("Invalid object: ...", ...);
+ *             return false;
+ *         }
+ *
+ *         ...
+ *     }
+ *
+ *     ...
+ *
+ *     BT_CTF_ASSERT_PRE(check_complex_precond(...),
+ *                   "Precondition is not satisfied: ...", ...);
+ */
+# define BT_CTF_ASSERT_PRE_MSG(_fmt, ...)                              \
+       do {                                                            \
+               _bt_log_write_d(_BT_LOG_SRCLOC_FUNCTION, __FILE__,      \
+                       __LINE__, BT_LOG_FATAL, BT_LOG_TAG, (_fmt),     \
+                       ##__VA_ARGS__);                                 \
+       } while (0)
+
 /*
  * Asserts that the library precondition _cond is satisfied.
  *
@@ -56,9 +90,9 @@
 # define BT_CTF_ASSERT_PRE(_cond, _fmt, ...)                           \
        do {                                                            \
                if (!(_cond)) {                                         \
-                       BT_LOGF_STR("Library precondition not satisfied; error is:"); \
-                       BT_LOGF((_fmt), ##__VA_ARGS__);         \
-                       BT_LOGF_STR("Aborting...");                     \
+                       BT_CTF_ASSERT_PRE_MSG("CTF writer precondition not satisfied; error is:"); \
+                       BT_CTF_ASSERT_PRE_MSG((_fmt), ##__VA_ARGS__);   \
+                       BT_CTF_ASSERT_PRE_MSG("Aborting...");           \
                        abort();                                        \
                }                                                       \
        } while (0)
  *     BT_CTF_ASSERT_PRE(check_complex_precond(...),
  *                   "Precondition is not satisfied: ...", ...);
  */
-# define BT_CTF_ASSERT_PRE_MSG BT_LOGF
 #else
 # define BT_CTF_ASSERT_PRE(_cond, _fmt, ...)   ((void) sizeof((void) (_cond), 0))
 # define BT_CTF_ASSERT_PRE_FUNC        __attribute__((unused))
index 1f4240eb8e8205cf7af555b6f5fc72a24f4f09af..48fe9598f4c83f107a83c145426114e504b143d0 100644 (file)
 #include "common/macros.h"
 
 #ifdef BT_DEV_MODE
-/*
- * Asserts that the library precondition _cond is satisfied.
- *
- * If _cond is false, log a fatal statement using _fmt and the optional
- * arguments using BT_LIB_LOGF(), and abort.
- *
- * To assert that a postcondition is satisfied or that some internal
- * object/context/value is in the expected state, use BT_ASSERT().
- */
-# define BT_ASSERT_PRE(_cond, _fmt, ...)                               \
-       do {                                                            \
-               if (!(_cond)) {                                         \
-                       BT_LOGF_STR("Library precondition not satisfied; error is:"); \
-                       BT_LIB_LOGF((_fmt), ##__VA_ARGS__);             \
-                       BT_LOGF_STR("Aborting...");                     \
-                       abort();                                        \
-               }                                                       \
-       } while (0)
-
-/*
- * Marks a function as being only used within a BT_ASSERT_PRE() context.
- */
-# define BT_ASSERT_PRE_FUNC
-
 /*
  * Prints the details of an unsatisfied precondition without immediately
  * aborting. You should use this within a function which checks
  *     BT_ASSERT_PRE(check_complex_precond(...),
  *                   "Precondition is not satisfied: ...", ...);
  */
-# define BT_ASSERT_PRE_MSG     BT_LIB_LOGF
+# define BT_ASSERT_PRE_MSG(_fmt, ...)                                  \
+       do {                                                            \
+               bt_lib_log(_BT_LOG_SRCLOC_FUNCTION, __FILE__,           \
+                       __LINE__, BT_LOG_FATAL, BT_LOG_TAG,             \
+                       (_fmt), ##__VA_ARGS__);                         \
+       } while (0)
+
+/*
+ * Asserts that the library precondition _cond is satisfied.
+ *
+ * If `_cond` is false, log a fatal statement using `_fmt` and the
+ * optional arguments (same usage as BT_LIB_LOGF()), and abort.
+ *
+ * To assert that a postcondition is satisfied or that some internal
+ * object/context/value is in the expected state, use BT_ASSERT().
+ */
+# define BT_ASSERT_PRE(_cond, _fmt, ...)                               \
+       do {                                                            \
+               if (!(_cond)) {                                         \
+                       BT_ASSERT_PRE_MSG("Babeltrace 2 library precondition not satisfied; error is:"); \
+                       BT_ASSERT_PRE_MSG((_fmt), ##__VA_ARGS__);       \
+                       BT_ASSERT_PRE_MSG("Aborting...");               \
+                       abort();                                        \
+               }                                                       \
+       } while (0)
+
+/*
+ * Marks a function as being only used within a BT_ASSERT_PRE() context.
+ */
+# define BT_ASSERT_PRE_FUNC
 #else
 # define BT_ASSERT_PRE(_cond, _fmt, ...)       ((void) sizeof((void) (_cond), 0))
 # define BT_ASSERT_PRE_FUNC    __attribute__((unused))
index 8f3160b5ffa635abaad5a78b4a2dbeb576eb0483..64bd8ca9a3c1f4d394c9103bac0acc337146c965 100644 (file)
 #define BT_LOG_TAG "LIB/LOGGING"
 #include "lib/logging.h"
 
-#ifdef BT_DEV_MODE
-/*
- * Default log level is FATAL in developer mode because fatal logging is
- * our way to communicate an unsatisfied precondition and the details.
- */
-# define DEFAULT_LOG_LEVEL     BT_LOG_FATAL
-#else
-/*
- * In non-developer mode, use NONE by default: we don't print logging
- * statements for any executable which links with the library. The
- * executable must call bt_logging_set_global_level() or the
- * executable's user must set the `LIBBABELTRACE2_INIT_LOG_LEVEL`
- * environment variable to enable logging.
- */
-# define DEFAULT_LOG_LEVEL     BT_LOG_NONE
-#endif /* BT_DEV_MODE */
-
 /*
  * This is exported because even though the Python plugin provider is a
  * different shared object for packaging purposes, it's still considered
  * part of the library and therefore needs the library's run-time log
  * level.
+ *
+ * The default log level is NONE: we don't print logging statements for
+ * any executable which links with the library. The executable must call
+ * bt_logging_set_global_level() or the executable's user must set the
+ * `LIBBABELTRACE2_INIT_LOG_LEVEL` environment variable to enable
+ * logging.
  */
-int bt_lib_log_level = DEFAULT_LOG_LEVEL;
+int bt_lib_log_level = BT_LOG_NONE;
 
 enum bt_logging_level bt_logging_get_minimal_level(void)
 {
@@ -64,17 +53,6 @@ enum bt_logging_level bt_logging_get_global_level(void)
 
 void bt_logging_set_global_level(enum bt_logging_level log_level)
 {
-#ifdef BT_DEV_MODE
-       /*
-        * Do not allow the library's log level to fall to NONE when in
-        * developer mode because fatal logging is our way to
-        * communicate an unsatisfied precondition and the details.
-        */
-       if (log_level == BT_LOG_NONE) {
-               log_level = BT_LOG_FATAL;
-       }
-#endif
-
        bt_lib_log_level = log_level;
 }
 
This page took 0.028539 seconds and 4 git commands to generate.