callsite: add "ip" context
[lttng-ust.git] / liblttng-ust / ltt-events.c
index ab099e1aba89afedb6a9456c0768509277500a8c..6b9170a03ed63b0feb5f680c41cedd2b728d4345 100644 (file)
@@ -98,6 +98,14 @@ struct ust_pending_probe {
        char name[];
 };
 
+/*
+ * Callsite hash table, containing the registered callsites.
+ * Protected by the sessions mutex.
+ */
+#define CALLSITE_HASH_BITS             6
+#define CALLSITE_HASH_SIZE             (1 << CALLSITE_HASH_BITS)
+static struct cds_hlist_head callsite_table[CALLSITE_HASH_SIZE];
+
 static void _ltt_event_destroy(struct ltt_event *event);
 static void _ltt_wildcard_destroy(struct session_wildcard *sw);
 static void _ltt_channel_destroy(struct ltt_channel *chan);
@@ -107,6 +115,10 @@ int _ltt_event_metadata_statedump(struct ltt_session *session,
                                  struct ltt_channel *chan,
                                  struct ltt_event *event);
 static
+int _ltt_callsite_metadata_statedump(struct ltt_session *session,
+                                 struct lttng_callsite *callsite);
+
+static
 int _ltt_session_metadata_statedump(struct ltt_session *session);
 
 int ltt_loglevel_match(const struct lttng_event_desc *desc,
@@ -246,9 +258,10 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
 
                                memcpy(&event_param, &sw->event_param,
                                                sizeof(event_param));
-                               memcpy(event_param.name,
+                               strncpy(event_param.name,
                                        desc->name,
                                        sizeof(event_param.name));
+                               event_param.name[sizeof(event_param.name) - 1] = '\0';
                                /* create event */
                                ret = ltt_event_create(sw->chan,
                                        &event_param, &ev);
@@ -302,6 +315,104 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc)
        return ret;
 }
 
+/*
+ * Called at library load: add callsite information.
+ * Takes the session mutex.
+ * Should _not_ be called with tracepoint mutex held (would cause
+ * deadlock with session mutex).
+ */
+int lttng_callsite_add(const struct tracepoint_callsite *tp_cs)
+{
+       struct cds_hlist_head *head;
+       struct lttng_callsite *cs_node;
+       struct ltt_session *session;
+       uint32_t hash;
+       int ret;
+
+       ust_lock();
+       /* hash by pointer value */
+       hash = jhash(&tp_cs, sizeof(tp_cs), 0);
+       head = &callsite_table[hash & (CALLSITE_HASH_SIZE - 1)];
+       cs_node = zmalloc(sizeof(struct lttng_callsite));
+       if (!cs_node)
+               goto error_mem;
+       cds_hlist_add_head(&cs_node->node, head);
+       cs_node->tp_cs = tp_cs;
+
+       /* print metadata for each session */
+       cds_list_for_each_entry(session, &sessions, list) {
+               ret = _ltt_callsite_metadata_statedump(session, cs_node);
+               assert(!ret);
+       }
+       ust_unlock();
+       return 0;
+
+error_mem:
+       ust_unlock();
+       return -ENOMEM;
+}
+
+/*
+ * Called at library unload: remove callsite information.
+ * Takes the session mutex.
+ * Should _not_ be called with tracepoint mutex held (would cause
+ * deadlock with session mutex).
+ */
+int lttng_callsite_remove(const struct tracepoint_callsite *tp_cs)
+{
+       struct cds_hlist_head *head;
+       struct cds_hlist_node *node;
+       struct lttng_callsite *cs_node;
+       uint32_t hash;
+       int found = 0;
+
+       ust_lock();
+       /* hash by pointer value */
+       hash = jhash(&tp_cs, sizeof(tp_cs), 0);
+       head = &callsite_table[hash & (CALLSITE_HASH_SIZE - 1)];
+       cds_hlist_for_each_entry(cs_node, node, head, node) {
+               if (cs_node->tp_cs == tp_cs) {
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found)
+               goto error;
+       cds_hlist_del(&cs_node->node);
+       free(cs_node);
+       ust_unlock();
+       return 0;
+
+error:
+       ust_unlock();
+       return -ENOENT;
+}
+
+/*
+ * Called with ust mutex held.
+ */
+static
+int _callsite_session_metadata_statedump(struct ltt_session *session)
+{
+       int ret = 0;
+       unsigned int i;
+
+       for (i = 0; i < CALLSITE_HASH_SIZE; i++) {
+               struct cds_hlist_head *head;
+               struct cds_hlist_node *node;
+               struct lttng_callsite *cs_node;
+
+               head = &callsite_table[i];
+               cds_hlist_for_each_entry(cs_node, node, head, node) {
+                       ret = _ltt_callsite_metadata_statedump(session,
+                                                       cs_node);
+                       if (ret)
+                               return ret;
+               }
+       }
+       return ret;
+}
+
 void synchronize_trace(void)
 {
        synchronize_rcu();
@@ -892,6 +1003,34 @@ int _ltt_fields_metadata_statedump(struct ltt_session *session,
        return ret;
 }
 
+static
+int _ltt_callsite_metadata_statedump(struct ltt_session *session,
+                                 struct lttng_callsite *callsite)
+{
+       int ret = 0;
+
+       if (!CMM_ACCESS_ONCE(session->active))
+               return 0;
+
+       ret = lttng_metadata_printf(session,
+               "callsite {\n"
+               "       name = \"%s\";\n"
+               "       func = \"%s\";\n"
+               "       ip = %p;\n"
+               "       file = \"%s\";\n"
+               "       line = %u;\n"
+               "};\n\n",
+               callsite->tp_cs->name,
+               callsite->tp_cs->func,
+               callsite->tp_cs->ip,
+               callsite->tp_cs->file,
+               callsite->tp_cs->lineno);
+       if (ret)
+               goto end;
+end:
+       return ret;
+}
+
 static
 int _ltt_event_metadata_statedump(struct ltt_session *session,
                                  struct ltt_channel *chan,
@@ -930,6 +1069,14 @@ int _ltt_event_metadata_statedump(struct ltt_session *session,
        if (ret)
                goto end;
 
+       if (event->desc->u.ext.model_emf_uri) {
+               ret = lttng_metadata_printf(session,
+                       "       model.emf.uri = \"%s\";\n",
+                       *(event->desc->u.ext.model_emf_uri));
+               if (ret)
+                       goto end;
+       }
+
        if (event->ctx) {
                ret = lttng_metadata_printf(session,
                        "       context := struct {\n");
@@ -1026,9 +1173,9 @@ int _ltt_stream_packet_context_declare(struct ltt_session *session)
                "struct packet_context {\n"
                "       uint64_clock_monotonic_t timestamp_begin;\n"
                "       uint64_clock_monotonic_t timestamp_end;\n"
+               "       uint64_t content_size;\n"
+               "       uint64_t packet_size;\n"
                "       unsigned long events_discarded;\n"
-               "       uint32_t content_size;\n"
-               "       uint32_t packet_size;\n"
                "       uint32_t cpu_id;\n"
                "};\n\n"
                );
@@ -1256,6 +1403,9 @@ int _ltt_session_metadata_statedump(struct ltt_session *session)
        ret = _ltt_event_header_declare(session);
        if (ret)
                goto end;
+       ret = _callsite_session_metadata_statedump(session);
+       if (ret)
+               goto end;
 
 skip_session:
        cds_list_for_each_entry(chan, &session->chan, list) {
This page took 0.025249 seconds and 4 git commands to generate.