Fix: Add signature check in tracepoint activation
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 1 Mar 2012 22:03:09 +0000 (17:03 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 1 Mar 2012 22:03:09 +0000 (17:03 -0500)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/lttng/tracepoint.h
liblttng-ust/ltt-events.c
liblttng-ust/tracepoint-internal.h
liblttng-ust/tracepoint.c

index b43f8f98458932e3f0c745e73f246a65717df54a..b1c2d360feffb3de46aa53237ba4d5cd2843d416 100644 (file)
@@ -149,7 +149,8 @@ end:                                                                                        \
 static inline void __tracepoint_register_##_provider##___##_name(char *name,           \
                void *func, void *data)                                                 \
 {                                                                                      \
-       __tracepoint_probe_register(name, func, data);                                  \
+       __tracepoint_probe_register(name, func, data,                                   \
+               __tracepoint_##_provider##___##_name.signature);                        \
 }                                                                                      \
 static inline void __tracepoint_unregister_##_provider##___##_name(char *name,         \
                void *func, void *data)                                                 \
@@ -157,7 +158,8 @@ 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_register(const char *name, void *func, void *data,
+               const char *signature);
 extern int __tracepoint_probe_unregister(const char *name, void *func, void *data);
 
 /*
index 72e315ec8593bb229f83788a681f84aae3e36147..ce4c2bb01719baab3b8bbf0f52fded018881bfef 100644 (file)
@@ -279,7 +279,7 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
                remove_pending_probe(e);
                ret |= __tracepoint_probe_register(name,
                                event->desc->probe_callback,
-                               event);
+                               event, event->desc->signature);
                if (ret)
                        continue;
                event->id = chan->free_event_id++;
@@ -550,7 +550,7 @@ int ltt_event_create(struct ltt_channel *chan,
                if (event->desc) {
                        ret = __tracepoint_probe_register(event_param->name,
                                        event->desc->probe_callback,
-                                       event);
+                                       event, event->desc->signature);
                        if (ret)
                                goto register_error;
                        event->id = chan->free_event_id++;
index d302e6ba34d2d6792d85eaf42b08152b869ecddf..98688ace8bd80c0a31aaefa7eb152fa9238565a7 100644 (file)
@@ -31,8 +31,11 @@ struct tracepoint_lib {
        int tracepoints_count;
 };
 
-extern int tracepoint_probe_register_noupdate(const char *name, void *callback, void *priv);
-extern int tracepoint_probe_unregister_noupdate(const char *name, void *callback, void *priv);
+extern int tracepoint_probe_register_noupdate(const char *name,
+               void *callback, void *priv,
+               const char *signature);
+extern int tracepoint_probe_unregister_noupdate(const char *name,
+               void *callback, void *priv);
 extern void tracepoint_probe_update_all(void);
 
 /*
index 7144fab40003c586a726fff5a6b4544f14d4c36c..a14c8b34303e43dc40be48cd3aefcd89a31c2197 100644 (file)
@@ -94,6 +94,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];
 };
 
@@ -243,7 +244,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 +276,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 +298,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 +390,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 *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 +417,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 *data,
+               const char *signature)
 {
        void *old;
        int ret = 0;
@@ -404,7 +426,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;
@@ -477,13 +499,13 @@ 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)
+                                      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;
This page took 0.028514 seconds and 4 git commands to generate.