Fix: filter bytecode and string memory leak on error
[lttng-tools.git] / src / bin / lttng-sessiond / event.c
index da6a2913fc217352734fe821306ff8ae4879775a..dd212f521010a4d9d87a16f616547169601119c6 100644 (file)
@@ -27,6 +27,7 @@
 #include "channel.h"
 #include "event.h"
 #include "kernel.h"
+#include "lttng-sessiond.h"
 #include "ust-ctl.h"
 #include "ust-app.h"
 #include "trace-kernel.h"
@@ -152,6 +153,7 @@ int event_kernel_disable_all(struct ltt_kernel_channel *kchan)
 
 /*
  * Enable kernel tracepoint event for a channel from the kernel session.
+ * We own filter_expression and filter.
  */
 int event_kernel_enable_tracepoint(struct ltt_kernel_channel *kchan,
                struct lttng_event *event)
@@ -409,6 +411,7 @@ error:
 
 /*
  * Enable UST tracepoint event for a channel from a UST session.
+ * We own filter_expression, filter, and exclusion.
  */
 int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
                struct ltt_ust_channel *uchan, struct lttng_event *event,
@@ -430,6 +433,10 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
        if (uevent == NULL) {
                uevent = trace_ust_create_event(event, filter_expression,
                        filter, exclusion);
+               /* We have passed ownership */
+               filter_expression = NULL;
+               filter = NULL;
+               exclusion = NULL;
                if (uevent == NULL) {
                        ret = LTTNG_ERR_UST_ENABLE_FAIL;
                        goto error;
@@ -477,6 +484,9 @@ int event_ust_enable_tracepoint(struct ltt_ust_session *usess,
 
 end:
        rcu_read_unlock();
+       free(filter_expression);
+       free(filter);
+       free(exclusion);
        return ret;
 
 error:
@@ -492,6 +502,9 @@ error:
                trace_ust_destroy_event(uevent);
        }
        rcu_read_unlock();
+       free(filter_expression);
+       free(filter);
+       free(exclusion);
        return ret;
 }
 
@@ -621,7 +634,7 @@ error:
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
 int event_jul_enable_all(struct ltt_ust_session *usess,
-               struct lttng_event *event)
+               struct lttng_event *event, struct lttng_filter_bytecode *filter)
 {
        int ret;
        struct jul_event *jevent;
@@ -632,7 +645,7 @@ int event_jul_enable_all(struct ltt_ust_session *usess,
        DBG("Event JUL enabling ALL events for session %" PRIu64, usess->id);
 
        /* Enable event on JUL application through TCP socket. */
-       ret = event_jul_enable(usess, event);
+       ret = event_jul_enable(usess, event, filter);
        if (ret != LTTNG_OK) {
                goto error;
        }
@@ -656,7 +669,8 @@ error:
  *
  * Return LTTNG_OK on success or else a LTTNG_ERR* code.
  */
-int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event)
+int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event,
+               struct lttng_filter_bytecode *filter)
 {
        int ret, created = 0;
        struct jul_event *jevent;
@@ -670,7 +684,7 @@ int event_jul_enable(struct ltt_ust_session *usess, struct lttng_event *event)
 
        jevent = jul_find_event(event->name, event->loglevel, &usess->domain_jul);
        if (!jevent) {
-               jevent = jul_create_event(event->name);
+               jevent = jul_create_event(event->name, filter);
                if (!jevent) {
                        ret = LTTNG_ERR_NOMEM;
                        goto error;
@@ -714,6 +728,9 @@ int event_jul_disable(struct ltt_ust_session *usess, char *event_name)
 {
        int ret;
        struct jul_event *jevent;
+       struct ltt_ust_event *uevent = NULL;
+       struct ltt_ust_channel *uchan = NULL;
+       char *ust_event_name;
 
        assert(usess);
        assert(event_name);
@@ -731,6 +748,40 @@ int event_jul_disable(struct ltt_ust_session *usess, char *event_name)
                goto end;
        }
 
+       /*
+        * Disable it on the UST side. First get the channel reference then find
+        * the event and finally disable it.
+        */
+       uchan = trace_ust_find_channel_by_name(usess->domain_global.channels,
+                       DEFAULT_JUL_CHANNEL_NAME);
+       if (!uchan) {
+               ret = LTTNG_ERR_UST_CHAN_NOT_FOUND;
+               goto error;
+       }
+
+       if (is_root) {
+               ust_event_name = DEFAULT_SYS_JUL_EVENT_NAME;
+       } else {
+               ust_event_name = DEFAULT_USER_JUL_EVENT_NAME;
+       }
+
+       /*
+        * The loglevel is hardcoded with 0 here since the JUL ust event is set
+        * with the loglevel type to ALL thus the loglevel stays 0. The event's
+        * filter is the one handling the loglevel for JUL.
+        */
+       uevent = trace_ust_find_event(uchan->events, ust_event_name,
+                       jevent->filter, 0, NULL);
+       /* If the JUL event exists, it must be available on the UST side. */
+       assert(uevent);
+
+       ret = ust_app_disable_event_glb(usess, uchan, uevent);
+       if (ret < 0 && ret != -LTTNG_UST_ERR_EXIST) {
+               ret = LTTNG_ERR_UST_DISABLE_FAIL;
+               goto error;
+       }
+       uevent->enabled = 0;
+
        ret = jul_disable_event(jevent);
        if (ret != LTTNG_OK) {
                goto error;
This page took 0.025316 seconds and 4 git commands to generate.