Add critical log level
[lttng-ust.git] / src / common / logging.h
index ab125e7c3dfc139d987e8a2d4192e18fe5de05cd..c98644d87c8128c3caf2debe0e841f830c82ba22 100644 (file)
@@ -16,6 +16,8 @@
 #include <stdio.h>
 
 #include <lttng/ust-utils.h>
+#include <urcu/compiler.h>
+#include <urcu/system.h>
 
 #include "common/patient.h"
 #include "common/compat/tid.h"
 
 enum lttng_ust_log_level {
        LTTNG_UST_LOG_LEVEL_UNKNOWN = 0,
-       LTTNG_UST_LOG_LEVEL_NORMAL,
+       LTTNG_UST_LOG_LEVEL_SILENT,
        LTTNG_UST_LOG_LEVEL_DEBUG,
 };
 
-extern volatile enum lttng_ust_log_level lttng_ust_log_level
+enum lttng_ust_log_critical_action {
+       LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN = 0,
+       LTTNG_UST_LOG_CRITICAL_ACTION_NONE,
+       LTTNG_UST_LOG_CRITICAL_ACTION_ABORT,
+};
+
+extern int lttng_ust_log_level                 /* enum lttng_ust_log_level */
+       __attribute__((visibility("hidden")));
+
+extern int lttng_ust_log_critical_action               /* enum lttng_ust_log_critical_action */
        __attribute__((visibility("hidden")));
 
+/*
+ * Initialize the global log level from the "LTTNG_UST_DEBUG" environment
+ * variable and the global log critical action from "LTTNG_UST_ABORT_ON_CRITICAL".
+ *
+ * This could end up being called concurrently by multiple threads but doesn't
+ * require a mutex since the input is invariant across threads and the result
+ * will be the same.
+ */
 void lttng_ust_logging_init(void)
        __attribute__((visibility("hidden")));
 
 #ifdef LTTNG_UST_DEBUG
-static inline bool lttng_ust_logging_debug_enabled(void)
+static inline
+bool lttng_ust_logging_debug_enabled(void)
 {
        return true;
 }
 #else /* #ifdef LTTNG_UST_DEBUG */
-static inline bool lttng_ust_logging_debug_enabled(void)
+static inline
+bool lttng_ust_logging_debug_enabled(void)
+{
+       int current_log_level;
+
+       current_log_level = CMM_LOAD_SHARED(lttng_ust_log_level);
+
+       /* If the global log level is unknown, lazy-initialize it. */
+       if (caa_unlikely(current_log_level == LTTNG_UST_LOG_LEVEL_UNKNOWN)) {
+               lttng_ust_logging_init();
+               current_log_level = CMM_LOAD_SHARED(lttng_ust_log_level);
+       }
+
+       return current_log_level == LTTNG_UST_LOG_LEVEL_DEBUG;
+}
+#endif /* #ifdef LTTNG_UST_DEBUG */
+
+#ifdef LTTNG_UST_ABORT_ON_CRITICAL
+static inline
+bool lttng_ust_logging_abort_on_critical_enabled(void)
 {
-       return lttng_ust_log_level == LTTNG_UST_LOG_LEVEL_DEBUG;
+       return true;
 }
-#endif /* #else #ifdef LTTNG_UST_DEBUG */
+#else /* #ifdef LTTNG_UST_ABORT_ON_CRITICAL */
+static inline
+bool lttng_ust_logging_abort_on_critical_enabled(void)
+{
+       int current_log_critical_action;
+
+       current_log_critical_action = CMM_LOAD_SHARED(lttng_ust_log_critical_action);
+
+       /* If the global log critical action is unknown, lazy-initialize it. */
+       if (caa_unlikely(current_log_critical_action == LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN)) {
+               lttng_ust_logging_init();
+               current_log_critical_action = CMM_LOAD_SHARED(lttng_ust_log_critical_action);
+       }
+
+       return current_log_critical_action == LTTNG_UST_LOG_CRITICAL_ACTION_ABORT;
+}
+#endif /* #ifdef LTTNG_UST_ABORT_ON_CRITICAL */
 
 /*
- * The default component for error messages.
+ * The default component for log statements.
  */
 #ifndef UST_COMPONENT
 #define UST_COMPONENT libust
@@ -90,7 +145,13 @@ do {                                                                        \
 #define DBG_raw(fmt, args...)  sigsafe_print_err(fmt, ## args)
 #define WARN(fmt, args...)     ERRMSG("Warning: " fmt, ## args)
 #define ERR(fmt, args...)      ERRMSG("Error: " fmt, ## args)
-#define BUG(fmt, args...)      ERRMSG("BUG: " fmt, ## args)
+#define CRIT(fmt, args...)                                             \
+       do {                                                            \
+               ERRMSG("Critical: " fmt, ## args);                      \
+               if (lttng_ust_logging_abort_on_critical_enabled()) {    \
+                       abort();                                        \
+               }                                                       \
+       } while(0)
 
 #if !defined(__GLIBC__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE))
 /*
This page took 0.024498 seconds and 4 git commands to generate.