----- On Feb 2, 2018, at 2:48 PM, Francis Deslauriers francis.deslauri...@efficios.com wrote:
> With this commit, it's now possible to dlclose() a library containing an > actively used probe provider. > > The destructor of such library will now iterate over all the sessions > and over all probe definitions to unregister them from the respective > callsites in the process. > > Signed-off-by: Francis Deslauriers <francis.deslauri...@efficios.com> > --- > liblttng-ust/lttng-events.c | 22 +++++++++++++++++++++- > liblttng-ust/lttng-probes.c | 5 ++++- > liblttng-ust/tracepoint.c | 43 ++++++++++++++++++++++++++++++++++--------- > 3 files changed, 59 insertions(+), 11 deletions(-) > > diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c > index 07385d7..698210c 100644 > --- a/liblttng-ust/lttng-events.c > +++ b/liblttng-ust/lttng-events.c > @@ -793,7 +793,7 @@ void lttng_create_event_if_missing(struct lttng_enabler > *enabler) > */ > void lttng_probe_provider_unregister_events(struct lttng_probe_desc > *provider_desc) > { > - int i; > + unsigned int i, j; shorter lines below whenever possible. > struct cds_list_head *sessionsp; > struct lttng_session *session; > struct cds_hlist_head *head; > @@ -867,7 +867,27 @@ void lttng_probe_provider_unregister_events(struct > lttng_probe_desc *provider_de > head = &session->events_ht.table[hash & > (LTTNG_UST_EVENT_HT_SIZE - 1)]; > cds_hlist_for_each_entry(event, node, head, hlist) { > if (event_desc == event->desc) { > + /* Destroy enums of the current event. > */ > + for (j = 0; j < event->desc->nr_fields; > j++) { > + const struct lttng_event_field > *field; > + const struct lttng_enum_desc > *enum_desc; > + struct lttng_enum *curr_enum; > + > + field = > &(event->desc->fields[j]); > + if (field->type.atype != > atype_enum) { > + continue; > + } > + > + enum_desc = > field->type.u.basic.enumeration.desc; > + curr_enum = > lttng_ust_enum_get_from_desc(session, enum_desc); > + if (curr_enum) { > + > _lttng_enum_destroy(curr_enum); > + } > + } > + > + /* Destroy event. */ > _lttng_event_destroy(event); > + > break; > } > } > diff --git a/liblttng-ust/lttng-probes.c b/liblttng-ust/lttng-probes.c > index a09497f..862b19e 100644 > --- a/liblttng-ust/lttng-probes.c > +++ b/liblttng-ust/lttng-probes.c > @@ -226,7 +226,10 @@ void lttng_probe_unregister(struct lttng_probe_desc > *desc) > cds_list_del(&desc->head); > else > cds_list_del(&desc->lazy_init_head); > - DBG("just unregistered probe %s", desc->provider); > + > + lttng_probe_provider_unregister_events(desc); > + DBG("just unregistered probes of provider %s", desc->provider); > + > ust_unlock(); > } > > diff --git a/liblttng-ust/tracepoint.c b/liblttng-ust/tracepoint.c > index 14b8231..8c630a6 100644 > --- a/liblttng-ust/tracepoint.c > +++ b/liblttng-ust/tracepoint.c > @@ -107,8 +107,8 @@ struct tracepoint_entry { > struct lttng_ust_tracepoint_probe *probes; > int refcount; /* Number of times armed. 0 if disarmed. */ > int callsite_refcount; /* how many libs use this tracepoint */ > - const char *signature; > - char name[0]; > + char *signature; > + char *name; > }; > > struct tp_probes { > @@ -132,6 +132,7 @@ struct callsite_entry { > struct cds_hlist_node hlist; /* hash table node */ > struct cds_list_head node; /* lib list of callsites node */ > struct lttng_ust_tracepoint *tp; > + bool tp_entry_callsite_ref; /* Has a tp_entry took a ref on this > callsite*/ missing space after callsite. Thanks, Mathieu > }; > > /* coverity[+alloc] */ > @@ -284,6 +285,8 @@ static struct tracepoint_entry *add_tracepoint(const char > *name, > struct cds_hlist_node *node; > struct tracepoint_entry *e; > size_t name_len = strlen(name); > + size_t sig_len = strlen(signature); > + size_t sig_off, name_off; > uint32_t hash; > > if (name_len > LTTNG_UST_SYM_NAME_LEN - 1) { > @@ -298,19 +301,29 @@ static struct tracepoint_entry *add_tracepoint(const > char > *name, > return ERR_PTR(-EEXIST); /* Already there */ > } > } > + > /* > - * Using zmalloc here to allocate a variable length element. Could > - * cause some memory fragmentation if overused. > + * Using zmalloc here to allocate a variable length elements: name and > + * signature. Could cause some memory fragmentation if overused. > */ > - e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1); > + name_off = sizeof(struct tracepoint_entry); > + sig_off = name_off + name_len + 1; > + > + e = zmalloc(sizeof(struct tracepoint_entry) + name_len + 1 + sig_len + > 1); > if (!e) > return ERR_PTR(-ENOMEM); > - memcpy(&e->name[0], name, name_len + 1); > + e->name = (char *) e + name_off; > + memcpy(e->name, name, name_len + 1); > e->name[name_len] = '\0'; > + > + e->signature = (char *) e + sig_off; > + memcpy(e->signature, signature, sig_len + 1); > + e->signature[sig_len] = '\0'; > + > e->probes = NULL; > e->refcount = 0; > e->callsite_refcount = 0; > - e->signature = signature; > + > cds_hlist_add_head(&e->hlist, head); > return e; > } > @@ -405,6 +418,7 @@ static void add_callsite(struct tracepoint_lib * lib, > struct > lttng_ust_tracepoin > if (!tp_entry) > return; > tp_entry->callsite_refcount++; > + e->tp_entry_callsite_ref = true; > } > > /* > @@ -417,7 +431,8 @@ static void remove_callsite(struct callsite_entry *e) > > tp_entry = get_tracepoint(e->tp->name); > if (tp_entry) { > - tp_entry->callsite_refcount--; > + if (e->tp_entry_callsite_ref) > + tp_entry->callsite_refcount--; > if (tp_entry->callsite_refcount == 0) > disable_tracepoint(e->tp); > } > @@ -453,10 +468,15 @@ static void tracepoint_sync_callsites(const char *name) > if (strncmp(name, tp->name, LTTNG_UST_SYM_NAME_LEN - 1)) > continue; > if (tp_entry) { > + if (!e->tp_entry_callsite_ref) { > + tp_entry->callsite_refcount++; > + e->tp_entry_callsite_ref = true; > + } > set_tracepoint(&tp_entry, tp, > !!tp_entry->refcount); > } else { > disable_tracepoint(tp); > + e->tp_entry_callsite_ref = false; > } > } > } > @@ -545,7 +565,12 @@ tracepoint_add_probe(const char *name, void > (*probe)(void), > void *data, > struct lttng_ust_tracepoint_probe *old; > > entry = get_tracepoint(name); > - if (!entry) { > + if (entry) { > + if (strcmp(entry->signature, signature) != 0) { > + ERR("Tracepoint and probe signature do not match."); > + return ERR_PTR(-EINVAL); > + } > + } else { > entry = add_tracepoint(name, signature); > if (IS_ERR(entry)) > return (struct lttng_ust_tracepoint_probe *)entry; > -- > 2.7.4 -- Mathieu Desnoyers EfficiOS Inc. http://www.efficios.com _______________________________________________ lttng-dev mailing list lttng-dev@lists.lttng.org https://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev