"TRACEPOINT_DEFINE" and include the tracepoint provider.
- Use "-I." for the compilation unit containing the tracepoint
provider include (e.g. tp.c).
- - Link application with "-ldl".
+ - Link application with "-ldl" on Linux, with "-lc" on BSD.
- If building the provider directly into the application,
link the application with "-llttng-ust".
- If building a static library for the provider, link the static
- Include the tracepoint provider header into all C files using
the provider.
- Example:
- tests/hello/ hello.c tp.c ust_tests_hello.h Makefile.example
+ tests/hello/ hello.c tp.c ust_tests_hello.h Makefile.example.*
2) Compile the Tracepoint Provider separately from the application,
using dynamic linking:
files that use the provider.
- Compile the tracepoint provider with "-I.".
- Link the tracepoint provider with "-llttng-ust".
- - Link application with "-ldl".
+ - Link application with "-ldl" on Linux, "-lc" on BSD.
- Set a LD_PRELOAD environment to preload the tracepoint provider
shared object before starting the application when tracing is
needed.
LT_INIT
## Checks for libraries.
-AC_CHECK_LIB([dl], [dlopen])
+AC_CHECK_LIB([dl], [dlopen],
+[
+ have_libdl=yes
+],
+[
+ #libdl not found, check for dlopen in libc.
+ AC_CHECK_LIB([c], [dlopen],
+ [
+ have_libc_dl=yes
+ ],
+ [
+ AC_MSG_ERROR([Cannot find dlopen in libdl nor libc. Use [LDFLAGS]=-Ldir to specify their location.])
+ ])
+])
+AM_CONDITIONAL([LTTNG_UST_BUILD_WITH_LIBDL], [test "x$have_libdl" = "xyes"])
+AM_CONDITIONAL([LTTNG_UST_BUILD_WITH_LIBC_DL], [test "x$have_libc_dl" = "xyes"])
+
AC_CHECK_LIB([pthread], [pthread_create])
# Check for libuuid
-AC_CHECK_LIB([uuid], [uuid_generate], [],
- [AC_MSG_ERROR([Cannot find libuuid. Use [LDFLAGS]=-Ldir to specify its location.])]
+AC_CHECK_LIB([uuid], [uuid_generate],
+[
+ AC_DEFINE_UNQUOTED([LTTNG_UST_HAVE_LIBUUID], 1, [Has libuuid support.])
+ have_libuuid=yes
+],
+[
+ # libuuid not found, check for uuid_create in libc.
+ AC_CHECK_LIB([c], [uuid_create],
+ [
+ AC_DEFINE_UNQUOTED([LTTNG_UST_HAVE_LIBC_UUID], 1, [Has libc uuid support.])
+ have_libc_uuid=yes
+ ],
+ [
+ AC_MSG_ERROR([Cannot find libuuid uuid_generate nor libc uuid_create. Use [LDFLAGS]=-Ldir to specify their location.])
+ ])
+]
)
+AM_CONDITIONAL([LTTNG_UST_BUILD_WITH_LIBUUID], [test "x$have_libuuid" = "xyes"])
+AM_CONDITIONAL([LTTNG_UST_BUILD_WITH_LIBC_UUID], [test "x$have_libc_uuid" = "xyes"])
# Checks for header files.
#AC_CHECK_HEADERS([fcntl.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h])
fi
;;
x86_64) LIBFORMAT="elf64-x86-64" ;;
+ amd64) LIBFORMAT="elf64-x86-64" ;;
powerpc) LIBFORMAT="elf32-powerpc" ;;
ppc64) LIBFORMAT="elf64-powerpc" ;;
powerpc64) LIBFORMAT="elf64-powerpc" ;;
# the "html" target helps for documentation (req. code2html)
CC = gcc
-LIBS = -ldl -llttng-ust
+LIBS = -ldl -llttng-ust # On Linux
+#LIBS = -lc -llttng-ust # On BSD
CFLAGS = -I.
all: sample
# provider probe.
CC = gcc
-LIBS = -ldl -llttng-ust
+
+LIBS = -ldl -llttng-ust #On Linux
+#LIBS = -lc -llttng-ust #On BSD
all: sample
lttng/ust-tracer.h \
lttng/ust-config.h \
lttng/ust.h \
+ lttng/ust-endian.h \
lttng/ringbuffer-config.h \
lttng/align.h \
lttng/bug.h
usterr-signal-safe.h \
ust_snprintf.h \
ust-comm.h \
+ lttng/ust-tid.h \
lttng/bitfield.h \
helper.h \
share.h
#include <stdint.h> /* C99 5.2.4.2 Numerical limits */
#include <limits.h> /* C99 5.2.4.2 Numerical limits */
-#include <endian.h> /* Non-standard BIG_ENDIAN, LITTLE_ENDIAN, BYTE_ORDER */
+#include <lttng/ust-endian.h> /* Non-standard BIG_ENDIAN, LITTLE_ENDIAN, BYTE_ORDER */
#include <assert.h>
/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
--- /dev/null
+#ifndef _LTTNG_UST_ENDIAN_H
+#define _LTTNG_UST_ENDIAN_H
+
+/*
+ * lttng/ust-endian.h
+ *
+ * Copyright 2012 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * endian.h compatibility layer.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ */
+
+#ifdef __linux__
+#include <endian.h>
+#elif defined(__FreeBSD__)
+#include <machine/endian.h>
+#else
+#error "Please add support for your OS."
+#endif
+
+#ifndef FLOAT_WORD_ORDER
+#ifdef __FLOAT_WORD_ORDER
+#define FLOAT_WORD_ORDER __FLOAT_WORD_ORDER
+#else /* __FLOAT_WORD_ORDER */
+#define FLOAT_WORD_ORDER BYTE_ORDER
+#endif /* __FLOAT_WORD_ORDER */
+#endif /* FLOAT_WORD_ORDER */
+
+#endif /* _LTTNG_UST_ENDIAN_H */
#include <urcu/list.h>
#include <urcu/hlist.h>
-#include <uuid/uuid.h>
#include <stdint.h>
#include <lttng/ust-abi.h>
#include <lttng/ust-tracer.h>
-#include <endian.h>
+#include <lttng/ust-endian.h>
#include <float.h>
+#define LTTNG_UST_UUID_LEN 16
+
struct ltt_channel;
struct ltt_session;
struct lttng_ust_lib_ring_buffer_ctx;
.size = sizeof(_type) * CHAR_BIT, \
.alignment = lttng_alignof(_type) * CHAR_BIT, \
.signedness = lttng_is_signed_type(_type), \
- .reverse_byte_order = _byte_order != __BYTE_ORDER, \
+ .reverse_byte_order = _byte_order != BYTE_ORDER, \
.base = _base, \
.encoding = lttng_encode_##_encoding, \
}, \
- _float_mant_dig(_type), \
.mant_dig = _float_mant_dig(_type), \
.alignment = lttng_alignof(_type) * CHAR_BIT, \
- .reverse_byte_order = __BYTE_ORDER != __FLOAT_WORD_ORDER, \
+ .reverse_byte_order = BYTE_ORDER != FLOAT_WORD_ORDER, \
}, \
} \
/* Channel ID, available for consumer too */
unsigned int id;
/* Copy of session UUID for consumer (availability through shm) */
- uuid_t uuid; /* Trace session unique ID */
+ unsigned char uuid[LTTNG_UST_UUID_LEN]; /* Trace session unique ID */
};
struct ltt_session {
struct cds_list_head wildcards; /* Wildcard list head */
struct cds_list_head list; /* Session list */
unsigned int free_chan_id; /* Next chan ID to allocate */
- uuid_t uuid; /* Trace session unique ID */
+ unsigned char uuid[LTTNG_UST_UUID_LEN]; /* Trace session unique ID */
unsigned int metadata_dumped:1;
};
--- /dev/null
+#ifndef _LTTNG_UST_TID_H
+#define _LTTNG_UST_TID_H
+
+/*
+ * lttng/ust-tid.h
+ *
+ * Copyright 2012 (c) - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * gettid compatibility layer.
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ */
+
+#ifdef __linux__
+#include <syscall.h>
+#endif
+
+#if defined(_syscall0)
+_syscall0(pid_t, gettid)
+#elif defined(__NR_gettid)
+#include <unistd.h>
+static inline pid_t gettid(void)
+{
+ return syscall(__NR_gettid);
+}
+#else
+#include <sys/types.h>
+#include <unistd.h>
+
+/* Fall-back on getpid for tid if not available. */
+static inline pid_t gettid(void)
+{
+ return getpid();
+}
+#endif
+
+#endif /* _LTTNG_UST_TID_H */
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
-
#include <share.h>
+#include "lttng/ust-tid.h"
enum ust_loglevel {
UST_LOGLEVEL_UNKNOWN = 0,
do { \
sigsafe_print_err(UST_STR_COMPONENT "[%ld/%ld]: " fmt " (in %s() at " __FILE__ ":" UST_XSTR(__LINE__) ")\n", \
(long) getpid(), \
- (long) syscall(SYS_gettid), \
+ (long) gettid(), \
## args, __func__); \
fflush(stderr); \
} while(0)
#define ERR(fmt, args...) ERRMSG("Error: " fmt, ## args)
#define BUG(fmt, args...) ERRMSG("BUG: " fmt, ## args)
-#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE)
+#if !defined(__linux__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE))
+/*
+ * Version using XSI strerror_r.
+ */
#define PERROR(call, args...)\
do { \
char buf[200] = "Error in strerror_r()"; \
ERRMSG("Error: " call ": %s", ## args, buf); \
} while(0);
#else
+/*
+ * Version using GNU strerror_r, for linux with appropriate defines.
+ */
#define PERROR(call, args...)\
do { \
char *buf; \
#include <stdarg.h>
#include <stdio.h>
+#include "lttng/ust-tid.h"
#include "share.h"
enum ust_loglevel {
do { \
fprintf(stderr, UST_STR_COMPONENT "[%ld/%ld]: " fmt " (in %s() at " __FILE__ ":" XSTR(__LINE__) ")\n", \
(long) getpid(), \
- (long) syscall(SYS_gettid), \
+ (long) gettid(), \
## args, \
__func__); \
} while(0)
#define ERR(fmt, args...) ERRMSG("Error: " fmt, ## args)
#define BUG(fmt, args...) ERRMSG("BUG: " fmt, ## args)
-#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE)
+#if !defined(__linux__) || ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !defined(_GNU_SOURCE))
+/*
+ * Version using XSI strerror_r.
+ */
#define PERROR(call, args...)\
do { \
char buf[200] = "Error in strerror_r()"; \
ERRMSG("Error: " call ": %s", ## args, buf); \
} while(0);
#else
+/*
+ * Version using GNU strerror_r, for linux with appropriate defines.
+ */
#define PERROR(call, args...)\
do { \
char *buf; \
#include <unistd.h>
#include <assert.h>
#include <errno.h>
+#include <fcntl.h>
#include <ust-comm.h>
* libust threads require the close-on-exec flag for all
* resources so it does not leak file descriptors upon exec.
*/
- fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ fd = socket(PF_UNIX, SOCK_STREAM, 0);
if (fd < 0) {
perror("socket");
ret = fd;
goto error;
}
+ ret = fcntl(fd, F_SETFD, FD_CLOEXEC);
+ if (ret < 0) {
+ perror("fcntl");
+ goto error_fcntl;
+ }
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
return fd;
error_connect:
+error_fcntl:
close(fd);
error:
return ret;
lib_LTLIBRARIES = liblttng-ust-fork.la
liblttng_ust_fork_la_SOURCES = ustfork.c
liblttng_ust_fork_la_LIBADD = \
- -ldl \
$(top_builddir)/liblttng-ust/liblttng-ust.la
+
+if LTTNG_UST_BUILD_WITH_LIBDL
+liblttng_ust_fork_la_LIBADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+liblttng_ust_fork_la_LIBADD += -lc
+endif
+
libustfork_CFLAGS = -DUST_COMPONENT=liblttng-ust-fork -fno-strict-aliasing
#include <lttng/ust.h>
-struct user_desc;
-
pid_t fork(void)
{
static pid_t (*plibc_func)(void) = NULL;
return retval;
}
+#ifdef __linux__
+
+struct user_desc;
+
struct ustfork_clone_info {
int (*fn)(void *);
void *arg;
}
return retval;
}
+
+#elif defined (__FreeBSD__)
+
+pid_t rfork(int flags)
+{
+ static pid_t (*plibc_func)(void) = NULL;
+ sigset_t sigset;
+ pid_t retval;
+
+ if (plibc_func == NULL) {
+ plibc_func = dlsym(RTLD_NEXT, "rfork");
+ if (plibc_func == NULL) {
+ fprintf(stderr, "libustfork: unable to find \"rfork\" symbol\n");
+ return -1;
+ }
+ }
+
+ ust_before_fork(&sigset);
+ /* Do the real rfork */
+ retval = plibc_func();
+ if (retval == 0) {
+ /* child */
+ ust_after_fork_child(&sigset);
+ } else {
+ ust_after_fork_parent(&sigset);
+ }
+ return retval;
+}
+
+/*
+ * On BSD, no need to override vfork, because it runs in the context of
+ * the parent, with parent waiting until execve or exit is executed in
+ * the child.
+ */
+
+#else
+#warning "Unknown OS. You might want to ensure that fork/clone/vfork/fork handling is complete."
+#endif
liblttng_ust_libc_wrapper_la_SOURCES = \
lttng-ust-malloc.c \
ust_libc.h
-liblttng_ust_libc_wrapper_la_LIBADD = -ldl \
+liblttng_ust_libc_wrapper_la_LIBADD = \
-L$(top_builddir)/liblttng-ust/.libs \
-llttng-ust
+if LTTNG_UST_BUILD_WITH_LIBDL
+liblttng_ust_libc_wrapper_la_LIBADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+liblttng_ust_libc_wrapper_la_LIBADD += -lc
+endif
+
noinst_SCRIPTS = run
EXTRA_DIST = run
compat.h \
wait.h \
jhash.h \
- error.h
+ error.h \
+ lttng-ust-uuid.h
liblttng_ust_support_la_SOURCES = \
ltt-tracer.h \
liblttng_ust_la_LIBADD = \
-lpthread \
-lrt \
- -luuid \
-llttng-ust-tracepoint \
$(top_builddir)/snprintf/libustsnprintf.la \
$(top_builddir)/liblttng-ust-comm/liblttng-ust-comm.la \
liblttng-ust-runtime.la liblttng-ust-support.la
+if LTTNG_UST_BUILD_WITH_LIBUUID
+liblttng_ust_la_LIBADD += -luuid
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_UUID
+liblttng_ust_la_LIBADD += -lc
+endif
+
liblttng_ust_la_CFLAGS = -DUST_COMPONENT="liblttng_ust" -fno-strict-aliasing
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
-
-/*
- * Includes final \0.
- */
-#define CLOCK_UUID_LEN 37
+#include "lttng-ust-uuid.h"
/* TRACE CLOCK */
}
static __inline__
-const int trace_clock_uuid(char *uuid)
+int trace_clock_uuid(char *uuid)
{
int ret = 0;
size_t len;
if (!fp) {
return -ENOENT;
}
- len = fread(uuid, 1, CLOCK_UUID_LEN - 1, fp);
- if (len < CLOCK_UUID_LEN - 1) {
+ len = fread(uuid, 1, LTTNG_UST_UUID_STR_LEN - 1, fp);
+ if (len < LTTNG_UST_UUID_STR_LEN - 1) {
ret = -EINVAL;
goto end;
}
- uuid[CLOCK_UUID_LEN - 1] = '\0';
+ uuid[LTTNG_UST_UUID_STR_LEN - 1] = '\0';
end:
fclose(fp);
return ret;
* modified is included with the above copyright notice.
*/
-#include <sys/syscall.h>
+/*
+ * lttng_ust_getprocname.
+ */
+#ifdef __linux__
+
+#include <sys/prctl.h>
+
+#define LTTNG_UST_PROCNAME_LEN 17
+
+static inline
+void lttng_ust_getprocname(char *name)
+{
+ (void) prctl(PR_GET_NAME, (unsigned long) name, 0, 0, 0);
+}
+
+#elif defined(__FreeBSD__)
+#include <stdlib.h>
+#include <string.h>
-#ifdef __UCLIBC__
-#define __getcpu(cpu, node, cache) syscall(__NR_getcpu, cpu, node, cache)
+/*
+ * Limit imposed by Linux UST-sessiond ABI.
+ */
+#define LTTNG_UST_PROCNAME_LEN 17
+
+/*
+ * Acts like linux prctl, the string is not necessarily 0-terminated if
+ * 16-byte long.
+ */
static inline
-int sched_getcpu(void)
+void lttng_ust_getprocname(char *name)
{
- int c, s;
+ const char *bsd_name;
- s = __getcpu(&c, NULL, NULL);
- return (s == -1) ? s : c;
+ bsd_name = getprogname();
+ if (!bsd_name)
+ name[0] = '\0';
+ memcpy(name, bsd_name, LTTNG_UST_PROCNAME_LEN - 1);
}
-#endif /* __UCLIBC__ */
+
+#endif
+
+#include <errno.h>
+
+#ifndef ENODATA
+#define ENODATA ENOMSG
+#endif
+
#endif /* _UST_COMPAT_H */
*/
#include <urcu/compiler.h>
-#include <endian.h>
+#include <lttng/ust-endian.h>
/*
* Hash function
#define _GNU_SOURCE
#include <stdio.h>
-#include <endian.h>
#include <urcu/list.h>
#include <urcu/hlist.h>
#include <pthread.h>
-#include <uuid/uuid.h>
#include <errno.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <stddef.h>
#include <inttypes.h>
#include <time.h>
-#include <sys/prctl.h>
+#include <lttng/ust-endian.h>
#include "clock.h"
#include <urcu-bp.h>
#include <usterr-signal-safe.h>
#include <helper.h>
#include "error.h"
+#include "compat.h"
+#include "lttng-ust-uuid.h"
#include "tracepoint-internal.h"
#include "ltt-tracer.h"
#include "../libringbuffer/shm.h"
#include "jhash.h"
-#define PROCNAME_LEN 17
-
/*
* The sessions mutex is the centralized mutex across UST tracing
* control and probe registration. All operations within this file are
struct ltt_session *ltt_session_create(void)
{
struct ltt_session *session;
+ int ret;
session = zmalloc(sizeof(struct ltt_session));
if (!session)
CDS_INIT_LIST_HEAD(&session->chan);
CDS_INIT_LIST_HEAD(&session->events);
CDS_INIT_LIST_HEAD(&session->wildcards);
- uuid_generate(session->uuid);
+ ret = lttng_ust_uuid_generate(session->uuid);
+ if (ret != 0) {
+ session->uuid[0] = '\0';
+ }
cds_list_add(&session->list, &sessions);
return session;
}
int _ltt_session_metadata_statedump(struct ltt_session *session)
{
unsigned char *uuid_c = session->uuid;
- char uuid_s[37], clock_uuid_s[CLOCK_UUID_LEN];
+ char uuid_s[LTTNG_UST_UUID_STR_LEN],
+ clock_uuid_s[LTTNG_UST_UUID_STR_LEN];
struct ltt_channel *chan;
struct ltt_event *event;
int ret = 0;
- char procname[PROCNAME_LEN] = "";
+ char procname[LTTNG_UST_PROCNAME_LEN] = "";
if (!CMM_ACCESS_ONCE(session->active))
return 0;
goto end;
/* ignore error, just use empty string if error. */
- (void) prctl(PR_GET_NAME, (unsigned long) procname, 0, 0, 0);
- procname[PROCNAME_LEN - 1] = '\0';
+ lttng_ust_getprocname(procname);
+ procname[LTTNG_UST_PROCNAME_LEN - 1] = '\0';
ret = lttng_metadata_printf(session,
"env {\n"
" vpid = %d;\n"
#include <lttng/ust-events.h>
#include "lttng/bitfield.h"
#include "clock.h"
+#include "lttng-ust-uuid.h"
#include "ltt-tracer.h"
#include "../libringbuffer/frontend_types.h"
* Trace magic number.
* contains endianness information.
*/
- uint8_t uuid[16];
+ uint8_t uuid[LTTNG_UST_UUID_LEN];
uint32_t stream_id;
struct {
struct metadata_packet_header {
uint32_t magic; /* 0x75D11D57 */
- uint8_t uuid[16]; /* Unique Universal Identifier */
+ uint8_t uuid[LTTNG_UST_UUID_LEN]; /* Unique Universal Identifier */
uint32_t checksum; /* 0 if unused */
uint32_t content_size; /* in bits */
uint32_t packet_size; /* in bits */
* Dual LGPL v2.1/GPL v2 license.
*/
-#include <sys/prctl.h>
#include <lttng/ust-events.h>
#include <lttng/ust-tracer.h>
#include <lttng/ringbuffer-config.h>
#include <assert.h>
-
-#define PROCNAME_LEN 17 /* includes \0 */
+#include "compat.h"
/*
* We cache the result to ensure we don't trigger a system call for
static inline
char *wrapper_getprocname(void)
{
- int ret;
-
if (caa_unlikely(!cached_procname[0])) {
- ret = prctl(PR_GET_NAME, (unsigned long) cached_procname,
- 0, 0, 0);
- assert(!ret);
+ lttng_ust_getprocname(cached_procname);
+ cached_procname[LTTNG_UST_PROCNAME_LEN - 1] = '\0';
}
return cached_procname;
}
{
size_t size = 0;
- size += PROCNAME_LEN;
+ size += LTTNG_UST_PROCNAME_LEN;
return size;
}
char *procname;
procname = wrapper_getprocname();
- chan->ops->event_write(ctx, procname, PROCNAME_LEN);
+ chan->ops->event_write(ctx, procname, LTTNG_UST_PROCNAME_LEN);
}
int lttng_add_procname_to_ctx(struct lttng_ctx **ctx)
field->event_field.type.u.array.elem_type.u.basic.integer.reverse_byte_order = 0;
field->event_field.type.u.array.elem_type.u.basic.integer.base = 10;
field->event_field.type.u.array.elem_type.u.basic.integer.encoding = lttng_encode_UTF8;
- field->event_field.type.u.array.length = PROCNAME_LEN;
+ field->event_field.type.u.array.length = LTTNG_UST_PROCNAME_LEN;
field->get_size = procname_get_size;
field->record = procname_record;
return 0;
#include <lttng/ust-events.h>
#include <lttng/ust-tracer.h>
#include <lttng/ringbuffer-config.h>
-
-#ifdef __linux__
-#include <syscall.h>
-#endif
-
-#if defined(_syscall0)
-_syscall0(pid_t, gettid)
-#elif defined(__NR_gettid)
-static inline pid_t gettid(void)
-{
- return syscall(__NR_gettid);
-}
-#else
-#warning "use pid as tid"
-static inline pid_t gettid(void)
-{
- return getpid();
-}
-#endif
+#include <lttng/ust-tid.h>
/*
* We cache the result to ensure we don't trigger a system call for
#define _LGPL_SOURCE
#include <sys/types.h>
#include <sys/socket.h>
-#include <sys/prctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <usterr-signal-safe.h>
#include "tracepoint-internal.h"
#include "ltt-tracer-core.h"
+#include "compat.h"
/*
* Has lttng ust comm constructor been called ?
int register_app_to_sessiond(int socket)
{
ssize_t ret;
- int prctl_ret;
struct {
uint32_t major;
uint32_t minor;
reg_msg.uid = getuid();
reg_msg.gid = getgid();
reg_msg.bits_per_long = CAA_BITS_PER_LONG;
- prctl_ret = prctl(PR_GET_NAME, (unsigned long) reg_msg.name, 0, 0, 0);
- if (prctl_ret) {
- ERR("Error executing prctl");
- return -errno;
- }
+ lttng_ust_getprocname(reg_msg.name);
ret = ustcomm_send_unix_sock(socket, ®_msg, sizeof(reg_msg));
if (ret >= 0 && ret != sizeof(reg_msg))
--- /dev/null
+#ifndef _LTTNG_UST_UUID_H
+#define _LTTNG_UST_UUID_H
+
+/*
+ * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
+ * OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
+ *
+ * Permission is hereby granted to use or copy this program
+ * for any purpose, provided the above notices are retained on all copies.
+ * Permission to modify the code and to distribute modified code is granted,
+ * provided the above notices are retained, and a notice that the code was
+ * modified is included with the above copyright notice.
+ */
+
+#include <config.h>
+#include <lttng/ust-events.h> /* For LTTNG_UST_UUID_LEN */
+/*
+ * Includes final \0.
+ */
+#define LTTNG_UST_UUID_STR_LEN 37
+
+#ifdef LTTNG_UST_HAVE_LIBUUID
+#include <uuid/uuid.h>
+
+static inline
+int lttng_ust_uuid_generate(unsigned char *uuid_out)
+{
+ uuid_generate(uuid_out);
+ return 0;
+}
+
+#elif defined(LTTNG_UST_HAVE_LIBC_UUID)
+#include <uuid.h>
+#include <stdint.h>
+
+static inline
+int lttng_ust_uuid_generate(unsigned char *uuid_out)
+{
+ uint32_t status;
+
+ uuid_create((uuid_t *) uuid_out, &status);
+ if (status == uuid_s_ok)
+ return 0;
+ else
+ return -1;
+}
+
+#else
+#error "LTTng-UST needs to have a UUID generator configured."
+#endif
+
+#endif /* _LTTNG_UST_UUID_H */
/* arch-agnostic implementation */
-static inline int fls(unsigned int x)
+static inline int lttng_ust_fls(unsigned int x)
{
int r = 32;
{
int order;
- order = fls(count) - 1;
+ order = lttng_ust_fls(count) - 1;
if (count & (count - 1))
order++;
return order;
*/
#include <urcu/compiler.h>
-#include <sched.h>
#ifdef UST_VALGRIND
#else
+/*
+ * sched_getcpu.
+ */
+#ifdef __linux__
+
+#ifdef __UCLIBC__
+#include <sys/syscall.h>
+#define __getcpu(cpu, node, cache) syscall(__NR_getcpu, cpu, node, cache)
+/*
+ * If getcpu is not implemented in the kernel, use cpu 0 as fallback.
+ */
+static inline
+int lttng_ust_get_cpu(void)
+{
+ int cpu, ret;
+
+ ret = __getcpu(&cpu, NULL, NULL);
+ if (caa_unlikely(ret < 0))
+ return 0;
+ return c;
+}
+#else /* __UCLIBC__ */
+#include <sched.h>
+
/*
* If getcpu is not implemented in the kernel, use cpu 0 as fallback.
*/
return 0;
return cpu;
}
+#endif /* __UCLIBC__ */
+
+#elif defined(__FreeBSD__)
+
+/*
+ * FreeBSD does not allow query of CPU ID. Always use CPU number 0, with
+ * the assocated performance degradation on SMP.
+ */
+static inline
+int lttng_ust_get_cpu(void)
+{
+ return 0;
+}
+
+#else
+#error "Please add support for your OS into liblttng-ust/compat.h."
+#endif
#endif
#include "backend.h"
#include "frontend.h"
#include "shm.h"
+#include "../liblttng-ust/compat.h" /* For ENODATA */
#ifndef max
#define max(a, b) ((a) > (b) ? (a) : (b))
int shmfd, waitfd[2], ret, i, sigblocked = 0;
struct shm_object *obj;
char *memory_map;
- char tmp_name[NAME_MAX] = "ust-shm-tmp-XXXXXX";
+ char tmp_name[NAME_MAX] = "/ust-shm-tmp-XXXXXX";
sigset_t all_sigs, orig_sigs;
if (table->allocated_len >= table->size)
#include "local.h"
/* Flush a single file, or (if fp is NULL) all files. */
-int ust_safe_fflush(LFILE *fp)
+int ust_safe_fflush(LTTNG_UST_LFILE *fp)
{
if (fp == NULL)
}
int
-__sflush(LFILE *fp)
+__sflush(LTTNG_UST_LFILE *fp)
{
unsigned char *p;
int n, t;
/*
* file extension
*/
-struct __sfileext {
- struct __sbuf _ub; /* ungetc buffer */
+struct __lttng_ust_sfileext {
+ struct __lttng_ust_sbuf _ub; /* ungetc buffer */
struct wchar_io_data _wcio; /* wide char io status */
};
-#define _EXT(fp) ((struct __sfileext *)((fp)->_ext._base))
+#define _EXT(fp) ((struct __lttng_ust_sfileext *)((fp)->_ext._base))
#define _UB(fp) _EXT(fp)->_ub
#define _FILEEXT_INIT(fp) \
* to the three different kinds of output buffering is handled here.
*/
int
-__sfvwrite(LFILE *fp, struct __suio *uio)
+__sfvwrite(LTTNG_UST_LFILE *fp, struct __lttng_ust_suio *uio)
{
size_t len;
char *p;
- struct __siov *iov;
+ struct __lttng_ust_siov *iov;
int w, s;
char *nl;
int nlknown, nldist;
/*
* I/O descriptors for __sfvwrite().
*/
-struct __siov {
+struct __lttng_ust_siov {
void *iov_base;
size_t iov_len;
};
-struct __suio {
- struct __siov *uio_iov;
+struct __lttng_ust_suio {
+ struct __lttng_ust_siov *uio_iov;
int uio_iovcnt;
int uio_resid;
};
-extern int __sfvwrite(LFILE *, struct __suio *);
+extern int __sfvwrite(LTTNG_UST_LFILE *, struct __lttng_ust_suio *);
#include "wcio.h"
#include "fileext.h"
-int __sflush(LFILE *);
-LFILE *__sfp(void);
-int __srefill(LFILE *);
+int __sflush(LTTNG_UST_LFILE *);
+LTTNG_UST_LFILE *__sfp(void);
+int __srefill(LTTNG_UST_LFILE *);
int __sread(void *, char *, int);
int __swrite(void *, const char *, int);
fpos_t __sseek(void *, fpos_t, int);
int __sclose(void *);
void __sinit(void);
void _cleanup(void);
-void __smakebuf(LFILE *);
-int __swhatbuf(LFILE *, size_t *, int *);
-int _fwalk(int (*)(LFILE *));
-int __swsetup(LFILE *);
+void __smakebuf(LTTNG_UST_LFILE *);
+int __swhatbuf(LTTNG_UST_LFILE *, size_t *, int *);
+int _fwalk(int (*)(LTTNG_UST_LFILE *));
+int __swsetup(LTTNG_UST_LFILE *);
int __sflags(const char *, int *);
-wint_t __fgetwc_unlock(LFILE *);
+wint_t __fgetwc_unlock(LTTNG_UST_LFILE *);
extern void __atexit_register_cleanup(void (*)(void));
extern int __sdidinit;
/*
- * Return true if the given LFILE cannot be written now.
+ * Return true if the given LTTNG_UST_LFILE cannot be written now.
*/
#define cantwrite(fp) \
((((fp)->_flags & __SWR) == 0 || (fp)->_bf._base == NULL) && \
{
int ret;
char dummy;
- LFILE f;
- struct __sfileext fext;
+ LTTNG_UST_LFILE f;
+ struct __lttng_ust_sfileext fext;
/* While snprintf(3) specifies size_t stdio uses an int internally */
if (n > INT_MAX)
#include <stdarg.h>
-struct __sbuf {
+struct __lttng_ust_sbuf {
unsigned char *_base;
int _size;
};
* _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
*/
-typedef struct __sFILE {
+typedef struct __lttng_ust_sFILE {
unsigned char *_p; /* current position in (some) buffer */
int _r; /* read space left for getc() */
int _w; /* write space left for putc() */
short _flags; /* flags, below; this FILE is free if 0 */
short _file; /* fileno, if Unix descriptor, else -1 */
- struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
+ struct __lttng_ust_sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
int _lbfsize; /* 0 or -_bf._size, for inline putc */
/* operations */
int (*_write)(void *, const char *, int);
/* extension data, to avoid further ABI breakage */
- struct __sbuf _ext;
+ struct __lttng_ust_sbuf _ext;
/* data for long sequences of ungetc() */
unsigned char *_up; /* saved _p when _p is doing ungetc data */
int _ur; /* saved _r when _r is counting ungetc data */
unsigned char _nbuf[1]; /* guarantee a getc() buffer */
/* separate buffer for fgetln() when line crosses buffer boundary */
- struct __sbuf _lb; /* buffer for fgetln() */
+ struct __lttng_ust_sbuf _lb; /* buffer for fgetln() */
/* Unix stdio files get aligned to block boundaries on fseek() */
int _blksize; /* stat.st_blksize (may be != _bf._size) */
fpos_t _offset; /* current lseek offset */
-} LFILE;
+} LTTNG_UST_LFILE;
#define __SLBF 0x0001 /* line buffered */
#define __SNBF 0x0002 /* unbuffered */
#define __sferror(p) (((p)->_flags & __SERR) != 0)
-extern int ust_safe_fflush(LFILE *fp);
-extern int ust_safe_vfprintf(LFILE *fp, const char *fmt0, va_list ap);
+extern int ust_safe_fflush(LTTNG_UST_LFILE *fp);
+extern int ust_safe_vfprintf(LTTNG_UST_LFILE *fp, const char *fmt0, va_list ap);
extern size_t ust_safe_mbrtowc(wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
* then reset it so that it can be reused.
*/
static int
-__sprint(LFILE *fp, struct __suio *uio)
+__sprint(LTTNG_UST_LFILE *fp, struct __lttng_ust_suio *uio)
{
int err;
* worries about ungetc buffers and so forth.
*/
//static int
-//__sbprintf(LFILE *fp, const char *fmt, va_list ap)
+//__sbprintf(LTTNG_UST_LFILE *fp, const char *fmt, va_list ap)
//{
// int ret;
-// LFILE fake;
+// LTTNG_UST_LFILE fake;
// struct __sfileext fakeext;
// unsigned char buf[BUFSIZ];
//
#define CHARINT 0x0800 /* 8 bit integer */
#define MAXINT 0x1000 /* largest integer size (intmax_t) */
-int ust_safe_vfprintf(LFILE *fp, const char *fmt0, va_list ap)
+int ust_safe_vfprintf(LTTNG_UST_LFILE *fp, const char *fmt0, va_list ap)
{
char *fmt; /* format string */
int ch; /* character from fmt */
int n, n2; /* handy integers (short term usage) */
char *cp; /* handy char pointer (short term usage) */
- struct __siov *iovp; /* for PRINT macro */
+ struct __lttng_ust_siov *iovp; /* for PRINT macro */
int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int size; /* size of converted field or string */
const char *xdigs = NULL; /* digits for %[xX] conversion */
#define NIOV 8
- struct __suio uio; /* output information: summary */
- struct __siov iov[NIOV];/* ... and individual io vectors */
+ struct __lttng_ust_suio uio; /* output information: summary */
+ struct __lttng_ust_siov iov[NIOV];/* ... and individual io vectors */
char buf[BUF]; /* buffer with space for digits of uintmax_t */
char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
union arg *argtable; /* args, built due to positional arg */
* _wsetup returns 0 if OK to write, nonzero otherwise.
*/
int
-__swsetup(LFILE *fp)
+__swsetup(LTTNG_UST_LFILE *fp)
{
/* make sure stdio is set up */
// if (!__sdidinit)
noinst_PROGRAMS = demo
demo_SOURCES = demo.c ust_tests_demo.h
-# The demo program only depends on libdl.
-demo_LDFLAGS = -ldl
+# The demo program only depends on libdl/libc for dlopen().
+if LTTNG_UST_BUILD_WITH_LIBDL
+demo_LDADD = -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+demo_LDADD = -lc
+endif
+
executing the demo. Executing "demo" without the shell wrapper will not
provide any tracing support. This ensures the demo binary can be
distributed on distros without depending on having liblttng-ust.so in
-place. Note: the "demo" program must be compiled with "-ldl".
+place. Note: the "demo" program must be compiled with "-ldl" on Linux,
+with "-lc" on BSD.
The simplest command to trace the demo program are:
lttng create
libdummy_la_LIBADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
libdummy_la_LDFLAGS = -rpath /nowhere
dlopen_SOURCES = dlopen.c
-dlopen_LDADD = -ldl $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
+dlopen_LDADD = $(top_builddir)/libust/libust.la $(top_builddir)/libust-initializer.o
+
+if LTTNG_UST_BUILD_WITH_LIBDL
+dlopen_LDADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+dlopen_LDADD += -lc
+endif
noinst_SCRIPTS = run
EXTRA_DIST = run
noinst_PROGRAMS = hello
hello_SOURCES = hello.c
-hello_LDADD = -ldl liblttng-ust-provider-ust-test-hello.la
+hello_LDADD = liblttng-ust-provider-ust-test-hello.la
+
+if LTTNG_UST_BUILD_WITH_LIBDL
+hello_LDADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+hello_LDADD += -lc
+endif
noinst_SCRIPTS = run
EXTRA_DIST = run
hello_SOURCES = hello.cpp tp.c ust_tests_hello.h
hello_LDADD = $(top_builddir)/liblttng-ust/liblttng-ust.la
+if LTTNG_UST_BUILD_WITH_LIBDL
+hello_LDADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+hello_LDADD += -lc
+endif
+
noinst_SCRIPTS = run
EXTRA_DIST = run
hello_SOURCES = hello.c tp.c ust_tests_hello.h
hello_LDADD = $(top_builddir)/liblttng-ust/liblttng-ust.la
+if LTTNG_UST_BUILD_WITH_LIBDL
+hello_LDADD += -ldl
+endif
+if LTTNG_UST_BUILD_WITH_LIBC_DL
+hello_LDADD += -lc
+endif
+
noinst_SCRIPTS = run
EXTRA_DIST = run
+++ /dev/null
-# Example makefile for build outside of the LTTng-UST tree.
-
-hello:
- ${CC} -O2 -I. -o hello -ldl -llttng-ust hello.c tp.c
-
-.PHONY: clean
-clean:
- rm -f hello
--- /dev/null
+# Example makefile for build outside of the LTTng-UST tree.
+
+hello:
+ ${CC} -O2 -I. -o hello -lc -llttng-ust hello.c tp.c
+
+.PHONY: clean
+clean:
+ rm -f hello
--- /dev/null
+# Example makefile for build outside of the LTTng-UST tree.
+
+hello:
+ ${CC} -O2 -I. -o hello -ldl -llttng-ust hello.c tp.c
+
+.PHONY: clean
+clean:
+ rm -f hello
#include <ust-comm.h>
#include "../../libringbuffer/backend.h"
#include "../../libringbuffer/frontend.h"
+#include "../../liblttng-ust/compat.h" /* For ENODATA */
#define MAX_NR_STREAMS 64
#define MAX_NR_EVENTS 128
}
/* copy */
- outfd = open(outfile, O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC,
+ outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (outfd < 0) {
perror("open output");
#include <ust-comm.h>
#include <../../libringbuffer/backend.h>
#include <../../libringbuffer/frontend.h>
+#include "../../liblttng-ust/compat.h" /* For ENODATA */
#define NR_SESSIONS 4
#define NR_CHANNELS 1
}
/* copy */
- outfd = open(outfile, O_WRONLY | O_CREAT | O_LARGEFILE | O_TRUNC,
+ outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
if (outfd < 0) {
perror("open output");