X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust-java-agent%2Fjni%2Fcommon%2Flttng_ust_context.c;h=ae478ba3c407c26ccd015ea9a2232454e763c5c7;hb=3b5babf8592ca27acaf01fca24406922fc5cc89c;hp=8cc4087f07548585f37254a3d79cf1d3146b6ffb;hpb=8ab5c06b92ac9a06ba2743470a38e4e1cfc6a3c9;p=lttng-ust.git diff --git a/liblttng-ust-java-agent/jni/common/lttng_ust_context.c b/liblttng-ust-java-agent/jni/common/lttng_ust_context.c index 8cc4087f..ae478ba3 100644 --- a/liblttng-ust-java-agent/jni/common/lttng_ust_context.c +++ b/liblttng-ust-java-agent/jni/common/lttng_ust_context.c @@ -1,20 +1,9 @@ /* - * Copyright (C) 2016 - EfficiOS Inc., Alexandre Montplaisir - * 2016 - EfficiOS Inc., Mathieu Desnoyers + * SPDX-License-Identifier: LGPL-2.1-only * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; only - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Copyright (C) 2016 EfficiOS Inc. + * Copyright (C) 2016 Alexandre Montplaisir + * Copyright (C) 2016 Mathieu Desnoyers */ #include "org_lttng_ust_agent_context_LttngContextApi.h" @@ -22,16 +11,12 @@ #include #include #include -#include -#include +#include +#include -#include "helper.h" +#include "ust-helper.h" #include "lttng_ust_context.h" -#define LTTNG_UST_JNI_CONTEXT_NAME_LEN 256 -/* TODO: the value should be variable length. */ -#define LTTNG_UST_JNI_VALUE_LEN 256 - enum lttng_ust_jni_type { JNI_TYPE_NULL = 0, JNI_TYPE_INTEGER = 1, @@ -44,8 +29,8 @@ enum lttng_ust_jni_type { JNI_TYPE_STRING = 8, }; -struct lttng_ust_jni_ctx { - char context_name[LTTNG_UST_JNI_CONTEXT_NAME_LEN]; +struct lttng_ust_jni_ctx_entry { + int32_t context_name_offset; char type; /* enum lttng_ust_jni_type */ union { int32_t _integer; @@ -55,33 +40,47 @@ struct lttng_ust_jni_ctx { signed char _byte; int16_t _short; signed char _boolean; - char _string[LTTNG_UST_JNI_VALUE_LEN]; + int32_t _string_offset; } value; } __attribute__((packed)); /* TLS passing context info from JNI to callbacks. */ __thread struct lttng_ust_jni_tls lttng_ust_context_info_tls; -static struct lttng_ust_jni_ctx *lookup_ctx_by_name(const char *ctx_name) +static const char *get_ctx_string_at_offset(int32_t offset) { - struct lttng_ust_jni_ctx *ctx_array = lttng_ust_context_info_tls.ctx; - int i, len = lttng_ust_context_info_tls.len / sizeof(struct lttng_ust_jni_ctx); + signed char *ctx_strings_array = lttng_ust_context_info_tls.ctx_strings; + + if (offset < 0 || offset >= lttng_ust_context_info_tls.ctx_strings_len) { + return NULL; + } + return (const char *) (ctx_strings_array + offset); +} + +static struct lttng_ust_jni_ctx_entry *lookup_ctx_by_name(const char *ctx_name) +{ + struct lttng_ust_jni_ctx_entry *ctx_entries_array = lttng_ust_context_info_tls.ctx_entries; + int i, len = lttng_ust_context_info_tls.ctx_entries_len / sizeof(struct lttng_ust_jni_ctx_entry); for (i = 0; i < len; i++) { - if (strcmp(ctx_array[i].context_name, ctx_name) == 0) - return &ctx_array[i]; + int32_t offset = ctx_entries_array[i].context_name_offset; + const char *string = get_ctx_string_at_offset(offset); + + if (string && strcmp(string, ctx_name) == 0) { + return &ctx_entries_array[i]; + } } return NULL; - } -static size_t get_size_cb(struct lttng_ctx_field *field, size_t offset) +static size_t get_size_cb(struct lttng_ust_ctx_field *field, size_t offset) { - struct lttng_ust_jni_ctx *jctx; + struct lttng_ust_jni_ctx_entry *jctx; size_t size = 0; - const char *ctx_name = field->event_field.name; + const char *ctx_name = field->event_field->name; enum lttng_ust_jni_type jni_type; + size += lib_ring_buffer_align(offset, lttng_alignof(char)); size += sizeof(char); /* tag */ jctx = lookup_ctx_by_name(ctx_name); @@ -119,8 +118,16 @@ static size_t get_size_cb(struct lttng_ctx_field *field, size_t offset) size += sizeof(char); /* variant */ break; case JNI_TYPE_STRING: - size += strlen(jctx->value._string) + 1; + { + /* The value is an offset, the string is in the "strings" array */ + int32_t string_offset = jctx->value._string_offset; + const char *string = get_ctx_string_at_offset(string_offset); + + if (string) { + size += strlen(string) + 1; + } break; + } default: abort(); } @@ -128,12 +135,12 @@ static size_t get_size_cb(struct lttng_ctx_field *field, size_t offset) } -static void record_cb(struct lttng_ctx_field *field, +static void record_cb(struct lttng_ust_ctx_field *field, struct lttng_ust_lib_ring_buffer_ctx *ctx, - struct lttng_channel *chan) + struct lttng_ust_channel_buffer *lttng_chan_buf) { - struct lttng_ust_jni_ctx *jctx; - const char *ctx_name = field->event_field.name; + struct lttng_ust_jni_ctx_entry *jctx; + const char *ctx_name = field->event_field->name; enum lttng_ust_jni_type jni_type; char sel_char; @@ -148,7 +155,7 @@ static void record_cb(struct lttng_ctx_field *field, case JNI_TYPE_NULL: sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); break; case JNI_TYPE_INTEGER: { @@ -156,9 +163,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_S32; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_LONG: @@ -167,9 +174,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_S64; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_DOUBLE: @@ -178,9 +185,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_DOUBLE; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_FLOAT: @@ -189,9 +196,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_FLOAT; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_SHORT: @@ -200,9 +207,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_S16; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_BYTE: @@ -211,9 +218,9 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_S8; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_BOOLEAN: @@ -222,19 +229,26 @@ static void record_cb(struct lttng_ctx_field *field, sel_char = LTTNG_UST_DYNAMIC_TYPE_S8; lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); lib_ring_buffer_align_ctx(ctx, lttng_alignof(v)); - chan->ops->event_write(ctx, &v, sizeof(v)); + lttng_chan_buf->ops->event_write(ctx, &v, sizeof(v)); break; } case JNI_TYPE_STRING: { - const char *str = jctx->value._string; - - sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING; + int32_t offset = jctx->value._string_offset; + const char *str = get_ctx_string_at_offset(offset); + + if (str) { + sel_char = LTTNG_UST_DYNAMIC_TYPE_STRING; + } else { + sel_char = LTTNG_UST_DYNAMIC_TYPE_NONE; + } lib_ring_buffer_align_ctx(ctx, lttng_alignof(char)); - chan->ops->event_write(ctx, &sel_char, sizeof(sel_char)); - chan->ops->event_write(ctx, str, strlen(str) + 1); + lttng_chan_buf->ops->event_write(ctx, &sel_char, sizeof(sel_char)); + if (str) { + lttng_chan_buf->ops->event_write(ctx, str, strlen(str) + 1); + } break; } default: @@ -242,11 +256,11 @@ static void record_cb(struct lttng_ctx_field *field, } } -static void get_value_cb(struct lttng_ctx_field *field, - struct lttng_ctx_value *value) +static void get_value_cb(struct lttng_ust_ctx_field *field, + struct lttng_ust_ctx_value *value) { - struct lttng_ust_jni_ctx *jctx; - const char *ctx_name = field->event_field.name; + struct lttng_ust_jni_ctx_entry *jctx; + const char *ctx_name = field->event_field->name; enum lttng_ust_jni_type jni_type; jctx = lookup_ctx_by_name(ctx_name); @@ -289,9 +303,18 @@ static void get_value_cb(struct lttng_ctx_field *field, value->u.s64 = (int64_t) jctx->value._boolean; break; case JNI_TYPE_STRING: - value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING; - value->u.str = jctx->value._string; + { + int32_t offset = jctx->value._string_offset; + const char *str = get_ctx_string_at_offset(offset); + + if (str) { + value->sel = LTTNG_UST_DYNAMIC_TYPE_STRING; + value->u.str = str; + } else { + value->sel = LTTNG_UST_DYNAMIC_TYPE_NONE; + } break; + } default: abort(); } @@ -331,6 +354,7 @@ JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registe if (!provider) { goto error_provider; } + provider->struct_size = sizeof(*provider); provider->name = provider_name_cstr; provider->get_size = get_size_cb; provider->record = record_cb; @@ -340,7 +364,7 @@ JNIEXPORT jlong JNICALL Java_org_lttng_ust_agent_context_LttngContextApi_registe goto error_register; } - provider_ref = (jlong) provider; + provider_ref = (jlong) (long) provider; return provider_ref; /* Error handling. */