Print compiler warning/runtime warning and truncate too long tracepoint names
[lttng-ust.git] / liblttng-ust / tracepoint.c
index e8241e8abd3cd29dfb0931f0edc2abbf17a43fe3..f146d382b7717955875938a1169d8436515ee043 100644 (file)
@@ -31,6 +31,7 @@
 #include <urcu/compiler.h>
 
 #include <lttng/tracepoint.h>
+#include <lttng/ust-abi.h>     /* for LTTNG_UST_SYM_NAME_LEN */
 
 #include <usterr-signal-safe.h>
 #include <helper.h>
@@ -45,7 +46,10 @@ static const int tracepoint_debug;
 static int initialized;
 static void (*new_tracepoint_cb)(struct tracepoint *);
 
-/* libraries that contain tracepoints (struct tracepoint_lib) */
+/*
+ * libraries that contain tracepoints (struct tracepoint_lib).
+ * Protected by UST lock.
+ */
 static CDS_LIST_HEAD(libs);
 
 /*
@@ -58,7 +62,7 @@ static CDS_LIST_HEAD(libs);
 
 /*
  * Tracepoint hash table, containing the active tracepoints.
- * Protected by tracepoints_mutex.
+ * Protected by ust lock.
  */
 #define TRACEPOINT_HASH_BITS 6
 #define TRACEPOINT_TABLE_SIZE (1 << TRACEPOINT_HASH_BITS)
@@ -71,7 +75,7 @@ static int need_update;
  * Note about RCU :
  * It is used to to delay the free of multiple probes array until a quiescent
  * state is reached.
- * Tracepoint entries modifications are protected by the tracepoints_mutex.
+ * Tracepoint entries modifications are protected by the ust lock.
  */
 struct tracepoint_entry {
        struct cds_hlist_node hlist;
@@ -87,14 +91,14 @@ struct tp_probes {
        struct tracepoint_probe probes[0];
 };
 
-static inline void *allocate_probes(int count)
+static void *allocate_probes(int count)
 {
        struct tp_probes *p  = zmalloc(count * sizeof(struct tracepoint_probe)
                        + sizeof(struct tp_probes));
        return p == NULL ? NULL : p->probes;
 }
 
-static inline void release_probes(void *old)
+static void release_probes(void *old)
 {
        if (old) {
                struct tp_probes *tp_probes = caa_container_of(old,
@@ -196,7 +200,7 @@ tracepoint_entry_remove_probe(struct tracepoint_entry *entry, void *probe,
 
 /*
  * Get tracepoint if the tracepoint is present in the tracepoint hash table.
- * Must be called with tracepoints_mutex held.
+ * Must be called with ust lock held.
  * Returns NULL if not present.
  */
 static struct tracepoint_entry *get_tracepoint(const char *name)
@@ -204,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;
@@ -216,19 +226,24 @@ static struct tracepoint_entry *get_tracepoint(const char *name)
 
 /*
  * Add the tracepoint to the tracepoint hash table. Must be called with
- * tracepoints_mutex held.
+ * ust lock held.
  */
 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 */
                }
@@ -237,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);
@@ -251,7 +267,7 @@ static struct tracepoint_entry *add_tracepoint(const char *name)
  * Remove the tracepoint from the tracepoint hash table. Must be called with
  * ust_lock held.
  */
-static inline void remove_tracepoint(struct tracepoint_entry *e)
+static void remove_tracepoint(struct tracepoint_entry *e)
 {
        cds_hlist_del(&e->hlist);
        free(e);
@@ -263,7 +279,7 @@ static inline 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
@@ -576,3 +592,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);
+}
This page took 0.024797 seconds and 4 git commands to generate.