X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=liblttng-ust%2Ftracepoint.c;h=d7293dab31697d94164f785b0aace9f9824da898;hb=refs%2Fheads%2Fstable-2.1;hp=7144fab40003c586a726fff5a6b4544f14d4c36c;hpb=05780d81d89c19ff3f9356796bb636a255f11077;p=lttng-ust.git diff --git a/liblttng-ust/tracepoint.c b/liblttng-ust/tracepoint.c index 7144fab4..d7293dab 100644 --- a/liblttng-ust/tracepoint.c +++ b/liblttng-ust/tracepoint.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ #include #include "tracepoint-internal.h" -#include "ltt-tracer-core.h" +#include "lttng-tracer-core.h" #include "jhash.h" #include "error.h" @@ -77,7 +78,7 @@ static CDS_LIST_HEAD(libs); * Tracepoint hash table, containing the active tracepoints. * Protected by tracepoint mutex. */ -#define TRACEPOINT_HASH_BITS 6 +#define TRACEPOINT_HASH_BITS 12 #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS) static struct cds_hlist_head tracepoint_table[TRACEPOINT_TABLE_SIZE]; @@ -94,6 +95,7 @@ struct tracepoint_entry { struct cds_hlist_node hlist; struct tracepoint_probe *probes; int refcount; /* Number of times armed. 0 if disarmed. */ + const char *signature; char name[0]; }; @@ -136,13 +138,15 @@ static void debug_print_probes(struct tracepoint_entry *entry) static void * tracepoint_entry_add_probe(struct tracepoint_entry *entry, - void *probe, void *data) + void (*probe)(void), void *data) { int nr_probes = 0; struct tracepoint_probe *old, *new; - WARN_ON(!probe); - + if (!probe) { + WARN_ON(1); + return ERR_PTR(-EINVAL); + } debug_print_probes(entry); old = entry->probes; if (old) { @@ -168,8 +172,8 @@ tracepoint_entry_add_probe(struct tracepoint_entry *entry, } static void * -tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe, - void *data) +tracepoint_entry_remove_probe(struct tracepoint_entry *entry, + void (*probe)(void), void *data) { int nr_probes = 0, nr_del = 0, i; struct tracepoint_probe *old, *new; @@ -243,7 +247,8 @@ static struct tracepoint_entry *get_tracepoint(const char *name) * Add the tracepoint to the tracepoint hash table. Must be called with * tracepoint mutex held. */ -static struct tracepoint_entry *add_tracepoint(const char *name) +static struct tracepoint_entry *add_tracepoint(const char *name, + const char *signature) { struct cds_hlist_head *head; struct cds_hlist_node *node; @@ -274,6 +279,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name) e->name[name_len] = '\0'; e->probes = NULL; e->refcount = 0; + e->signature = signature; cds_hlist_add_head(&e->hlist, head); return e; } @@ -295,6 +301,23 @@ static void set_tracepoint(struct tracepoint_entry **entry, struct tracepoint *elem, int active) { WARN_ON(strncmp((*entry)->name, elem->name, LTTNG_UST_SYM_NAME_LEN - 1) != 0); + /* + * Check that signatures match before connecting a probe to a + * tracepoint. Warn the user if they don't. + */ + if (strcmp(elem->signature, (*entry)->signature) != 0) { + static int warned = 0; + + /* Only print once, don't flood console. */ + if (!warned) { + WARN("Tracepoint signature mismatch, not enabling one or more tracepoints. Ensure that the tracepoint probes prototypes match the application."); + WARN("Tracepoint \"%s\" signatures: call: \"%s\" vs probe: \"%s\".", + elem->name, elem->signature, (*entry)->signature); + warned = 1; + } + /* Don't accept connecting non-matching signatures. */ + return; + } /* * rcu_assign_pointer has a cmm_smp_wmb() which makes sure that the new @@ -370,14 +393,15 @@ static void tracepoint_update_probes(void) } static struct tracepoint_probe * -tracepoint_add_probe(const char *name, void *probe, void *data) +tracepoint_add_probe(const char *name, void (*probe)(void), void *data, + const char *signature) { struct tracepoint_entry *entry; struct tracepoint_probe *old; entry = get_tracepoint(name); if (!entry) { - entry = add_tracepoint(name); + entry = add_tracepoint(name, signature); if (IS_ERR(entry)) return (struct tracepoint_probe *)entry; } @@ -396,7 +420,8 @@ tracepoint_add_probe(const char *name, void *probe, void *data) * 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 *name, void *probe, void *data) +int __tracepoint_probe_register(const char *name, void (*probe)(void), + void *data, const char *signature) { void *old; int ret = 0; @@ -404,7 +429,7 @@ int __tracepoint_probe_register(const char *name, void *probe, void *data) DBG("Registering probe to tracepoint %s", name); pthread_mutex_lock(&tracepoint_mutex); - old = tracepoint_add_probe(name, probe, data); + old = tracepoint_add_probe(name, probe, data, signature); if (IS_ERR(old)) { ret = PTR_ERR(old); goto end; @@ -417,7 +442,8 @@ end: return ret; } -static void *tracepoint_remove_probe(const char *name, void *probe, void *data) +static void *tracepoint_remove_probe(const char *name, void (*probe)(void), + void *data) { struct tracepoint_entry *entry; void *old; @@ -439,7 +465,8 @@ static void *tracepoint_remove_probe(const char *name, void *probe, void *data) * @probe: probe function pointer * @probe: probe data pointer */ -int __tracepoint_probe_unregister(const char *name, void *probe, void *data) +int __tracepoint_probe_unregister(const char *name, void (*probe)(void), + void *data) { void *old; int ret = 0; @@ -476,14 +503,14 @@ static void tracepoint_add_old_probes(void *old) * * caller must call tracepoint_probe_update_all() */ -int tracepoint_probe_register_noupdate(const char *name, void *probe, - void *data) +int tracepoint_probe_register_noupdate(const char *name, void (*probe)(void), + void *data, const char *signature) { void *old; int ret = 0; pthread_mutex_lock(&tracepoint_mutex); - old = tracepoint_add_probe(name, probe, data); + old = tracepoint_add_probe(name, probe, data, signature); if (IS_ERR(old)) { ret = PTR_ERR(old); goto end; @@ -502,7 +529,7 @@ end: * caller must call tracepoint_probe_update_all() * Called with the tracepoint mutex held. */ -int tracepoint_probe_unregister_noupdate(const char *name, void *probe, +int tracepoint_probe_unregister_noupdate(const char *name, void (*probe)(void), void *data) { void *old;