X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=src%2Flib%2Flttng-ust-tracepoint%2Ftracepoint.c;h=12bc561c3342693cbdafbefac0a87612b5852981;hb=6f78600e9600f413ebdf532e154d8946725d83fd;hp=939af88872b75daf0bdc2b21502dab0ec1856869;hpb=34f7f1421e4869381acf65d59cb1abb37df440df;p=lttng-ust.git diff --git a/src/lib/lttng-ust-tracepoint/tracepoint.c b/src/lib/lttng-ust-tracepoint/tracepoint.c index 939af888..12bc561c 100644 --- a/src/lib/lttng-ust-tracepoint/tracepoint.c +++ b/src/lib/lttng-ust-tracepoint/tracepoint.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -33,11 +34,11 @@ #include "common/err-ptr.h" /* Test compiler support for weak symbols with hidden visibility. */ -int __tracepoint_test_symbol1 __attribute__((weak, visibility("hidden"))); -void *__tracepoint_test_symbol2 __attribute__((weak, visibility("hidden"))); +int lttng_ust_tracepoint_test_symbol1 __attribute__((weak, visibility("hidden"))); +void *lttng_ust_tracepoint_test_symbol2 __attribute__((weak, visibility("hidden"))); struct { char a[24]; -} __tracepoint_test_symbol3 __attribute__((weak, visibility("hidden"))); +} lttng_ust_tracepoint_test_symbol3 __attribute__((weak, visibility("hidden"))); /* Set to 1 to enable tracepoint debug output */ static const int tracepoint_debug; @@ -74,8 +75,8 @@ static CDS_LIST_HEAD(libs); * The tracepoint mutex protects the library tracepoints, the hash table, and * the library list. * All calls to the tracepoint API must be protected by the tracepoint mutex, - * excepts calls to tracepoint_register_lib and - * tracepoint_unregister_lib, which take the tracepoint mutex themselves. + * excepts calls to lttng_ust_tracepoint_module_register and + * lttng_ust_tracepoint_module_unregister, which take the tracepoint mutex themselves. */ /* @@ -607,8 +608,41 @@ static void tracepoint_release_queue_add_old_probes(void *old) } } +/* + * Use a symbol of the previous ABI to detect if liblttng-ust-tracepoint.so.0 + * is loaded in the current process. + */ +#define LTTNG_UST_TRACEPOINT_SONAME_0_SYM "tracepoint_unregister_lib" + +static +void lttng_ust_tracepoint_check_soname_0(void) +{ + if (!dlsym(RTLD_DEFAULT, LTTNG_UST_TRACEPOINT_SONAME_0_SYM)) + return; + + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by lookup of ABI 0 symbol \"%s\" in the Global Symbol Table\n", + LTTNG_UST_TRACEPOINT_SONAME_0_SYM); +} + +/* + * Expose a canary symbol of the previous ABI to ensure we catch uses of a + * liblttng-ust-tracepoint.so.0 dlopen'd after .so.1 has been loaded. Use a + * different symbol than the detection code to ensure we don't detect ourself. + */ +int tracepoint_register_lib(void *arg0 __attribute__((unused)), int arg1 __attribute__((unused))); +int tracepoint_register_lib(void *arg0 __attribute__((unused)), int arg1 __attribute__((unused))) +{ + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by canary symbol \"%s\"\n", __func__); + + return -1; +} + /** - * __tracepoint_probe_register - Connect a probe to a tracepoint + * lttng_ust_tracepoint_provider_register - Connect a probe to a tracepoint * @name: tracepoint provider name * @name: tracepoint event name * @probe: probe handler @@ -617,12 +651,20 @@ static void tracepoint_release_queue_add_old_probes(void *old) * The probe address must at least be aligned on the architecture pointer size. * Called with the tracepoint mutex held. */ -int __tracepoint_probe_register(const char *provider_name, const char *event_name, +int lttng_ust_tracepoint_provider_register(const char *provider_name, const char *event_name, void (*probe)(void), void *data, const char *signature) { void *old; int ret = 0; + /* + * Check if we find a symbol of the previous ABI in the current process + * as different ABIs of liblttng-ust can't co-exist in a process. If we + * do so, emit a critical log message which will also abort if the + * LTTNG_UST_ABORT_ON_CRITICAL environment variable is set. + */ + lttng_ust_tracepoint_check_soname_0(); + DBG("Registering probe to tracepoint \"%s:%s\"", provider_name, event_name); pthread_mutex_lock(&tracepoint_mutex); @@ -640,7 +682,7 @@ end: } /* - * Caller needs to invoke __tracepoint_probe_release_queue() after + * Caller needs to invoke lttng_ust_tracepoint_probe_release_queue() after * calling lttng_ust_tp_probe_register_queue_release() one or multiple * times to ensure it does not leak memory. */ @@ -690,7 +732,7 @@ static void *tracepoint_remove_probe(const char *provider_name, const char *even * @probe: probe function pointer * @probe: probe data pointer */ -int __tracepoint_probe_unregister(const char *provider_name, const char *event_name, +int lttng_ust_tracepoint_provider_unregister(const char *provider_name, const char *event_name, void (*probe)(void), void *data) { void *old; @@ -712,7 +754,7 @@ end: } /* - * Caller needs to invoke __tracepoint_probe_release_queue() after + * Caller needs to invoke lttng_ust_tracepoint_probe_release_queue() after * calling lttng_ust_tp_probe_unregister_queue_release() one or multiple * times to ensure it does not leak memory. */ @@ -877,9 +919,9 @@ static void new_tracepoints(struct lttng_ust_tracepoint * const *start, * against recent liblttng-ust headers require a recent liblttng-ust * runtime for those tracepoints to be taken into account. */ -int tracepoint_register_lib(struct lttng_ust_tracepoint * const *tracepoints_start, +int lttng_ust_tracepoint_module_register(struct lttng_ust_tracepoint * const *tracepoints_start, int tracepoints_count); -int tracepoint_register_lib(struct lttng_ust_tracepoint * const *tracepoints_start, +int lttng_ust_tracepoint_module_register(struct lttng_ust_tracepoint * const *tracepoints_start, int tracepoints_count) { struct tracepoint_lib *pl, *iter; @@ -932,8 +974,8 @@ lib_added: return 0; } -int tracepoint_unregister_lib(struct lttng_ust_tracepoint * const *tracepoints_start); -int tracepoint_unregister_lib(struct lttng_ust_tracepoint * const *tracepoints_start) +int lttng_ust_tracepoint_module_unregister(struct lttng_ust_tracepoint * const *tracepoints_start); +int lttng_ust_tracepoint_module_unregister(struct lttng_ust_tracepoint * const *tracepoints_start) { struct tracepoint_lib *lib; @@ -968,15 +1010,15 @@ int tracepoint_unregister_lib(struct lttng_ust_tracepoint * const *tracepoints_s static void check_weak_hidden(void) { DBG("Your compiler treats weak symbols with hidden visibility for integer objects as %s between compile units part of the same module.", - &__tracepoint_test_symbol1 == lttng_ust_tp_check_weak_hidden1() ? + <tng_ust_tracepoint_test_symbol1 == lttng_ust_tp_check_weak_hidden1() ? "SAME address" : "DIFFERENT addresses"); DBG("Your compiler treats weak symbols with hidden visibility for pointer objects as %s between compile units part of the same module.", - &__tracepoint_test_symbol2 == lttng_ust_tp_check_weak_hidden2() ? + <tng_ust_tracepoint_test_symbol2 == lttng_ust_tp_check_weak_hidden2() ? "SAME address" : "DIFFERENT addresses"); DBG("Your compiler treats weak symbols with hidden visibility for 24-byte structure objects as %s between compile units part of the same module.", - &__tracepoint_test_symbol3 == lttng_ust_tp_check_weak_hidden3() ? + <tng_ust_tracepoint_test_symbol3 == lttng_ust_tp_check_weak_hidden3() ? "SAME address" : "DIFFERENT addresses"); } @@ -998,24 +1040,24 @@ void lttng_ust_tp_exit(void) /* * Create the wrapper symbols. */ -#undef tp_rcu_read_lock -#undef tp_rcu_read_unlock -#undef tp_rcu_dereference +#undef lttng_ust_tp_rcu_read_lock +#undef lttng_ust_tp_rcu_read_unlock +#undef lttng_ust_tp_rcu_dereference -void tp_rcu_read_lock(void); -void tp_rcu_read_lock(void) +void lttng_ust_tp_rcu_read_lock(void); +void lttng_ust_tp_rcu_read_lock(void) { lttng_ust_urcu_read_lock(); } -void tp_rcu_read_unlock(void); -void tp_rcu_read_unlock(void) +void lttng_ust_tp_rcu_read_unlock(void); +void lttng_ust_tp_rcu_read_unlock(void) { lttng_ust_urcu_read_unlock(); } -void *tp_rcu_dereference_sym(void *p); -void *tp_rcu_dereference_sym(void *p) +void *lttng_ust_tp_rcu_dereference_sym(void *p); +void *lttng_ust_tp_rcu_dereference_sym(void *p) { return lttng_ust_rcu_dereference(p); } @@ -1023,16 +1065,16 @@ void *tp_rcu_dereference_sym(void *p) /* * Programs that have threads that survive after they exit, and therefore call * library destructors, should disable the tracepoint destructors by calling - * tp_disable_destructors(). This will leak the tracepoint + * lttng_ust_tp_disable_destructors(). This will leak the tracepoint * instrumentation library shared object, leaving its teardown to the operating * system process teardown. * * To access and/or modify this value, users need to use a combination of * dlopen(3) and dlsym(3) to get an handle on the - * tp_disable_destructors and tp_get_destructors_state symbols below. + * lttng_ust_tp_disable_destructors and lttng_ust_tp_get_destructors_state symbols below. */ -void tp_disable_destructors(void); -void tp_disable_destructors(void) +void lttng_ust_tp_disable_destructors(void); +void lttng_ust_tp_disable_destructors(void) { uatomic_set(&tracepoint_destructors_state, 0); } @@ -1041,8 +1083,8 @@ void tp_disable_destructors(void) * Returns 1 if the destructors are enabled and should be executed. * Returns 0 if the destructors are disabled. */ -int tp_get_destructors_state(void); -int tp_get_destructors_state(void) +int lttng_ust_tp_get_destructors_state(void); +int lttng_ust_tp_get_destructors_state(void) { return uatomic_read(&tracepoint_destructors_state); }