From deb6e5408bafcab23cdd3e04b080134931d83906 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Sun, 27 Nov 2011 10:08:02 +0000 Subject: [PATCH] Allow weak binding from instrumented apps to liblttng-ust This introduce the TRACEPOINT_DEFINE macro. See demo program for usage example. This is an API change for instrumentation. Signed-off-by: Mathieu Desnoyers --- include/lttng/tracepoint-event.h | 3 +- include/lttng/tracepoint.h | 47 ++++++++++++++++++++++----- liblttng-ust/probes/lttng-probe-ust.c | 5 +-- tests/demo/Makefile.am | 19 +++++++++-- tests/demo/README | 8 ++++- tests/demo/demo.c | 6 +++- tests/demo/ust_tests_demo.h | 23 ------------- tests/fork/fork.c | 1 + tests/fork/fork2.c | 1 + tests/hello/hello.c | 1 + 10 files changed, 73 insertions(+), 41 deletions(-) diff --git a/include/lttng/tracepoint-event.h b/include/lttng/tracepoint-event.h index 94b0bcb1..9d757940 100644 --- a/include/lttng/tracepoint-event.h +++ b/include/lttng/tracepoint-event.h @@ -21,8 +21,7 @@ extern "C" { #define __tp_stringify(x) __tp_stringify1(x) #undef TRACEPOINT_EVENT_INSTANCE -#define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) \ - _DEFINE_TRACEPOINT(_provider, _name) +#define TRACEPOINT_EVENT_INSTANCE(_provider, _template, _name, _args) #undef TRACEPOINT_EVENT #define TRACEPOINT_EVENT(_provider, _name, _args, _fields) \ diff --git a/include/lttng/tracepoint.h b/include/lttng/tracepoint.h index dc7832cb..831447dd 100644 --- a/include/lttng/tracepoint.h +++ b/include/lttng/tracepoint.h @@ -17,6 +17,7 @@ #include #include #include +#include /* for dlopen */ #ifdef __cplusplus extern "C" { @@ -108,8 +109,10 @@ static inline void __tracepoint_cb_##provider##___##name(_TP_ARGS_PROTO(__VA_ARG { \ struct tracepoint_probe *__tp_probe; \ \ + if (!rcu_read_lock_bp) \ + return; \ rcu_read_lock_bp(); \ - __tp_probe = rcu_dereference(__tracepoint_##provider##___##name.probes); \ + __tp_probe = rcu_dereference_bp(__tracepoint_##provider##___##name.probes); \ if (caa_unlikely(!__tp_probe)) \ goto end; \ do { \ @@ -133,6 +136,11 @@ static inline void __tracepoint_unregister_##provider##___##name(char *name, \ __tracepoint_probe_unregister(name, func, data); \ } +extern int __tracepoint_probe_register(const char *name, void *func, void *data); +extern int __tracepoint_probe_unregister(const char *name, void *func, void *data); + +#ifdef TRACEPOINT_DEFINE + /* * Note: to allow PIC code, we need to allow the linker to update the pointers * in the __tracepoints_ptrs section. @@ -149,11 +157,10 @@ static inline void __tracepoint_unregister_##provider##___##name(char *name, \ __attribute__((used, section("__tracepoints_ptrs"))) = \ &__tracepoint_##provider##___##name; -extern int __tracepoint_probe_register(const char *name, void *func, void *data); -extern int __tracepoint_probe_unregister(const char *name, void *func, void *data); -extern int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, +static int (*tracepoint_register_lib)(struct tracepoint * const *tracepoints_start, int tracepoints_count); -extern int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start); +static int (*tracepoint_unregister_lib)(struct tracepoint * const *tracepoints_start); +static void *liblttngust_handle; /* * These weak symbols, the constructor, and destructor take care of @@ -171,6 +178,14 @@ static void __attribute__((constructor)) __tracepoints__init(void) { if (__tracepoint_registered++) return; + + liblttngust_handle = dlopen("liblttng-ust.so", RTLD_NOW | RTLD_GLOBAL); + if (!liblttngust_handle) + return; + tracepoint_register_lib = dlsym(liblttngust_handle, + "tracepoint_register_lib"); + tracepoint_unregister_lib = dlsym(liblttngust_handle, + "tracepoint_unregister_lib"); tracepoint_register_lib(__start___tracepoints_ptrs, __stop___tracepoints_ptrs - __start___tracepoints_ptrs); @@ -178,11 +193,25 @@ static void __attribute__((constructor)) __tracepoints__init(void) static void __attribute__((destructor)) __tracepoints__destroy(void) { + int ret; if (--__tracepoint_registered) return; - tracepoint_unregister_lib(__start___tracepoints_ptrs); + if (tracepoint_unregister_lib) + tracepoint_unregister_lib(__start___tracepoints_ptrs); + if (liblttngust_handle) { + tracepoint_unregister_lib = NULL; + tracepoint_register_lib = NULL; + ret = dlclose(liblttngust_handle); + assert(!ret); + } } +#else /* TRACEPOINT_DEFINE */ + +#define _DEFINE_TRACEPOINT(provider, name) + +#endif /* #else TRACEPOINT_DEFINE */ + #ifdef __cplusplus } #endif @@ -273,12 +302,14 @@ static void __attribute__((destructor)) __tracepoints__destroy(void) */ #define TRACEPOINT_EVENT(provider, name, args, fields) \ - _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) + _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \ + _DEFINE_TRACEPOINT(provider, name) #define TRACEPOINT_EVENT_CLASS(provider, name, args, fields) #define TRACEPOINT_EVENT_INSTANCE(provider, _template, name, args) \ - _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) + _DECLARE_TRACEPOINT(provider, name, _TP_PARAMS(args)) \ + _DEFINE_TRACEPOINT(provider, name) #endif /* #ifndef TRACEPOINT_EVENT */ diff --git a/liblttng-ust/probes/lttng-probe-ust.c b/liblttng-ust/probes/lttng-probe-ust.c index a5fba868..a5594c95 100644 --- a/liblttng-ust/probes/lttng-probe-ust.c +++ b/liblttng-ust/probes/lttng-probe-ust.c @@ -8,9 +8,6 @@ * Dual LGPL v2.1/GPL v2 license. */ -/* - * Create LTTng tracepoint probes. - */ +#define TRACEPOINT_DEFINE #define TRACEPOINT_CREATE_PROBES - #include "lttng-probe-ust.h" diff --git a/tests/demo/Makefile.am b/tests/demo/Makefile.am index 7ed5ce1e..1988dac4 100644 --- a/tests/demo/Makefile.am +++ b/tests/demo/Makefile.am @@ -1,5 +1,20 @@ AM_CPPFLAGS = -I$(top_srcdir)/include +lib_LTLIBRARIES = liblttng-ust-provider-ust-tests-demo.la \ + liblttng-ust-provider-ust-tests-demo3.la + +#contains ust_tests_demo.h and ust_tests_demo2.h provider probes +liblttng_ust_provider_ust_tests_demo_la_SOURCES = \ + tp.c ust_tests_demo.h \ + tp2.c ust_tests_demo2.h +liblttng_ust_provider_ust_tests_demo_la_LIBADD = \ + $(top_builddir)/liblttng-ust/liblttng-ust.la + +#contains ust_tests_demo3.h provider probes +liblttng_ust_provider_ust_tests_demo3_la_SOURCES = \ + tp3.c ust_tests_demo3.h +liblttng_ust_provider_ust_tests_demo3_la_LIBADD = \ + $(top_builddir)/liblttng-ust/liblttng-ust.la + noinst_PROGRAMS = demo -demo_SOURCES = demo.c tp.c ust_tests_demo.h -demo_LDADD = $(top_builddir)/liblttng-ust/liblttng-ust.la +demo_SOURCES = demo.c ust_tests_demo.h diff --git a/tests/demo/README b/tests/demo/README index 68b11e69..73becb0f 100644 --- a/tests/demo/README +++ b/tests/demo/README @@ -1 +1,7 @@ -This is a hello world application used to test the LTTng userspace tracer. +This is a demo application used to test the LTTng userspace tracer. + +demo-trace shell script preloads the provider shared objects before +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". diff --git a/tests/demo/demo.c b/tests/demo/demo.c index eff50529..3ab8bfd8 100644 --- a/tests/demo/demo.c +++ b/tests/demo/demo.c @@ -28,7 +28,10 @@ #include #include +#define TRACEPOINT_DEFINE #include "ust_tests_demo.h" +#include "ust_tests_demo2.h" +#include "ust_tests_demo3.h" int main(int argc, char **argv) { @@ -50,10 +53,11 @@ int main(int argc, char **argv) tracepoint(ust_tests_demo, starting, 123); for (i = 0; i < 5; i++) { netint = htonl(i); - tracepoint(ust_tests_demo, loop, i, netint, values, + tracepoint(ust_tests_demo2, loop, i, netint, values, text, strlen(text), dbl, flt); } tracepoint(ust_tests_demo, done, 456); + tracepoint(ust_tests_demo3, done, 42); fprintf(stderr, " done.\n"); return 0; } diff --git a/tests/demo/ust_tests_demo.h b/tests/demo/ust_tests_demo.h index d7493282..355867d2 100644 --- a/tests/demo/ust_tests_demo.h +++ b/tests/demo/ust_tests_demo.h @@ -29,29 +29,6 @@ TRACEPOINT_LOGLEVEL_ENUM( tp_loglevel(debug, 2) ) -TRACEPOINT_EVENT(ust_tests_demo, loop, - TP_ARGS(int, anint, int, netint, long *, values, - char *, text, size_t, textlen, - double, doublearg, float, floatarg), - TP_FIELDS( - ctf_integer(int, intfield, anint) - ctf_integer_hex(int, intfield2, anint) - ctf_integer(long, longfield, anint) - ctf_integer_network(int, netintfield, netint) - ctf_integer_network_hex(int, netintfieldhex, netint) - ctf_array(long, arrfield1, values, 3) - ctf_array_text(char, arrfield2, text, 10) - ctf_sequence(char, seqfield1, text, - size_t, textlen) - ctf_sequence_text(char, seqfield2, text, - size_t, textlen) - ctf_string(stringfield, text) - ctf_float(float, floatfield, floatarg) - ctf_float(double, doublefield, doublearg) - ) -) -TRACEPOINT_LOGLEVEL(ust_tests_demo, loop, debug) - TRACEPOINT_EVENT(ust_tests_demo, starting, TP_ARGS(int, value), TP_FIELDS( diff --git a/tests/fork/fork.c b/tests/fork/fork.c index f15a6925..0d290690 100644 --- a/tests/fork/fork.c +++ b/tests/fork/fork.c @@ -22,6 +22,7 @@ #include #include +#define TRACEPOINT_DEFINE #define TRACEPOINT_CREATE_PROBES #include "ust_tests_fork.h" diff --git a/tests/fork/fork2.c b/tests/fork/fork2.c index 5727f3f4..49baba8a 100644 --- a/tests/fork/fork2.c +++ b/tests/fork/fork2.c @@ -18,6 +18,7 @@ #include #include +#define TRACEPOINT_DEFINE #define TRACEPOINT_CREATE_PROBES #include "ust_tests_fork.h" diff --git a/tests/hello/hello.c b/tests/hello/hello.c index 68fca7a7..da33407b 100644 --- a/tests/hello/hello.c +++ b/tests/hello/hello.c @@ -28,6 +28,7 @@ #include #include +#define TRACEPOINT_DEFINE #include "ust_tests_hello.h" void inthandler(int sig) -- 2.34.1