From: Mathieu Desnoyers Date: Mon, 13 May 2013 10:02:55 +0000 (-0400) Subject: Fix: incorrect support for multi-context X-Git-Tag: v2.2.0-rc3~24 X-Git-Url: http://git.liburcu.org/?p=lttng-ust.git;a=commitdiff_plain;h=83e43212040a26aca40a4f8fefaa3682e9edaa57 Fix: incorrect support for multi-context * Zifei Tong wrote: > I did some debugging one this issue. The problem only occurs when we > have more than one context field. > So this will not work, too: > > lttng create > lttng enable-event -a -u > lttng add-context -u -t vpid > lttng add-context -u -t vtid > lttng start > $@ > lttng stop > sleep 1 > lttng view > lttng destroy > > The problem I found out is wrong `fields` argument passed into > `ustcomm_register_channel`. > The `fields` argument passed is a pointer to the `event_field` of the > first element in a `lttng_ctx_field` array, but not a > `lttng_event_field` array as expected. Fixes #529 Reported-by: Francis Giraldeau Signed-off-by: Mathieu Desnoyers --- diff --git a/include/ust-comm.h b/include/ust-comm.h index 133426e5..7f268b7f 100644 --- a/include/ust-comm.h +++ b/include/ust-comm.h @@ -48,6 +48,7 @@ #define LTTNG_UST_COMM_REG_MSG_PADDING 64 struct lttng_event_field; +struct lttng_ctx_field; struct ustctl_reg_msg { uint32_t magic; @@ -226,7 +227,7 @@ int ustcomm_register_channel(int sock, int session_objd, /* session descriptor */ int channel_objd, /* channel descriptor */ size_t nr_ctx_fields, - const struct lttng_event_field *ctx_fields, + const struct lttng_ctx_field *ctx_fields, uint32_t *chan_id, /* channel id (output) */ int *header_type); /* header type (output) */ diff --git a/liblttng-ust-comm/lttng-ust-comm.c b/liblttng-ust-comm/lttng-ust-comm.c index 087424fe..5321922d 100644 --- a/liblttng-ust-comm/lttng-ust-comm.c +++ b/liblttng-ust-comm/lttng-ust-comm.c @@ -830,6 +830,47 @@ error_type: return ret; } +static +int serialize_ctx_fields(size_t *_nr_write_fields, + struct ustctl_field **ustctl_fields, + size_t nr_fields, + const struct lttng_ctx_field *lttng_fields) +{ + struct ustctl_field *fields; + int i, ret; + size_t nr_write_fields = 0; + + fields = zmalloc(nr_fields * sizeof(*fields)); + if (!fields) + return -ENOMEM; + + for (i = 0; i < nr_fields; i++) { + struct ustctl_field *f; + const struct lttng_event_field *lf; + + f = &fields[nr_write_fields]; + lf = <tng_fields[i].event_field; + + /* skip 'nowrite' fields */ + if (lf->nowrite) + continue; + strncpy(f->name, lf->name, LTTNG_UST_SYM_NAME_LEN); + f->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0'; + ret = serialize_one_type(&f->type, &lf->type); + if (ret) + goto error_type; + nr_write_fields++; + } + + *_nr_write_fields = nr_write_fields; + *ustctl_fields = fields; + return 0; + +error_type: + free(fields); + return ret; +} + /* * Returns 0 on success, negative error value on error. */ @@ -968,7 +1009,7 @@ int ustcomm_register_channel(int sock, int session_objd, /* session descriptor */ int channel_objd, /* channel descriptor */ size_t nr_ctx_fields, - const struct lttng_event_field *ctx_fields, + const struct lttng_ctx_field *ctx_fields, uint32_t *chan_id, /* channel id (output) */ int *header_type) /* header type (output) */ { @@ -982,7 +1023,7 @@ int ustcomm_register_channel(int sock, struct ustcomm_notify_channel_reply r; } reply; size_t fields_len; - struct ustctl_field *fields; + struct ustctl_field *fields = NULL; int ret; size_t nr_write_fields = 0; @@ -993,7 +1034,7 @@ int ustcomm_register_channel(int sock, /* Calculate fields len, serialize fields. */ if (nr_ctx_fields > 0) { - ret = serialize_fields(&nr_write_fields, &fields, + ret = serialize_ctx_fields(&nr_write_fields, &fields, nr_ctx_fields, ctx_fields); if (ret) return ret; diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c index e4faf605..a3127a47 100644 --- a/liblttng-ust/lttng-events.c +++ b/liblttng-ust/lttng-events.c @@ -260,7 +260,7 @@ int lttng_session_enable(struct lttng_session *session) */ cds_list_for_each_entry(chan, &session->chan_head, node) { const struct lttng_ctx *ctx; - const struct lttng_event_field *fields = NULL; + const struct lttng_ctx_field *fields = NULL; size_t nr_fields = 0; uint32_t chan_id; @@ -270,7 +270,7 @@ int lttng_session_enable(struct lttng_session *session) ctx = chan->ctx; if (ctx) { nr_fields = ctx->nr_fields; - fields = &ctx->fields->event_field; + fields = ctx->fields; } ret = ustcomm_register_channel(notify_socket, session->objd,