#include <urcu/compiler.h>
#include <lttng/urcu/urcu-ust.h>
+#include <lttng/ust-utils.h>
#include <lttng/ust-events.h>
#include <lttng/ust-abi.h>
-#include <lttng/ust.h>
+#include <lttng/ust-fork.h>
#include <lttng/ust-error.h>
#include <lttng/ust-ctl.h>
+#include <lttng/ust-libc-wrapper.h>
+#include <lttng/ust-thread.h>
+#include <lttng/ust-tracer.h>
#include <urcu/tls-compat.h>
#include <ust-comm.h>
#include <ust-fd.h>
#include "ust-events-internal.h"
#include "context-internal.h"
#include "ust-compat.h"
-
-/* Concatenate lttng ust shared library name with its major version number. */
-#define LTTNG_UST_LIB_SO_NAME "liblttng-ust.so." __ust_stringify(CONFIG_LTTNG_UST_LIBRARY_VERSION_MAJOR)
+#include "lttng-counter-client.h"
+#include "lttng-rb-clients.h"
/*
* Has lttng ust comm constructor been called ?
static int wait_poll_fallback;
static const char *cmd_name_mapping[] = {
- [ LTTNG_UST_RELEASE ] = "Release",
- [ LTTNG_UST_SESSION ] = "Create Session",
- [ LTTNG_UST_TRACER_VERSION ] = "Get Tracer Version",
+ [ LTTNG_UST_ABI_RELEASE ] = "Release",
+ [ LTTNG_UST_ABI_SESSION ] = "Create Session",
+ [ LTTNG_UST_ABI_TRACER_VERSION ] = "Get Tracer Version",
- [ LTTNG_UST_TRACEPOINT_LIST ] = "Create Tracepoint List",
- [ LTTNG_UST_WAIT_QUIESCENT ] = "Wait for Quiescent State",
- [ LTTNG_UST_REGISTER_DONE ] = "Registration Done",
- [ LTTNG_UST_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List",
+ [ LTTNG_UST_ABI_TRACEPOINT_LIST ] = "Create Tracepoint List",
+ [ LTTNG_UST_ABI_WAIT_QUIESCENT ] = "Wait for Quiescent State",
+ [ LTTNG_UST_ABI_REGISTER_DONE ] = "Registration Done",
+ [ LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST ] = "Create Tracepoint Field List",
- [ LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE ] = "Create event notifier group",
+ [ LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE ] = "Create event notifier group",
/* Session FD commands */
- [ LTTNG_UST_CHANNEL ] = "Create Channel",
- [ LTTNG_UST_SESSION_START ] = "Start Session",
- [ LTTNG_UST_SESSION_STOP ] = "Stop Session",
+ [ LTTNG_UST_ABI_CHANNEL ] = "Create Channel",
+ [ LTTNG_UST_ABI_SESSION_START ] = "Start Session",
+ [ LTTNG_UST_ABI_SESSION_STOP ] = "Stop Session",
/* Channel FD commands */
- [ LTTNG_UST_STREAM ] = "Create Stream",
- [ LTTNG_UST_EVENT ] = "Create Event",
+ [ LTTNG_UST_ABI_STREAM ] = "Create Stream",
+ [ LTTNG_UST_ABI_EVENT ] = "Create Event",
/* Event and Channel FD commands */
- [ LTTNG_UST_CONTEXT ] = "Create Context",
- [ LTTNG_UST_FLUSH_BUFFER ] = "Flush Buffer",
+ [ LTTNG_UST_ABI_CONTEXT ] = "Create Context",
+ [ LTTNG_UST_ABI_FLUSH_BUFFER ] = "Flush Buffer",
/* Event, Channel and Session commands */
- [ LTTNG_UST_ENABLE ] = "Enable",
- [ LTTNG_UST_DISABLE ] = "Disable",
+ [ LTTNG_UST_ABI_ENABLE ] = "Enable",
+ [ LTTNG_UST_ABI_DISABLE ] = "Disable",
/* Tracepoint list commands */
- [ LTTNG_UST_TRACEPOINT_LIST_GET ] = "List Next Tracepoint",
- [ LTTNG_UST_TRACEPOINT_FIELD_LIST_GET ] = "List Next Tracepoint Field",
+ [ LTTNG_UST_ABI_TRACEPOINT_LIST_GET ] = "List Next Tracepoint",
+ [ LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET ] = "List Next Tracepoint Field",
/* Event FD commands */
- [ LTTNG_UST_FILTER ] = "Create Filter",
- [ LTTNG_UST_EXCLUSION ] = "Add exclusions to event",
+ [ LTTNG_UST_ABI_FILTER ] = "Create Filter",
+ [ LTTNG_UST_ABI_EXCLUSION ] = "Add exclusions to event",
/* Event notifier group commands */
- [ LTTNG_UST_EVENT_NOTIFIER_CREATE ] = "Create event notifier",
+ [ LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE ] = "Create event notifier",
/* Session and event notifier group commands */
- [ LTTNG_UST_COUNTER ] = "Create Counter",
+ [ LTTNG_UST_ABI_COUNTER ] = "Create Counter",
/* Counter commands */
- [ LTTNG_UST_COUNTER_GLOBAL ] = "Create Counter Global",
- [ LTTNG_UST_COUNTER_CPU ] = "Create Counter CPU",
+ [ LTTNG_UST_ABI_COUNTER_GLOBAL ] = "Create Counter Global",
+ [ LTTNG_UST_ABI_COUNTER_CPU ] = "Create Counter CPU",
};
static const char *str_timeout;
static int got_timeout_env;
-extern void lttng_ring_buffer_client_overwrite_init(void);
-extern void lttng_ring_buffer_client_overwrite_rt_init(void);
-extern void lttng_ring_buffer_client_discard_init(void);
-extern void lttng_ring_buffer_client_discard_rt_init(void);
-extern void lttng_ring_buffer_metadata_client_init(void);
-extern void lttng_ring_buffer_client_overwrite_exit(void);
-extern void lttng_ring_buffer_client_overwrite_rt_exit(void);
-extern void lttng_ring_buffer_client_discard_exit(void);
-extern void lttng_ring_buffer_client_discard_rt_exit(void);
-extern void lttng_ring_buffer_metadata_client_exit(void);
-LTTNG_HIDDEN
-extern void lttng_counter_client_percpu_32_modular_init(void);
-LTTNG_HIDDEN
-extern void lttng_counter_client_percpu_32_modular_exit(void);
-LTTNG_HIDDEN
-extern void lttng_counter_client_percpu_64_modular_init(void);
-LTTNG_HIDDEN
-extern void lttng_counter_client_percpu_64_modular_exit(void);
-
static char *get_map_shm(struct sock_info *sock_info);
ssize_t lttng_ust_read(int fd, void *buf, size_t len)
lttng_fixup_net_ns_tls();
lttng_fixup_time_ns_tls();
lttng_fixup_uts_ns_tls();
+ lttng_ust_fixup_ring_buffer_client_discard_tls();
+ lttng_ust_fixup_ring_buffer_client_discard_rt_tls();
+ lttng_ust_fixup_ring_buffer_client_overwrite_tls();
+ lttng_ust_fixup_ring_buffer_client_overwrite_rt_tls();
+}
+
+/*
+ * LTTng-UST uses Global Dynamic model TLS variables rather than IE
+ * model because many versions of glibc don't preallocate a pool large
+ * enough for TLS variables IE model defined in other shared libraries,
+ * and causes issues when using LTTng-UST for Java tracing.
+ *
+ * Because of this use of Global Dynamic TLS variables, users wishing to
+ * trace from signal handlers need to explicitly trigger the lazy
+ * allocation of those variables for each thread before using them.
+ * This can be triggered by calling lttng_ust_init_thread().
+ */
+void lttng_ust_init_thread(void)
+{
+ /*
+ * Because those TLS variables are global dynamic, we need to
+ * ensure those are initialized before a signal handler nesting over
+ * this thread attempts to use them.
+ */
+ lttng_ust_fixup_tls();
}
int lttng_get_notify_socket(void *owner)
}
-LTTNG_HIDDEN
char* lttng_ust_sockinfo_get_procname(void *owner)
{
struct sock_info *info = owner;
return ustcomm_send_reg_msg(socket,
type,
CAA_BITS_PER_LONG,
- lttng_alignof(uint8_t) * CHAR_BIT,
- lttng_alignof(uint16_t) * CHAR_BIT,
- lttng_alignof(uint32_t) * CHAR_BIT,
- lttng_alignof(uint64_t) * CHAR_BIT,
- lttng_alignof(unsigned long) * CHAR_BIT);
+ lttng_ust_rb_alignof(uint8_t) * CHAR_BIT,
+ lttng_ust_rb_alignof(uint16_t) * CHAR_BIT,
+ lttng_ust_rb_alignof(uint32_t) * CHAR_BIT,
+ lttng_ust_rb_alignof(uint64_t) * CHAR_BIT,
+ lttng_ust_rb_alignof(unsigned long) * CHAR_BIT);
}
static
const char *bytecode_type_str(uint32_t cmd)
{
switch (cmd) {
- case LTTNG_UST_CAPTURE:
+ case LTTNG_UST_ABI_CAPTURE:
return "capture";
- case LTTNG_UST_FILTER:
+ case LTTNG_UST_ABI_FILTER:
return "filter";
default:
abort();
int sock, struct ustcomm_ust_msg *lum)
{
struct lttng_ust_bytecode_node *bytecode = NULL;
- enum lttng_ust_bytecode_node_type type;
- const struct lttng_ust_objd_ops *ops;
+ enum lttng_ust_bytecode_type type;
+ const struct lttng_ust_abi_objd_ops *ops;
uint32_t data_size, data_size_max, reloc_offset;
uint64_t seqnum;
ssize_t len;
int ret = 0;
switch (lum->cmd) {
- case LTTNG_UST_FILTER:
- type = LTTNG_UST_BYTECODE_NODE_TYPE_FILTER;
+ case LTTNG_UST_ABI_FILTER:
+ type = LTTNG_UST_BYTECODE_TYPE_FILTER;
data_size = lum->u.filter.data_size;
- data_size_max = FILTER_BYTECODE_MAX_LEN;
+ data_size_max = LTTNG_UST_ABI_FILTER_BYTECODE_MAX_LEN;
reloc_offset = lum->u.filter.reloc_offset;
seqnum = lum->u.filter.seqnum;
break;
- case LTTNG_UST_CAPTURE:
- type = LTTNG_UST_BYTECODE_NODE_TYPE_CAPTURE;
+ case LTTNG_UST_ABI_CAPTURE:
+ type = LTTNG_UST_BYTECODE_TYPE_CAPTURE;
data_size = lum->u.capture.data_size;
- data_size_max = CAPTURE_BYTECODE_MAX_LEN;
+ data_size_max = LTTNG_UST_ABI_CAPTURE_BYTECODE_MAX_LEN;
reloc_offset = lum->u.capture.reloc_offset;
seqnum = lum->u.capture.seqnum;
break;
}
}
- ops = objd_ops(lum->handle);
+ ops = lttng_ust_abi_objd_ops(lum->handle);
if (!ops) {
ret = -ENOENT;
goto end;
int sock, struct ustcomm_ust_msg *lum)
{
int ret = 0;
- const struct lttng_ust_objd_ops *ops;
+ const struct lttng_ust_abi_objd_ops *ops;
struct ustcomm_ust_reply lur;
- union ust_args args;
- char ctxstr[LTTNG_UST_SYM_NAME_LEN]; /* App context string. */
+ union lttng_ust_abi_args args;
+ char ctxstr[LTTNG_UST_ABI_SYM_NAME_LEN]; /* App context string. */
ssize_t len;
memset(&lur, 0, sizeof(lur));
goto error;
}
- ops = objd_ops(lum->handle);
+ ops = lttng_ust_abi_objd_ops(lum->handle);
if (!ops) {
ret = -ENOENT;
goto error;
}
switch (lum->cmd) {
- case LTTNG_UST_REGISTER_DONE:
- if (lum->handle == LTTNG_UST_ROOT_HANDLE)
+ case LTTNG_UST_ABI_REGISTER_DONE:
+ if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE)
ret = handle_register_done(sock_info);
else
ret = -EINVAL;
break;
- case LTTNG_UST_RELEASE:
- if (lum->handle == LTTNG_UST_ROOT_HANDLE)
+ case LTTNG_UST_ABI_RELEASE:
+ if (lum->handle == LTTNG_UST_ABI_ROOT_HANDLE)
ret = -EPERM;
else
- ret = lttng_ust_objd_unref(lum->handle, 1);
+ ret = lttng_ust_abi_objd_unref(lum->handle, 1);
break;
- case LTTNG_UST_CAPTURE:
- case LTTNG_UST_FILTER:
+ case LTTNG_UST_ABI_CAPTURE:
+ case LTTNG_UST_ABI_FILTER:
ret = handle_bytecode_recv(sock_info, sock, lum);
if (ret)
goto error;
break;
- case LTTNG_UST_EXCLUSION:
+ case LTTNG_UST_ABI_EXCLUSION:
{
/* Receive exclusion names */
struct lttng_ust_excluder_node *node;
goto error;
}
node = zmalloc(sizeof(*node) +
- count * LTTNG_UST_SYM_NAME_LEN);
+ count * LTTNG_UST_ABI_SYM_NAME_LEN);
if (!node) {
ret = -ENOMEM;
goto error;
}
node->excluder.count = count;
len = ustcomm_recv_unix_sock(sock, node->excluder.names,
- count * LTTNG_UST_SYM_NAME_LEN);
+ count * LTTNG_UST_ABI_SYM_NAME_LEN);
switch (len) {
case 0: /* orderly shutdown */
ret = 0;
free(node);
goto error;
default:
- if (len == count * LTTNG_UST_SYM_NAME_LEN) {
+ if (len == count * LTTNG_UST_ABI_SYM_NAME_LEN) {
DBG("Exclusion data received");
break;
} else if (len < 0) {
free(node);
break;
}
- case LTTNG_UST_EVENT_NOTIFIER_GROUP_CREATE:
+ case LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE:
{
int event_notifier_notif_fd, close_ret;
}
break;
}
- case LTTNG_UST_CHANNEL:
+ case LTTNG_UST_ABI_CHANNEL:
{
void *chan_data;
int wakeup_fd;
free(args.channel.chan_data);
break;
}
- case LTTNG_UST_STREAM:
+ case LTTNG_UST_ABI_STREAM:
{
int close_ret;
}
break;
}
- case LTTNG_UST_CONTEXT:
+ case LTTNG_UST_ABI_CONTEXT:
switch (lum->u.context.ctx) {
- case LTTNG_UST_CONTEXT_APP_CONTEXT:
+ case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
{
char *p;
size_t ctxlen, recvlen;
ctxlen = strlen("$app.") + lum->u.context.u.app_ctx.provider_name_len - 1
+ strlen(":") + lum->u.context.u.app_ctx.ctx_name_len;
- if (ctxlen >= LTTNG_UST_SYM_NAME_LEN) {
+ if (ctxlen >= LTTNG_UST_ABI_SYM_NAME_LEN) {
ERR("Application context string length size is too large: %zu bytes",
ctxlen);
ret = -EINVAL;
ret = -ENOSYS;
}
break;
- case LTTNG_UST_COUNTER:
+ case LTTNG_UST_ABI_COUNTER:
{
void *counter_data;
free(args.counter.counter_data);
break;
}
- case LTTNG_UST_COUNTER_GLOBAL:
+ case LTTNG_UST_ABI_COUNTER_GLOBAL:
{
/* Receive shm_fd */
ret = ustcomm_recv_counter_shm_from_sessiond(sock,
}
break;
}
- case LTTNG_UST_COUNTER_CPU:
+ case LTTNG_UST_ABI_COUNTER_CPU:
{
/* Receive shm_fd */
ret = ustcomm_recv_counter_shm_from_sessiond(sock,
}
break;
}
- case LTTNG_UST_EVENT_NOTIFIER_CREATE:
+ case LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE:
{
/* Receive struct lttng_ust_event_notifier */
- struct lttng_ust_event_notifier event_notifier;
+ struct lttng_ust_abi_event_notifier event_notifier;
if (sizeof(event_notifier) != lum->u.event_notifier.len) {
DBG("incorrect event notifier data message size: %u", lum->u.event_notifier.len);
}
if (ret >= 0) {
switch (lum->cmd) {
- case LTTNG_UST_TRACER_VERSION:
+ case LTTNG_UST_ABI_TRACER_VERSION:
lur.u.version = lum->u.version;
break;
- case LTTNG_UST_TRACEPOINT_LIST_GET:
+ case LTTNG_UST_ABI_TRACEPOINT_LIST_GET:
memcpy(&lur.u.tracepoint, &lum->u.tracepoint, sizeof(lur.u.tracepoint));
break;
}
*/
if (lur.ret_code == LTTNG_UST_OK) {
switch (lum->cmd) {
- case LTTNG_UST_TRACEPOINT_FIELD_LIST_GET:
+ case LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET:
len = ustcomm_send_unix_sock(sock,
&args.field_list.entry,
sizeof(args.field_list.entry));
int ret;
if (sock_info->root_handle != -1) {
- ret = lttng_ust_objd_unref(sock_info->root_handle, 1);
+ ret = lttng_ust_abi_objd_unref(sock_info->root_handle, 1);
if (ret) {
ERR("Error unref root handle");
}
goto quit;
}
/* Cleanup socket handles before trying to reconnect */
- lttng_ust_objd_table_owner_cleanup(sock_info);
+ lttng_ust_abi_objd_table_owner_cleanup(sock_info);
ust_unlock();
goto restart; /* try to reconnect */
* Weak symbol to call when the ust malloc wrapper is not loaded.
*/
__attribute__((weak))
-void lttng_ust_malloc_wrapper_init(void)
+void lttng_ust_libc_wrapper_malloc_init(void)
{
}
* sessiond monitoring thread: monitor presence of global and per-user
* sessiond by polling the application common named pipe.
*/
-void __attribute__((constructor)) lttng_ust_init(void)
+static
+void lttng_ust_init(void)
+ __attribute__((constructor));
+static
+void lttng_ust_init(void)
{
struct timespec constructor_timeout;
sigset_t sig_all_blocked, orig_parent_mask;
* liblttng-ust.so to increment the dynamic loader's internal refcount for
* this library so it never becomes zero, thus never gets unloaded from the
* address space of the process. Since we are already running in the
- * constructor of the LTTNG_UST_LIB_SO_NAME library, calling dlopen will
+ * constructor of the LTTNG_UST_LIB_SONAME library, calling dlopen will
* simply increment the refcount and no additionnal work is needed by the
* dynamic loader as the shared library is already loaded in the address
* space. As a safe guard, we use the RTLD_NODELETE flag to prevent
* never happen). Do the return value check but discard the handle at the
* end of the function as it's not needed.
*/
- handle = dlopen(LTTNG_UST_LIB_SO_NAME, RTLD_LAZY | RTLD_NODELETE);
+ handle = dlopen(LTTNG_UST_LIB_SONAME, RTLD_LAZY | RTLD_NODELETE);
if (!handle) {
- ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SO_NAME);
+ ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME);
}
/*
*/
ust_err_init();
lttng_ust_getenv_init(); /* Needs ust_err_init() to be completed. */
- init_tracepoint();
+ lttng_ust_tp_init();
lttng_ust_init_fd_tracker();
lttng_ust_clock_init();
lttng_ust_getcpu_init();
lttng_ust_statedump_init();
- lttng_ring_buffer_metadata_client_init();
- lttng_ring_buffer_client_overwrite_init();
- lttng_ring_buffer_client_overwrite_rt_init();
- lttng_ring_buffer_client_discard_init();
- lttng_ring_buffer_client_discard_rt_init();
- lttng_counter_client_percpu_32_modular_init();
- lttng_counter_client_percpu_64_modular_init();
+ lttng_ust_ring_buffer_clients_init();
+ lttng_ust_counter_clients_init();
lttng_perf_counter_init();
/*
* Invoke ust malloc wrapper init before starting other threads.
*/
- lttng_ust_malloc_wrapper_init();
+ lttng_ust_libc_wrapper_malloc_init();
timeout_mode = get_constructor_timeout(&constructor_timeout);
* point.
*/
lttng_ust_abi_exit();
- lttng_ust_events_exit();
+ lttng_ust_abi_events_exit();
lttng_perf_counter_exit();
- lttng_ring_buffer_client_discard_rt_exit();
- lttng_ring_buffer_client_discard_exit();
- lttng_ring_buffer_client_overwrite_rt_exit();
- lttng_ring_buffer_client_overwrite_exit();
- lttng_ring_buffer_metadata_client_exit();
- lttng_counter_client_percpu_32_modular_exit();
- lttng_counter_client_percpu_64_modular_exit();
+ lttng_ust_ring_buffer_clients_exit();
+ lttng_ust_counter_clients_exit();
lttng_ust_statedump_destroy();
- exit_tracepoint();
+ lttng_ust_tp_exit();
if (!exiting) {
/* Reinitialize values for fork */
sem_count = sem_count_initial_value;
}
}
-void __attribute__((destructor)) lttng_ust_exit(void)
+static
+void lttng_ust_exit(void)
+ __attribute__((destructor));
+static
+void lttng_ust_exit(void)
{
int ret;
* in the middle of an tracepoint or ust tracing state modification.
* Holding this mutex protects these structures across fork and clone.
*/
-void ust_before_fork(sigset_t *save_sigset)
+void lttng_ust_before_fork(sigset_t *save_sigset)
{
/*
* Disable signals. This is to avoid that the child intervenes
}
}
-void ust_after_fork_parent(sigset_t *restore_sigset)
+void lttng_ust_after_fork_parent(sigset_t *restore_sigset)
{
if (URCU_TLS(lttng_ust_nest_count))
return;
* This is meant for forks() that have tracing in the child between the
* fork and following exec call (if there is any).
*/
-void ust_after_fork_child(sigset_t *restore_sigset)
+void lttng_ust_after_fork_child(sigset_t *restore_sigset)
{
if (URCU_TLS(lttng_ust_nest_count))
return;
lttng_context_vpid_reset();
lttng_context_vtid_reset();
- lttng_context_procname_reset();
+ lttng_ust_context_procname_reset();
ust_context_ns_reset();
ust_context_vuids_reset();
ust_context_vgids_reset();
lttng_ust_init();
}
-void ust_after_setns(void)
+void lttng_ust_after_setns(void)
{
ust_context_ns_reset();
ust_context_vuids_reset();
ust_context_vgids_reset();
}
-void ust_after_unshare(void)
+void lttng_ust_after_unshare(void)
{
ust_context_ns_reset();
ust_context_vuids_reset();
ust_context_vgids_reset();
}
-void ust_after_setuid(void)
+void lttng_ust_after_setuid(void)
{
ust_context_vuids_reset();
}
-void ust_after_seteuid(void)
+void lttng_ust_after_seteuid(void)
{
ust_context_vuids_reset();
}
-void ust_after_setreuid(void)
+void lttng_ust_after_setreuid(void)
{
ust_context_vuids_reset();
}
-void ust_after_setresuid(void)
+void lttng_ust_after_setresuid(void)
{
ust_context_vuids_reset();
}
-void ust_after_setgid(void)
+void lttng_ust_after_setgid(void)
{
ust_context_vgids_reset();
}
-void ust_after_setegid(void)
+void lttng_ust_after_setegid(void)
{
ust_context_vgids_reset();
}
-void ust_after_setregid(void)
+void lttng_ust_after_setregid(void)
{
ust_context_vgids_reset();
}
-void ust_after_setresgid(void)
+void lttng_ust_after_setresgid(void)
{
ust_context_vgids_reset();
}