X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=liblttng-ust%2Ftracepoint.c;h=a71e3e6e3967ea59bee850fe717fadad08b1669a;hb=e81a53afbf8fc88951cace52adc45bb02994fe55;hp=3a50df66a08de552256a342987c153dbcdd701e0;hpb=efa2c5917d9fb8dc40114e35b0da6916cc1d0422;p=lttng-ust.git diff --git a/liblttng-ust/tracepoint.c b/liblttng-ust/tracepoint.c index 3a50df66..a71e3e6e 100644 --- a/liblttng-ust/tracepoint.c +++ b/liblttng-ust/tracepoint.c @@ -31,6 +31,7 @@ #include #include +#include /* for LTTNG_UST_SYM_NAME_LEN */ #include #include @@ -207,11 +208,17 @@ static struct tracepoint_entry *get_tracepoint(const char *name) struct cds_hlist_head *head; struct cds_hlist_node *node; struct tracepoint_entry *e; - uint32_t hash = jhash(name, strlen(name), 0); + size_t name_len = strlen(name); + uint32_t hash; + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; cds_hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) + if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) return e; } return NULL; @@ -226,12 +233,17 @@ static struct tracepoint_entry *add_tracepoint(const char *name) struct cds_hlist_head *head; struct cds_hlist_node *node; struct tracepoint_entry *e; - size_t name_len = strlen(name) + 1; - uint32_t hash = jhash(name, name_len-1, 0); + size_t name_len = strlen(name); + uint32_t hash; + if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN - 1); + name_len = LTTNG_UST_SYM_NAME_LEN - 1; + } + hash = jhash(name, name_len, 0); head = &tracepoint_table[hash & (TRACEPOINT_TABLE_SIZE - 1)]; cds_hlist_for_each_entry(e, node, head, hlist) { - if (!strcmp(name, e->name)) { + if (!strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) { DBG("tracepoint %s busy", name); return ERR_PTR(-EEXIST); /* Already there */ } @@ -240,10 +252,11 @@ static struct tracepoint_entry *add_tracepoint(const char *name) * Using zmalloc here to allocate a variable length element. Could * cause some memory fragmentation if overused. */ - e = zmalloc(sizeof(struct tracepoint_entry) + name_len); + e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1); if (!e) return ERR_PTR(-ENOMEM); - memcpy(&e->name[0], name, name_len); + memcpy(&e->name[0], name, name_len + 1); + e->name[name_len] = '\0'; e->probes = NULL; e->refcount = 0; cds_hlist_add_head(&e->hlist, head); @@ -266,7 +279,7 @@ static void remove_tracepoint(struct tracepoint_entry *e) static void set_tracepoint(struct tracepoint_entry **entry, struct tracepoint *elem, int active) { - WARN_ON(strcmp((*entry)->name, elem->name) != 0); + WARN_ON(strncmp((*entry)->name, elem->name, LTTNG_UST_SYM_NAME_LEN - 1) != 0); /* * rcu_assign_pointer has a cmm_smp_wmb() which makes sure that the new @@ -511,6 +524,20 @@ static void new_tracepoints(struct tracepoint * const *start, struct tracepoint } } +static +void lib_disable_tracepoints(struct tracepoint * const *begin, + struct tracepoint * const *end) +{ + struct tracepoint * const *iter; + + for (iter = begin; iter < end; iter++) { + if (!*iter) + continue; /* skip dummy */ + disable_tracepoint(*iter); + } + +} + int tracepoint_register_lib(struct tracepoint * const *tracepoints_start, int tracepoints_count) { @@ -553,18 +580,34 @@ lib_added: int tracepoint_unregister_lib(struct tracepoint * const *tracepoints_start) { struct tracepoint_lib *lib; + int tracepoints_count; ust_lock(); cds_list_for_each_entry(lib, &libs, list) { if (lib->tracepoints_start == tracepoints_start) { struct tracepoint_lib *lib2free = lib; + cds_list_del(&lib->list); + tracepoints_count = lib->tracepoints_count; free(lib2free); - break; + goto found; } } + goto end; +found: + /* + * Force tracepoint disarm for all tracepoints of this lib. + * This takes care of destructor of library that would leave a + * LD_PRELOAD wrapper override function enabled for tracing, but + * the session teardown would not be able to reach the + * tracepoint anymore to disable it. + */ + lib_disable_tracepoints(tracepoints_start, + tracepoints_start + tracepoints_count); + DBG("just unregistered a tracepoints section from %p", + tracepoints_start); +end: ust_unlock(); - return 0; } @@ -579,3 +622,25 @@ void exit_tracepoint(void) { initialized = 0; } + +/* + * Create the wrapper symbols. + */ +#undef tp_rcu_read_lock_bp +#undef tp_rcu_read_unlock_bp +#undef tp_rcu_dereference_bp + +void tp_rcu_read_lock_bp(void) +{ + rcu_read_lock_bp(); +} + +void tp_rcu_read_unlock_bp(void) +{ + rcu_read_unlock_bp(); +} + +void *tp_rcu_dereference_sym_bp(void *p) +{ + return rcu_dereference_bp(p); +}