variable `LTTNG_UST_DEBUG` when launching the user application. It
can also be enabled at build time by compiling LTTng-UST with
`-DLTTNG_UST_DEBUG`.
+ - `liblttng-ust` abort on critical can be activated by setting the
+ environment variable `LTTNG_UST_ABORT_ON_CRITICAL` when launching the user
+ application. It can also be enabled at build time by compiling LTTng-UST with
+ `-DLTTNG_UST_ABORT_ON_CRITICAL`.
- The environment variable `LTTNG_UST_REGISTER_TIMEOUT` can be used to
specify how long the applications should wait for the session
daemon _registration done_ command before proceeding to execute the
static struct lttng_env lttng_env[] = {
/*
- * LTTNG_UST_DEBUG is used directly by snprintf, because it
- * needs to be already set for ERR() used in
- * lttng_ust_getenv_init().
+ * LTTNG_UST_DEBUG and LTTNG_UST_ABORT_ON_CRITICAL are used directly by
+ * the internal logging, because they need to be already set for ERR()
+ * used in lttng_ust_getenv_init().
*/
{ "LTTNG_UST_DEBUG", LTTNG_ENV_NOT_SECURE, NULL, },
+ { "LTTNG_UST_ABORT_ON_CRITICAL", LTTNG_ENV_NOT_SECURE, NULL, },
/* Env. var. which can be used in setuid/setgid executables. */
{ "LTTNG_UST_WITHOUT_BADDR_STATEDUMP", LTTNG_ENV_NOT_SECURE, NULL, },
#include "common/logging.h"
int lttng_ust_log_level = LTTNG_UST_LOG_LEVEL_UNKNOWN;
+int lttng_ust_log_critical_action = LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN;
/*
* Initialize the global log level from the "LTTNG_UST_DEBUG" environment
* variable.
*
- * This could end up being called concurently by multiple threads but doesn't
+ * 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.
- *
- * Return the current log level to save the caller a second read of the global
- * log level.
*/
-int lttng_ust_logging_init(void)
+static
+void lttng_ust_logging_log_level_init(void)
{
char *lttng_ust_debug;
int current_log_level;
/*
* Check early if we are initialized, this is unlikely as it's already tested
- * in lttng_ust_debug_enabled before performing lazy initialization.
+ * in lttng_ust_logging_debug_enabled before performing lazy initialization.
*/
if (caa_unlikely(current_log_level != LTTNG_UST_LOG_LEVEL_UNKNOWN))
- goto end;
+ return;
/*
* This getenv is not part of lttng_ust_getenv() because logging is
/* Initialize the log level */
CMM_STORE_SHARED(lttng_ust_log_level, current_log_level);
+}
+
+/*
+ * Initialize the global log critical action from the "LTTNG_UST_ABORT_ON_CRITICAL"
+ * environment variable.
+ *
+ * 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.
+ */
+static
+void lttng_ust_logging_log_critical_action_init(void)
+{
+ char *lttng_ust_abort_on_critical;
+ int current_log_critical_action;
-end:
- return current_log_level;
+ current_log_critical_action = CMM_LOAD_SHARED(lttng_ust_log_critical_action);
+
+ /*
+ * Check early if we are initialized, this is unlikely as it's already tested
+ * in lttng_ust_logging_abort_on_critical_enabled before performing lazy initialization.
+ */
+ if (caa_unlikely(current_log_critical_action != LTTNG_UST_LOG_CRITICAL_ACTION_UNKNOWN))
+ return;
+
+ /*
+ * This getenv is not part of lttng_ust_getenv() because logging is
+ * used in the getenv initialization and thus logging must be
+ * initialized prior to getenv.
+ */
+ lttng_ust_abort_on_critical = getenv("LTTNG_UST_ABORT_ON_CRITICAL");
+
+ /*
+ * If the LTTNG_UST_ABORT_ON_CRITICAL environment variable is defined,
+ * call abort() on CRIT(), otherwise take no action.
+ */
+ if (lttng_ust_abort_on_critical)
+ current_log_critical_action = LTTNG_UST_LOG_CRITICAL_ACTION_ABORT;
+ else
+ current_log_critical_action = LTTNG_UST_LOG_CRITICAL_ACTION_NONE;
+
+ /* Initialize the log critical action */
+ CMM_STORE_SHARED(lttng_ust_log_critical_action, current_log_critical_action);
+}
+
+/*
+ * 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)
+{
+ lttng_ust_logging_log_level_init();
+ lttng_ust_logging_log_critical_action_init();
}
LTTNG_UST_LOG_LEVEL_DEBUG,
};
+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.
+ * 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.
- *
- * Return the current log level to save the caller a second read of the global
- * log level.
*/
-int lttng_ust_logging_init(void)
+void lttng_ust_logging_init(void)
__attribute__((visibility("hidden")));
#ifdef LTTNG_UST_DEBUG
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))
- current_log_level = lttng_ust_logging_init();
+ 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 true;
+}
+#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
#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))
/*