*/
#define _LGPL_SOURCE
+#include "agent-thread.hpp"
+#include "agent.hpp"
+#include "buffer-registry.hpp"
+#include "channel.hpp"
+#include "client.hpp"
+#include "cmd.hpp"
+#include "consumer.hpp"
+#include "context.hpp"
+#include "dispatch.hpp"
+#include "event-notifier-error-accounting.hpp"
+#include "event.hpp"
+#include "fd-limit.hpp"
+#include "health-sessiond.hpp"
+#include "kernel-consumer.hpp"
+#include "kernel.hpp"
+#include "lttng-sessiond.hpp"
+#include "lttng-ust-ctl.hpp"
+#include "manage-apps.hpp"
+#include "manage-kernel.hpp"
+#include "modprobe.hpp"
+#include "notification-thread-commands.hpp"
+#include "notification-thread.hpp"
+#include "notify-apps.hpp"
+#include "register.hpp"
+#include "rotation-thread.hpp"
+#include "save.hpp"
+#include "sessiond-config.hpp"
+#include "testpoint.hpp"
+#include "thread.hpp"
+#include "timer.hpp"
+#include "ust-consumer.hpp"
+#include "ust-sigbus.hpp"
+#include "utils.hpp"
+
+#include <common/common.hpp>
+#include <common/compat/getenv.hpp>
+#include <common/compat/socket.hpp>
+#include <common/config/session-config.hpp>
+#include <common/daemonize.hpp>
+#include <common/defaults.hpp>
+#include <common/dynamic-buffer.hpp>
+#include <common/futex.hpp>
+#include <common/ini-config/ini-config.hpp>
+#include <common/kernel-consumer/kernel-consumer.hpp>
+#include <common/logging-utils.hpp>
+#include <common/path.hpp>
+#include <common/relayd/relayd.hpp>
+#include <common/utils.hpp>
+
+#include <lttng/event-internal.hpp>
+
+#include <ctype.h>
#include <getopt.h>
#include <grp.h>
+#include <inttypes.h>
#include <limits.h>
#include <paths.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <urcu/uatomic.h>
#include <unistd.h>
-#include <ctype.h>
-
-#include <common/common.h>
-#include <common/compat/socket.h>
-#include <common/compat/getenv.h>
-#include <common/defaults.h>
-#include <common/kernel-consumer/kernel-consumer.h>
-#include <common/futex.h>
-#include <common/relayd/relayd.h>
-#include <common/utils.h>
-#include <common/path.h>
-#include <common/daemonize.h>
-#include <common/config/session-config.h>
-#include <common/ini-config/ini-config.h>
-#include <common/dynamic-buffer.h>
-#include <lttng/event-internal.h>
-
-#include "lttng-sessiond.h"
-#include "buffer-registry.h"
-#include "channel.h"
-#include "cmd.h"
-#include "consumer.h"
-#include "context.h"
-#include "event.h"
-#include "event-notifier-error-accounting.h"
-#include "kernel.h"
-#include "kernel-consumer.h"
-#include "lttng-ust-ctl.h"
-#include "ust-consumer.h"
-#include "utils.h"
-#include "fd-limit.h"
-#include "health-sessiond.h"
-#include "testpoint.h"
-#include "notify-apps.h"
-#include "agent-thread.h"
-#include "save.h"
-#include "notification-thread.h"
-#include "notification-thread-commands.h"
-#include "rotation-thread.h"
-#include "agent.h"
-#include "ht-cleanup.h"
-#include "sessiond-config.h"
-#include "timer.h"
-#include "thread.h"
-#include "client.h"
-#include "dispatch.h"
-#include "register.h"
-#include "manage-apps.h"
-#include "manage-kernel.h"
-#include "modprobe.h"
-#include "ust-sigbus.h"
+#include <urcu/uatomic.h>
static const char *help_msg =
#ifdef LTTNG_EMBED_HELP
#include <lttng-sessiond.8.h>
#else
-NULL
+ nullptr
#endif
-;
+ ;
#define EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX 65535
-#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR \
- "event-notifier-error-buffer-size"
+#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "event-notifier-error-buffer-size"
#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR \
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-kernel"
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-kernel"
#define EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR \
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-userspace"
-
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_BASE_OPTION_STR "-userspace"
const char *progname;
static int lockfile_fd = -1;
/* Command line options */
static const struct option long_options[] = {
- { "client-sock", required_argument, 0, 'c' },
- { "apps-sock", required_argument, 0, 'a' },
- { "kconsumerd-cmd-sock", required_argument, 0, '\0' },
- { "kconsumerd-err-sock", required_argument, 0, '\0' },
- { "ustconsumerd32-cmd-sock", required_argument, 0, '\0' },
- { "ustconsumerd32-err-sock", required_argument, 0, '\0' },
- { "ustconsumerd64-cmd-sock", required_argument, 0, '\0' },
- { "ustconsumerd64-err-sock", required_argument, 0, '\0' },
- { "consumerd32-path", required_argument, 0, '\0' },
- { "consumerd32-libdir", required_argument, 0, '\0' },
- { "consumerd64-path", required_argument, 0, '\0' },
- { "consumerd64-libdir", required_argument, 0, '\0' },
- { "daemonize", no_argument, 0, 'd' },
- { "background", no_argument, 0, 'b' },
- { "sig-parent", no_argument, 0, 'S' },
- { "help", no_argument, 0, 'h' },
- { "group", required_argument, 0, 'g' },
- { "version", no_argument, 0, 'V' },
- { "quiet", no_argument, 0, 'q' },
- { "verbose", no_argument, 0, 'v' },
- { "verbose-consumer", no_argument, 0, '\0' },
- { "no-kernel", no_argument, 0, '\0' },
- { "pidfile", required_argument, 0, 'p' },
- { "agent-tcp-port", required_argument, 0, '\0' },
- { "config", required_argument, 0, 'f' },
- { "load", required_argument, 0, 'l' },
- { "kmod-probes", required_argument, 0, '\0' },
- { "extra-kmod-probes", required_argument, 0, '\0' },
- { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, required_argument, 0, '\0' },
- { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, required_argument, 0, '\0' },
- { NULL, 0, 0, 0 }
+ { "client-sock", required_argument, nullptr, 'c' },
+ { "apps-sock", required_argument, nullptr, 'a' },
+ { "kconsumerd-cmd-sock", required_argument, nullptr, '\0' },
+ { "kconsumerd-err-sock", required_argument, nullptr, '\0' },
+ { "ustconsumerd32-cmd-sock", required_argument, nullptr, '\0' },
+ { "ustconsumerd32-err-sock", required_argument, nullptr, '\0' },
+ { "ustconsumerd64-cmd-sock", required_argument, nullptr, '\0' },
+ { "ustconsumerd64-err-sock", required_argument, nullptr, '\0' },
+ { "consumerd32-path", required_argument, nullptr, '\0' },
+ { "consumerd32-libdir", required_argument, nullptr, '\0' },
+ { "consumerd64-path", required_argument, nullptr, '\0' },
+ { "consumerd64-libdir", required_argument, nullptr, '\0' },
+ { "daemonize", no_argument, nullptr, 'd' },
+ { "background", no_argument, nullptr, 'b' },
+ { "sig-parent", no_argument, nullptr, 'S' },
+ { "help", no_argument, nullptr, 'h' },
+ { "group", required_argument, nullptr, 'g' },
+ { "version", no_argument, nullptr, 'V' },
+ { "quiet", no_argument, nullptr, 'q' },
+ { "verbose", no_argument, nullptr, 'v' },
+ { "verbose-consumer", no_argument, nullptr, '\0' },
+ { "no-kernel", no_argument, nullptr, '\0' },
+ { "pidfile", required_argument, nullptr, 'p' },
+ { "agent-tcp-port", required_argument, nullptr, '\0' },
+ { "config", required_argument, nullptr, 'f' },
+ { "load", required_argument, nullptr, 'l' },
+ { "kmod-probes", required_argument, nullptr, '\0' },
+ { "extra-kmod-probes", required_argument, nullptr, '\0' },
+ { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, required_argument, nullptr, '\0' },
+ { EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, required_argument, nullptr, '\0' },
+ { nullptr, 0, nullptr, 0 }
};
/* Command line options to ignore from configuration file */
/*
* Section name to look for in the daemon configuration file.
*/
-static const char * const config_section_name = "sessiond";
+static const char *const config_section_name = "sessiond";
/* Am I root or not. Set to 1 if the daemon is running as root */
static int is_root;
/*
- * Stop all threads by closing the thread quit pipe.
+ * Notify the main thread to initiate the teardown of the worker threads by
+ * writing to the main quit pipe.
*/
-static void stop_threads(void)
+static void notify_main_quit_pipe()
{
int ret;
/* Stopping all threads */
- DBG("Terminating all threads");
- ret = sessiond_notify_quit_pipe();
+ DBG("Notify the main thread to terminate all worker threads");
+ ret = sessiond_notify_main_quit_pipe();
if (ret < 0) {
- ERR("write error on thread quit pipe");
+ ERR("write error on main quit pipe");
}
}
/*
* Close every consumer sockets.
*/
-static void close_consumer_sockets(void)
+static void close_consumer_sockets()
{
int ret;
return;
}
- DBG("Waiting for complete teardown of consumerd (PID: %d)",
- consumer_data->pid);
+ DBG("Waiting for complete teardown of consumerd (PID: %d)", consumer_data->pid);
ret = waitpid(consumer_data->pid, &status, 0);
if (ret == -1) {
PERROR("consumerd waitpid pid: %d", consumer_data->pid)
- } else if (!WIFEXITED(status)) {
- ERR("consumerd termination with error: %d",
- WEXITSTATUS(ret));
+ } else if (!WIFEXITED(status)) {
+ ERR("consumerd termination with error: %d", WEXITSTATUS(ret));
}
consumer_data->pid = 0;
}
/*
* Cleanup the session daemon's data structures.
*/
-static void sessiond_cleanup(void)
+static void sessiond_cleanup()
{
int ret;
struct ltt_session_list *session_list = session_get_list();
DBG("Cleanup sessiond");
/*
- * Close the thread quit pipe. It has already done its job,
- * since we are now called.
+ * Close the main quit pipe. It has already done its job, since we are
+ * now cleaning up.
*/
- sessiond_close_quit_pipe();
+ sessiond_close_main_quit_pipe();
+
+ /* Close all other pipes. */
utils_close_pipe(apps_cmd_pipe);
utils_close_pipe(apps_cmd_notify_pipe);
utils_close_pipe(the_kernel_poll_pipe);
PERROR("remove pidfile %s", the_config.pid_file_path.value);
}
- DBG("Removing sessiond and consumerd content of directory %s",
- the_config.rundir.value);
+ DBG("Removing sessiond and consumerd content of directory %s", the_config.rundir.value);
/* sessiond */
DBG("Removing %s", the_config.pid_file_path.value);
/*
* Cleanup the daemon's option data structures.
*/
-static void sessiond_cleanup_options(void)
+static void sessiond_cleanup_options()
{
DBG("Cleaning up options");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-c, --client-sock");
+ "-c, --client-sock");
} else {
- config_string_set(&the_config.client_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.client_unix_sock_path, strdup(arg));
if (!the_config.client_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-a, --apps-sock");
+ "-a, --apps-sock");
} else {
- config_string_set(&the_config.apps_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.apps_unix_sock_path, strdup(arg));
if (!the_config.apps_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-g, --group");
+ "-g, --group");
} else {
- config_string_set(&the_config.tracing_group_name,
- strdup(arg));
+ config_string_set(&the_config.tracing_group_name, strdup(arg));
if (!the_config.tracing_group_name.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--kconsumerd-err-sock");
+ "--kconsumerd-err-sock");
} else {
- config_string_set(
- &the_config.kconsumerd_err_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.kconsumerd_err_unix_sock_path, strdup(arg));
if (!the_config.kconsumerd_err_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--kconsumerd-cmd-sock");
+ "--kconsumerd-cmd-sock");
} else {
- config_string_set(
- &the_config.kconsumerd_cmd_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.kconsumerd_cmd_unix_sock_path, strdup(arg));
if (!the_config.kconsumerd_cmd_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--ustconsumerd64-err-sock");
+ "--ustconsumerd64-err-sock");
} else {
- config_string_set(
- &the_config.consumerd64_err_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd64_err_unix_sock_path, strdup(arg));
if (!the_config.consumerd64_err_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--ustconsumerd64-cmd-sock");
+ "--ustconsumerd64-cmd-sock");
} else {
- config_string_set(
- &the_config.consumerd64_cmd_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd64_cmd_unix_sock_path, strdup(arg));
if (!the_config.consumerd64_cmd_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--ustconsumerd32-err-sock");
+ "--ustconsumerd32-err-sock");
} else {
- config_string_set(
- &the_config.consumerd32_err_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd32_err_unix_sock_path, strdup(arg));
if (!the_config.consumerd32_err_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--ustconsumerd32-cmd-sock");
+ "--ustconsumerd32-cmd-sock");
} else {
- config_string_set(
- &the_config.consumerd32_cmd_unix_sock_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd32_cmd_unix_sock_path, strdup(arg));
if (!the_config.consumerd32_cmd_unix_sock_path.value) {
ret = -ENOMEM;
PERROR("strdup");
}
/* Clamp value to [0, 3] */
the_config.verbose = the_config.verbose < 0 ?
- 0 :
- (the_config.verbose <= 3 ? the_config.verbose :
- 3);
+ 0 :
+ (the_config.verbose <= 3 ? the_config.verbose : 3);
} else if (string_match(optname, "verbose-consumer")) {
if (arg) {
the_config.verbose_consumer = config_parse_value(arg);
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--consumerd32-path");
+ "--consumerd32-path");
} else {
- config_string_set(&the_config.consumerd32_bin_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd32_bin_path, strdup(arg));
if (!the_config.consumerd32_bin_path.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--consumerd32-libdir");
+ "--consumerd32-libdir");
} else {
- config_string_set(&the_config.consumerd32_lib_dir,
- strdup(arg));
+ config_string_set(&the_config.consumerd32_lib_dir, strdup(arg));
if (!the_config.consumerd32_lib_dir.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--consumerd64-path");
+ "--consumerd64-path");
} else {
- config_string_set(&the_config.consumerd64_bin_path,
- strdup(arg));
+ config_string_set(&the_config.consumerd64_bin_path, strdup(arg));
if (!the_config.consumerd64_bin_path.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--consumerd64-libdir");
+ "--consumerd64-libdir");
} else {
- config_string_set(&the_config.consumerd64_lib_dir,
- strdup(arg));
+ config_string_set(&the_config.consumerd64_lib_dir, strdup(arg));
if (!the_config.consumerd64_lib_dir.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-p, --pidfile");
+ "-p, --pidfile");
} else {
- config_string_set(
- &the_config.pid_file_path, strdup(arg));
+ config_string_set(&the_config.pid_file_path, strdup(arg));
if (!the_config.pid_file_path.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--agent-tcp-port");
+ "--agent-tcp-port");
} else {
unsigned long v;
errno = 0;
- v = strtoul(arg, NULL, 0);
+ v = strtoul(arg, nullptr, 0);
if (errno != 0 || !isdigit(arg[0])) {
ERR("Wrong value in --agent-tcp-port parameter: %s", arg);
return -1;
ERR("Port overflow in --agent-tcp-port parameter: %s", arg);
return -1;
}
- the_config.agent_tcp_port.begin =
- the_config.agent_tcp_port.end = (int) v;
+ the_config.agent_tcp_port.begin = the_config.agent_tcp_port.end = (int) v;
DBG3("Agent TCP port set to non default: %i", (int) v);
}
} else if (string_match(optname, "load") || opt == 'l') {
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-l, --load");
+ "-l, --load");
} else {
- config_string_set(&the_config.load_session_path,
- strdup(arg));
+ config_string_set(&the_config.load_session_path, strdup(arg));
if (!the_config.load_session_path.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--kmod-probes");
+ "--kmod-probes");
} else {
- config_string_set(&the_config.kmod_probes_list,
- strdup(arg));
+ config_string_set(&the_config.kmod_probes_list, strdup(arg));
if (!the_config.kmod_probes_list.value) {
PERROR("strdup");
ret = -ENOMEM;
}
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "--extra-kmod-probes");
+ "--extra-kmod-probes");
} else {
- config_string_set(&the_config.kmod_extra_probes_list,
- strdup(arg));
+ config_string_set(&the_config.kmod_extra_probes_list, strdup(arg));
if (!the_config.kmod_extra_probes_list.value) {
PERROR("strdup");
ret = -ENOMEM;
unsigned long v;
errno = 0;
- v = strtoul(arg, NULL, 0);
+ v = strtoul(arg, nullptr, 0);
if (errno != 0 || !isdigit(arg[0])) {
ERR("Wrong value in --%s parameter: %s",
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, arg);
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR,
+ arg);
return -1;
}
if (v == 0 || v >= EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX) {
ERR("Value out of range for --%s parameter: %s",
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR, arg);
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_KERNEL_OPTION_STR,
+ arg);
return -1;
}
the_config.event_notifier_buffer_size_kernel = (int) v;
DBG3("Number of event notifier error buffer kernel size to non default: %i",
- the_config.event_notifier_buffer_size_kernel);
+ the_config.event_notifier_buffer_size_kernel);
goto end;
} else if (string_match(optname, EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR)) {
unsigned long v;
errno = 0;
- v = strtoul(arg, NULL, 0);
+ v = strtoul(arg, nullptr, 0);
if (errno != 0 || !isdigit(arg[0])) {
ERR("Wrong value in --%s parameter: %s",
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, arg);
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR,
+ arg);
return -1;
}
if (v == 0 || v >= EVENT_NOTIFIER_ERROR_COUNTER_NUMBER_OF_BUCKET_MAX) {
ERR("Value out of range for --%s parameter: %s",
- EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR, arg);
+ EVENT_NOTIFIER_ERROR_BUFFER_SIZE_USERSPACE_OPTION_STR,
+ arg);
return -1;
}
the_config.event_notifier_buffer_size_userspace = (int) v;
DBG3("Number of event notifier error buffer userspace size to non default: %i",
- the_config.event_notifier_buffer_size_userspace);
+ the_config.event_notifier_buffer_size_userspace);
goto end;
} else if (string_match(optname, "config") || opt == 'f') {
/* This is handled in set_options() thus silent skip. */
const char *opt_name = "unknown";
int i;
- for (i = 0; i < sizeof(long_options) / sizeof(struct option);
- i++) {
+ for (i = 0; i < sizeof(long_options) / sizeof(struct option); i++) {
if (opt == long_options[i].val) {
opt_name = long_options[i].name;
break;
}
}
- WARN("Invalid argument provided for option \"%s\", using default value.",
- opt_name);
+ WARN("Invalid argument provided for option \"%s\", using default value.", opt_name);
}
return ret;
* See config_entry_handler_cb comment in common/config/session-config.h for the
* return value conventions.
*/
-static int config_entry_handler(const struct config_entry *entry, void *unused)
+static int config_entry_handler(const struct config_entry *entry,
+ void *unused __attribute__((unused)))
{
int ret = 0, i;
}
}
- for (i = 0; i < (sizeof(long_options) / sizeof(struct option)) - 1;
- i++) {
-
+ for (i = 0; i < (sizeof(long_options) / sizeof(struct option)) - 1; i++) {
/* Ignore if not fully matched. */
- if (strcmp(entry->name, long_options[i].name)) {
+ if (strcmp(entry->name, long_options[i].name) != 0) {
continue;
}
if (ret <= 0) {
if (ret) {
WARN("Invalid configuration value \"%s\" for option %s",
- entry->value, entry->name);
+ entry->value,
+ entry->name);
}
/* False, skip boolean config option. */
goto end;
return ret;
}
-static void print_version(void) {
+static void print_version()
+{
fprintf(stdout, "%s\n", VERSION);
}
int ret = 0, c = 0, option_index = 0;
int orig_optopt = optopt, orig_optind = optind;
char *optstring;
- char *config_path = NULL;
+ char *config_path = nullptr;
optstring = utils_generate_optstring(long_options,
- sizeof(long_options) / sizeof(struct option));
+ sizeof(long_options) / sizeof(struct option));
if (!optstring) {
ret = -ENOMEM;
goto end;
}
/* Check for the --config option */
- while ((c = getopt_long(argc, argv, optstring, long_options,
- &option_index)) != -1) {
+ while ((c = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1) {
if (c == '?') {
ret = -EINVAL;
goto end;
if (lttng_is_setuid_setgid()) {
WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
- "-f, --config");
+ "-f, --config");
} else {
free(config_path);
config_path = utils_expand_path(optarg);
}
}
- ret = config_get_section_entries(config_path, config_section_name,
- config_entry_handler, NULL);
+ ret = config_get_section_entries(
+ config_path, config_section_name, config_entry_handler, nullptr);
if (ret) {
if (ret > 0) {
ERR("Invalid configuration option at line %i", ret);
/* Reset getopt's global state */
optopt = orig_optopt;
optind = orig_optind;
- while (1) {
+ while (true) {
option_index = -1;
/*
* getopt_long() will not set option_index if it encounters a
* short option.
*/
- c = getopt_long(argc, argv, optstring, long_options,
- &option_index);
+ c = getopt_long(argc, argv, optstring, long_options, &option_index);
if (c == -1) {
break;
}
* Pass NULL as the long option name if popt left the index
* unset.
*/
- ret = set_option(c, optarg,
- option_index < 0 ? NULL :
- long_options[option_index].name);
+ ret = set_option(
+ c, optarg, option_index < 0 ? nullptr : long_options[option_index].name);
if (ret < 0) {
break;
}
/*
* Create lockfile using the rundir and return its fd.
*/
-static int create_lockfile(void)
+static int create_lockfile()
{
return utils_create_lock_file(the_config.lock_file_path.value);
}
*
* Also attempts to create and hold the lock file.
*/
-static int check_existing_daemon(void)
+static int check_existing_daemon()
{
int ret = 0;
return ret;
}
-static void sessiond_cleanup_lock_file(void)
+static void sessiond_cleanup_lock_file()
{
int ret;
int ret;
gid_t gid;
- ret = utils_get_group_id(
- the_config.tracing_group_name.value, true, &gid);
+ ret = utils_get_group_id(the_config.tracing_group_name.value, true, &gid);
if (ret) {
/* Default to root group. */
gid = 0;
/* lttng client socket path */
ret = chown(the_config.client_unix_sock_path.value, 0, gid);
if (ret < 0) {
- ERR("Unable to set group on %s",
- the_config.client_unix_sock_path.value);
+ ERR("Unable to set group on %s", the_config.client_unix_sock_path.value);
PERROR("chown");
}
/* kconsumer error socket path */
ret = chown(the_kconsumer_data.err_unix_sock_path, 0, 0);
if (ret < 0) {
- ERR("Unable to set group on %s",
- the_kconsumer_data.err_unix_sock_path);
+ ERR("Unable to set group on %s", the_kconsumer_data.err_unix_sock_path);
PERROR("chown");
}
/* 64-bit ustconsumer error socket path */
ret = chown(the_ustconsumer64_data.err_unix_sock_path, 0, 0);
if (ret < 0) {
- ERR("Unable to set group on %s",
- the_ustconsumer64_data.err_unix_sock_path);
+ ERR("Unable to set group on %s", the_ustconsumer64_data.err_unix_sock_path);
PERROR("chown");
}
/* 32-bit ustconsumer compat32 error socket path */
ret = chown(the_ustconsumer32_data.err_unix_sock_path, 0, 0);
if (ret < 0) {
- ERR("Unable to set group on %s",
- the_ustconsumer32_data.err_unix_sock_path);
+ ERR("Unable to set group on %s", the_ustconsumer32_data.err_unix_sock_path);
PERROR("chown");
}
/*
* Create the lttng run directory needed for all global sockets and pipe.
*/
-static int create_lttng_rundir(void)
+static int create_lttng_rundir()
{
int ret;
static int set_consumer_sockets(struct consumer_data *consumer_data)
{
int ret;
- char *path = NULL;
+ char *path = nullptr;
switch (consumer_data->type) {
case LTTNG_CONSUMER_KERNEL:
if (is_root) {
gid_t gid;
- ret = utils_get_group_id(the_config.tracing_group_name.value,
- true, &gid);
+ ret = utils_get_group_id(the_config.tracing_group_name.value, true, &gid);
if (ret) {
/* Default to root group. */
gid = 0;
}
/* Create the consumerd error unix socket */
- consumer_data->err_sock =
- lttcomm_create_unix_sock(consumer_data->err_unix_sock_path);
+ consumer_data->err_sock = lttcomm_create_unix_sock(consumer_data->err_unix_sock_path);
if (consumer_data->err_sock < 0) {
ERR("Create unix sock failed: %s", consumer_data->err_unix_sock_path);
ret = -1;
}
/* File permission MUST be 660 */
- ret = chmod(consumer_data->err_unix_sock_path,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ ret = chmod(consumer_data->err_unix_sock_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (ret < 0) {
ERR("Set file permissions failed: %s", consumer_data->err_unix_sock_path);
PERROR("chmod");
* Simply stop all worker threads, leaving main() return gracefully after
* joining all threads and calling cleanup().
*/
-static void sighandler(int sig, siginfo_t *siginfo, void *arg)
+static void sighandler(int sig, siginfo_t *siginfo, void *arg __attribute__((unused)))
{
switch (sig) {
case SIGINT:
DBG("SIGINT caught");
- stop_threads();
+ notify_main_quit_pipe();
break;
case SIGTERM:
DBG("SIGTERM caught");
- stop_threads();
+ notify_main_quit_pipe();
break;
case SIGUSR1:
CMM_STORE_SHARED(recv_child_signal, 1);
* Setup signal handler for :
* SIGINT, SIGTERM, SIGPIPE
*/
-static int set_signal_handler(void)
+static int set_signal_handler()
{
int ret = 0;
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = sighandler;
- if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
+ if ((ret = sigaction(SIGTERM, &sa, nullptr)) < 0) {
PERROR("sigaction");
return ret;
}
- if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
+ if ((ret = sigaction(SIGINT, &sa, nullptr)) < 0) {
PERROR("sigaction");
return ret;
}
- if ((ret = sigaction(SIGUSR1, &sa, NULL)) < 0) {
+ if ((ret = sigaction(SIGUSR1, &sa, nullptr)) < 0) {
PERROR("sigaction");
return ret;
}
- if ((ret = sigaction(SIGBUS, &sa, NULL)) < 0) {
+ if ((ret = sigaction(SIGBUS, &sa, nullptr)) < 0) {
PERROR("sigaction");
return ret;
}
sa.sa_flags = 0;
sa.sa_handler = SIG_IGN;
- if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
+ if ((ret = sigaction(SIGPIPE, &sa, nullptr)) < 0) {
PERROR("sigaction");
return ret;
}
* Set open files limit to unlimited. This daemon can open a large number of
* file descriptors in order to consume multiple kernel traces.
*/
-static void set_ulimit(void)
+static void set_ulimit()
{
int ret;
struct rlimit lim;
}
}
-static int write_pidfile(void)
+static int write_pidfile()
{
return utils_create_pid_file(getpid(), the_config.pid_file_path.value);
}
-static int set_clock_plugin_env(void)
+static int set_clock_plugin_env()
{
int ret = 0;
- char *env_value = NULL;
+ char *env_value = nullptr;
if (!the_config.lttng_ust_clock_plugin.value) {
goto end;
}
- ret = asprintf(&env_value, "LTTNG_UST_CLOCK_PLUGIN=%s",
- the_config.lttng_ust_clock_plugin.value);
+ ret = asprintf(
+ &env_value, "LTTNG_UST_CLOCK_PLUGIN=%s", the_config.lttng_ust_clock_plugin.value);
if (ret < 0) {
PERROR("asprintf");
goto end;
}
DBG("Updated LTTNG_UST_CLOCK_PLUGIN environment variable to \"%s\"",
- the_config.lttng_ust_clock_plugin.value);
+ the_config.lttng_ust_clock_plugin.value);
end:
return ret;
}
-static void destroy_all_sessions_and_wait(void)
+static void destroy_all_sessions_and_wait()
{
struct ltt_session *session, *tmp;
struct ltt_session_list *session_list;
session_lock_list();
/* Initiate the destruction of all sessions. */
- cds_list_for_each_entry_safe(session, tmp,
- &session_list->head, list) {
+ cds_list_for_each_entry_safe (session, tmp, &session_list->head, list) {
if (!session_get(session)) {
continue;
}
goto unlock_session;
}
(void) cmd_stop_trace(session);
- (void) cmd_destroy_session(
- session, the_notification_thread_handle, NULL);
+ (void) cmd_destroy_session(session, nullptr);
unlock_session:
session_unlock(session);
session_put(session);
DBG("Destruction of all sessions completed");
}
-static void unregister_all_triggers(void)
+static void unregister_all_triggers()
{
enum lttng_error_code ret_code;
enum lttng_trigger_status trigger_status;
- struct lttng_triggers *triggers = NULL;
+ struct lttng_triggers *triggers = nullptr;
unsigned int trigger_count, i;
const struct lttng_credentials creds = {
.uid = LTTNG_OPTIONAL_INIT_VALUE(0),
+ .gid = LTTNG_OPTIONAL_INIT_UNSET,
};
DBG("Unregistering all triggers");
* List all triggers as "root" since we wish to unregister all triggers.
*/
ret_code = notification_thread_command_list_triggers(
- the_notification_thread_handle, creds.uid.value,
- &triggers);
+ the_notification_thread_handle, creds.uid.value, &triggers);
if (ret_code != LTTNG_OK) {
ERR("Failed to list triggers while unregistering all triggers");
goto end;
for (i = 0; i < trigger_count; i++) {
uid_t trigger_owner;
const char *trigger_name;
- const struct lttng_trigger *trigger =
- lttng_triggers_get_at_index(triggers, i);
+ const struct lttng_trigger *trigger = lttng_triggers_get_at_index(triggers, i);
LTTNG_ASSERT(trigger);
- trigger_status = lttng_trigger_get_owner_uid(
- trigger, &trigger_owner);
+ trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_owner);
LTTNG_ASSERT(trigger_status == LTTNG_TRIGGER_STATUS_OK);
trigger_status = lttng_trigger_get_name(trigger, &trigger_name);
- trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ?
- trigger_name : "(anonymous)";
+ trigger_name = trigger_status == LTTNG_TRIGGER_STATUS_OK ? trigger_name :
+ "(anonymous)";
DBG("Unregistering trigger: trigger owner uid = %d, trigger name = '%s'",
- (int) trigger_owner, trigger_name);
+ (int) trigger_owner,
+ trigger_name);
- ret_code = cmd_unregister_trigger(&creds, trigger,
- the_notification_thread_handle);
+ ret_code = cmd_unregister_trigger(&creds, trigger, the_notification_thread_handle);
if (ret_code != LTTNG_OK) {
ERR("Failed to unregister trigger: trigger owner uid = %d, trigger name = '%s', error: '%s'",
- (int) trigger_owner, trigger_name,
- lttng_strerror(-ret_code));
+ (int) trigger_owner,
+ trigger_name,
+ lttng_strerror(-ret_code));
/* Continue to unregister the remaining triggers. */
}
}
* be leaked as the process forks a run-as worker (and performs
* no exec*()). The same would apply to any opened fd.
*/
- return run_as_create_worker(
- procname, run_as_worker_post_fork_cleanup, &the_config);
+ return run_as_create_worker(procname, run_as_worker_post_fork_cleanup, &the_config);
}
-static void sessiond_uuid_log(void)
+static void sessiond_uuid_log()
{
char uuid_str[LTTNG_UUID_STR_LEN];
/*
* main
*/
-int main(int argc, char **argv)
+static int _main(int argc, char **argv)
{
int ret = 0, retval = 0;
const char *env_app_timeout;
- struct lttng_pipe *ust32_channel_monitor_pipe = NULL,
- *ust64_channel_monitor_pipe = NULL,
- *kernel_channel_monitor_pipe = NULL;
- struct lttng_thread *ht_cleanup_thread = NULL;
+ struct lttng_pipe *ust32_channel_monitor_pipe = nullptr,
+ *ust64_channel_monitor_pipe = nullptr,
+ *kernel_channel_monitor_pipe = nullptr;
struct timer_thread_parameters timer_thread_parameters;
- /* Rotation thread handle. */
- struct rotation_thread_handle *rotation_thread_handle = NULL;
/* Queue of rotation jobs populated by the sessiond-timer. */
- struct rotation_thread_timer_queue *rotation_timer_queue = NULL;
- struct lttng_thread *client_thread = NULL;
- struct lttng_thread *notification_thread = NULL;
- struct lttng_thread *register_apps_thread = NULL;
+ lttng::sessiond::rotation_thread_timer_queue *rotation_timer_queue = nullptr;
+ struct lttng_thread *client_thread = nullptr;
+ struct lttng_thread *notification_thread = nullptr;
+ struct lttng_thread *register_apps_thread = nullptr;
enum event_notifier_error_accounting_status event_notifier_error_accounting_status;
logger_set_thread_name("Main", false);
* Parse arguments and load the daemon configuration file.
*
* We have an exit_options exit path to free memory reserved by
- * set_options. This is needed because the rest of sessiond_cleanup()
- * depends on ht_cleanup_thread, which depends on lttng_daemonize, which
- * depends on set_options.
+ * set_options.
*/
progname = argv[0];
if (set_options(argc, argv)) {
/* Apply config. */
lttng_opt_verbose = the_config.verbose;
lttng_opt_quiet = the_config.quiet;
- the_kconsumer_data.err_unix_sock_path =
- the_config.kconsumerd_err_unix_sock_path.value;
- the_kconsumer_data.cmd_unix_sock_path =
- the_config.kconsumerd_cmd_unix_sock_path.value;
- the_ustconsumer32_data.err_unix_sock_path =
- the_config.consumerd32_err_unix_sock_path.value;
- the_ustconsumer32_data.cmd_unix_sock_path =
- the_config.consumerd32_cmd_unix_sock_path.value;
- the_ustconsumer64_data.err_unix_sock_path =
- the_config.consumerd64_err_unix_sock_path.value;
- the_ustconsumer64_data.cmd_unix_sock_path =
- the_config.consumerd64_cmd_unix_sock_path.value;
+ the_kconsumer_data.err_unix_sock_path = the_config.kconsumerd_err_unix_sock_path.value;
+ the_kconsumer_data.cmd_unix_sock_path = the_config.kconsumerd_cmd_unix_sock_path.value;
+ the_ustconsumer32_data.err_unix_sock_path = the_config.consumerd32_err_unix_sock_path.value;
+ the_ustconsumer32_data.cmd_unix_sock_path = the_config.consumerd32_cmd_unix_sock_path.value;
+ the_ustconsumer64_data.err_unix_sock_path = the_config.consumerd64_err_unix_sock_path.value;
+ the_ustconsumer64_data.cmd_unix_sock_path = the_config.consumerd64_cmd_unix_sock_path.value;
set_clock_plugin_env();
sessiond_config_log(&the_config);
sessiond_uuid_log();
+ lttng::logging::log_system_information(PRINT_DBG);
if (opt_print_version) {
print_version();
if (the_config.daemonize || the_config.background) {
int i;
- ret = lttng_daemonize(&the_child_ppid, &recv_child_signal,
- !the_config.background);
+ ret = lttng_daemonize(&the_child_ppid, &recv_child_signal, !the_config.background);
if (ret < 0) {
retval = -1;
goto exit_options;
goto stop_threads;
}
- /* Create thread to clean up RCU hash tables */
- ht_cleanup_thread = launch_ht_cleanup_thread();
- if (!ht_cleanup_thread) {
- retval = -1;
- goto stop_threads;
- }
-
- /* Create thread quit pipe */
- if (sessiond_init_thread_quit_pipe()) {
+ /* Create main quit pipe */
+ if (sessiond_init_main_quit_pipe()) {
retval = -1;
goto stop_threads;
}
goto stop_threads;
}
the_kconsumer_data.channel_monitor_pipe =
- lttng_pipe_release_writefd(
- kernel_channel_monitor_pipe);
+ lttng_pipe_release_writefd(kernel_channel_monitor_pipe);
if (the_kconsumer_data.channel_monitor_pipe < 0) {
retval = -1;
goto stop_threads;
goto stop_threads;
}
the_ustconsumer32_data.channel_monitor_pipe =
- lttng_pipe_release_writefd(ust32_channel_monitor_pipe);
+ lttng_pipe_release_writefd(ust32_channel_monitor_pipe);
if (the_ustconsumer32_data.channel_monitor_pipe < 0) {
retval = -1;
goto stop_threads;
* sessiond timer thread and the rotation thread. The main thread keeps
* its ownership and destroys it when both threads have been joined.
*/
- rotation_timer_queue = rotation_thread_timer_queue_create();
+ rotation_timer_queue = lttng::sessiond::rotation_thread_timer_queue_create();
if (!rotation_timer_queue) {
retval = -1;
goto stop_threads;
}
- timer_thread_parameters.rotation_thread_job_queue =
- rotation_timer_queue;
+ timer_thread_parameters.rotation_thread_job_queue = rotation_timer_queue;
ust64_channel_monitor_pipe = lttng_pipe_open(0);
if (!ust64_channel_monitor_pipe) {
goto stop_threads;
}
the_ustconsumer64_data.channel_monitor_pipe =
- lttng_pipe_release_writefd(ust64_channel_monitor_pipe);
+ lttng_pipe_release_writefd(ust64_channel_monitor_pipe);
if (the_ustconsumer64_data.channel_monitor_pipe < 0) {
retval = -1;
goto stop_threads;
}
event_notifier_error_accounting_status = event_notifier_error_accounting_init(
- the_config.event_notifier_buffer_size_kernel,
- the_config.event_notifier_buffer_size_userspace);
+ the_config.event_notifier_buffer_size_kernel,
+ the_config.event_notifier_buffer_size_userspace);
if (event_notifier_error_accounting_status != EVENT_NOTIFIER_ERROR_ACCOUNTING_STATUS_OK) {
ERR("Failed to initialize event notifier error accounting system");
retval = -1;
}
/* notification_thread_data acquires the pipes' read side. */
- the_notification_thread_handle = notification_thread_handle_create(
- ust32_channel_monitor_pipe, ust64_channel_monitor_pipe,
- kernel_channel_monitor_pipe);
+ the_notification_thread_handle =
+ notification_thread_handle_create(ust32_channel_monitor_pipe,
+ ust64_channel_monitor_pipe,
+ kernel_channel_monitor_pipe);
if (!the_notification_thread_handle) {
retval = -1;
ERR("Failed to create notification thread shared data");
}
/* Create notification thread. */
- notification_thread = launch_notification_thread(
- the_notification_thread_handle);
+ notification_thread = launch_notification_thread(the_notification_thread_handle);
if (!notification_thread) {
retval = -1;
goto stop_threads;
goto stop_threads;
}
- /* rotation_thread_data acquires the pipes' read side. */
- rotation_thread_handle = rotation_thread_handle_create(
- rotation_timer_queue, the_notification_thread_handle);
- if (!rotation_thread_handle) {
+ try {
+ the_rotation_thread_handle = lttng::make_unique<lttng::sessiond::rotation_thread>(
+ *rotation_timer_queue, *the_notification_thread_handle);
+ } catch (const std::exception& e) {
retval = -1;
- ERR("Failed to create rotation thread shared data");
- stop_threads();
+ ERR("Failed to create rotation thread: %s", e.what());
goto stop_threads;
}
- /* Create rotation thread. */
- if (!launch_rotation_thread(rotation_thread_handle)) {
+ try {
+ the_rotation_thread_handle->launch_thread();
+ } catch (const std::exception& e) {
retval = -1;
+ ERR("Failed to launch rotation thread: %s", e.what());
goto stop_threads;
}
goto stop_threads;
}
- if (!launch_ust_dispatch_thread(&ust_cmd_queue, apps_cmd_pipe[1],
- apps_cmd_notify_pipe[1])) {
+ if (!launch_ust_dispatch_thread(&ust_cmd_queue, apps_cmd_pipe[1], apps_cmd_notify_pipe[1])) {
retval = -1;
goto stop_threads;
}
/* Create thread to manage application registration. */
- register_apps_thread = launch_application_registration_thread(
- &ust_cmd_queue);
+ register_apps_thread = launch_application_registration_thread(&ust_cmd_queue);
if (!register_apps_thread) {
retval = -1;
goto stop_threads;
if (kernel_get_notification_fd() >= 0) {
ret = notification_thread_command_add_tracer_event_source(
- the_notification_thread_handle,
- kernel_get_notification_fd(),
- LTTNG_DOMAIN_KERNEL);
+ the_notification_thread_handle,
+ kernel_get_notification_fd(),
+ LTTNG_DOMAIN_KERNEL);
if (ret != LTTNG_OK) {
ERR("Failed to add kernel trigger event source to notification thread");
retval = -1;
}
/* Load sessions. */
- ret = config_load_session(
- the_config.load_session_path.value, NULL, 1, 1, NULL);
+ ret = config_load_session(the_config.load_session_path.value, nullptr, 1, 1, nullptr);
if (ret) {
ERR("Session load failed: %s", error_get_str(ret));
retval = -1;
* signal that asks threads to teardown).
*/
- /* Initiate teardown once activity occurs on the quit pipe. */
- sessiond_wait_for_quit_pipe(-1);
+ /* Initiate teardown once activity occurs on the main quit pipe. */
+ sessiond_wait_for_main_quit_pipe(-1);
stop_threads:
+ DBG("Terminating all threads");
+
/*
* Ensure that the client thread is no longer accepting new commands,
* which could cause new sessions to be created.
* perform lookups in those structures.
*/
rcu_barrier();
- /*
- * sessiond_cleanup() is called when no other thread is running, except
- * the ht_cleanup thread, which is needed to destroy the hash tables.
- */
+
rcu_thread_online();
sessiond_cleanup();
*/
if (is_root && !the_config.no_kernel) {
DBG("Unloading kernel modules");
- modprobe_remove_lttng_all();
- }
-
- /*
- * Ensure all prior call_rcu are done. call_rcu callbacks may push
- * hash tables to the ht_cleanup thread. Therefore, we ensure that
- * the queue is empty before shutting down the clean-up thread.
- */
- rcu_barrier();
-
- if (ht_cleanup_thread) {
- lttng_thread_shutdown(ht_cleanup_thread);
- lttng_thread_put(ht_cleanup_thread);
+ modprobe_remove_lttng_all();
}
rcu_thread_offline();
rcu_unregister_thread();
- if (rotation_thread_handle) {
- rotation_thread_handle_destroy(rotation_thread_handle);
- }
-
/*
* After the rotation and timer thread have quit, we can safely destroy
* the rotation_timer_queue.
* of the active session and channels at the moment of the teardown.
*/
if (the_notification_thread_handle) {
- notification_thread_handle_destroy(
- the_notification_thread_handle);
+ notification_thread_handle_destroy(the_notification_thread_handle);
}
lttng_pipe_destroy(ust32_channel_monitor_pipe);
lttng_pipe_destroy(ust64_channel_monitor_pipe);
exit(EXIT_FAILURE);
}
}
+
+int main(int argc, char **argv)
+{
+ try {
+ return _main(argc, argv);
+ } catch (const std::exception& e) {
+ ERR_FMT("Unhandled exception caught by main thread: %s", e.what());
+ abort();
+ }
+}