X-Git-Url: http://git.lttng.org./?a=blobdiff_plain;f=liblttng-ust%2Fltt-events.c;h=2bc5a1597b3ed15812a543f78c60ddcaad7263ec;hb=56b849af90745087f9a6abb0bed352e6705119aa;hp=52feeb08a7dad9c9bc9970a39197a586f9305612;hpb=457a6b5879a7dd8cdd1b5b22b20d028a59489159;p=lttng-ust.git diff --git a/liblttng-ust/ltt-events.c b/liblttng-ust/ltt-events.c index 52feeb08..2bc5a159 100644 --- a/liblttng-ust/ltt-events.c +++ b/liblttng-ust/ltt-events.c @@ -1,20 +1,30 @@ /* * ltt-events.c * - * Copyright 2010 (c) - Mathieu Desnoyers - * * Holds LTTng per-session event registry. * - * Dual LGPL v2.1/GPL v2 license. + * Copyright (C) 2010-2012 Mathieu Desnoyers + * + * 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 */ #define _GNU_SOURCE #include -#include #include #include #include -#include #include #include #include @@ -22,6 +32,7 @@ #include #include #include +#include #include "clock.h" #include @@ -35,6 +46,8 @@ #include #include #include "error.h" +#include "compat.h" +#include "lttng-ust-uuid.h" #include "tracepoint-internal.h" #include "ltt-tracer.h" @@ -166,20 +179,20 @@ int add_pending_probe(struct ltt_event *event, const char *name, { struct cds_hlist_head *head; struct ust_pending_probe *e; - size_t name_len = strlen(name); + size_t name_len = strlen(name) + 1; 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; + if (name_len > LTTNG_UST_SYM_NAME_LEN) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN); + name_len = LTTNG_UST_SYM_NAME_LEN; } - hash = jhash(name, name_len, 0); + hash = jhash(name, name_len - 1, 0); head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; e = zmalloc(sizeof(struct ust_pending_probe) + name_len); if (!e) return -ENOMEM; - memcpy(&e->name[0], name, name_len + 1); - e->name[name_len] = '\0'; + memcpy(&e->name[0], name, name_len); + e->name[name_len - 1] = '\0'; e->loglevel_type = loglevel_type; e->loglevel = loglevel; cds_hlist_add_head(&e->node, head); @@ -215,7 +228,7 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) const char *name = desc->name; int ret = 0; struct lttng_ust_event event_param; - size_t name_len = strlen(name); + size_t name_len = strlen(name) + 1; uint32_t hash; /* Wildcard */ @@ -238,30 +251,30 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) sizeof(event_param.name)); /* create event */ ret = ltt_event_create(sw->chan, - &event_param, NULL, - &ev); + &event_param, &ev); if (ret) { DBG("Error creating event"); continue; } cds_list_add(&ev->wildcard_list, &sw->events); + lttng_filter_event_link_bytecode(ev, + sw->filter_bytecode); } } } - 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; + if (name_len > LTTNG_UST_SYM_NAME_LEN) { + WARN("Truncating tracepoint name %s which exceeds size limits of %u chars", name, LTTNG_UST_SYM_NAME_LEN); + name_len = LTTNG_UST_SYM_NAME_LEN; } - hash = jhash(name, name_len, 0); + hash = jhash(name, name_len - 1, 0); head = &pending_probe_table[hash & (PENDING_PROBE_HASH_SIZE - 1)]; cds_hlist_for_each_entry_safe(e, node, p, head, node) { struct ltt_event *event; struct ltt_channel *chan; - event = e->event; - if (!ltt_loglevel_match(event->desc, + if (!ltt_loglevel_match(desc, e->loglevel_type, e->loglevel)) { continue; @@ -269,6 +282,7 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) if (strncmp(name, e->name, LTTNG_UST_SYM_NAME_LEN - 1)) { continue; } + event = e->event; chan = event->chan; assert(!event->desc); event->desc = desc; @@ -276,12 +290,14 @@ int pending_probe_fix_events(const struct lttng_event_desc *desc) remove_pending_probe(e); ret |= __tracepoint_probe_register(name, event->desc->probe_callback, - event); + event, event->desc->signature); if (ret) continue; event->id = chan->free_event_id++; ret |= _ltt_event_metadata_statedump(chan->session, chan, event); + lttng_filter_event_link_bytecode(event, + event->filter_bytecode); } return ret; } @@ -294,6 +310,7 @@ void synchronize_trace(void) struct ltt_session *ltt_session_create(void) { struct ltt_session *session; + int ret; session = zmalloc(sizeof(struct ltt_session)); if (!session) @@ -301,7 +318,10 @@ struct ltt_session *ltt_session_create(void) CDS_INIT_LIST_HEAD(&session->chan); CDS_INIT_LIST_HEAD(&session->events); CDS_INIT_LIST_HEAD(&session->wildcards); - uuid_generate(session->uuid); + ret = lttng_ust_uuid_generate(session->uuid); + if (ret != 0) { + session->uuid[0] = '\0'; + } cds_list_add(&session->list, &sessions); return session; } @@ -450,7 +470,7 @@ struct ltt_channel *ltt_channel_create(struct ltt_session *session, * headers. Therefore the "chan" information used as input * should be already accessible. */ - chan = transport->ops.channel_create("[lttng]", buf_addr, + chan = transport->ops.channel_create(transport_name, buf_addr, subbuf_size, num_subbuf, switch_timer_interval, read_timer_interval, shm_fd, wait_fd, memory_map_size, chan_priv_init); @@ -483,14 +503,13 @@ void _ltt_channel_destroy(struct ltt_channel *chan) */ int ltt_event_create(struct ltt_channel *chan, struct lttng_ust_event *event_param, - void *filter, struct ltt_event **_event) { const struct lttng_event_desc *desc = NULL; /* silence gcc */ struct ltt_event *event; int ret = 0; - if (chan->used_event_id == -1UL) { + if (chan->used_event_id == -1U) { ret = -ENOMEM; goto full; } @@ -512,12 +531,18 @@ int ltt_event_create(struct ltt_channel *chan, */ if (event_param->instrumentation == LTTNG_UST_TRACEPOINT) { desc = ltt_event_get(event_param->name); - if (!ltt_loglevel_match(desc, - event_param->loglevel_type, - event_param->loglevel)) { - ret = -EPERM; - goto no_loglevel_match; + if (desc) { + if (!ltt_loglevel_match(desc, + event_param->loglevel_type, + event_param->loglevel)) { + ret = -EPERM; + goto no_loglevel_match; + } } + /* + * If descriptor is not there, it will be added to + * pending probes. + */ } event = zmalloc(sizeof(struct ltt_event)); if (!event) { @@ -525,7 +550,6 @@ int ltt_event_create(struct ltt_channel *chan, goto cache_error; } event->chan = chan; - event->filter = filter; /* * used_event_id counts the maximum number of event IDs that can * register if all probes register. @@ -541,7 +565,7 @@ int ltt_event_create(struct ltt_channel *chan, if (event->desc) { ret = __tracepoint_probe_register(event_param->name, event->desc->probe_callback, - event); + event, event->desc->signature); if (ret) goto register_error; event->id = chan->free_event_id++; @@ -630,6 +654,8 @@ void _ltt_event_destroy(struct ltt_event *event) } cds_list_del(&event->list); lttng_destroy_context(event->ctx); + free(event->filter_bytecode); + free(event->filter_data); free(event); } @@ -700,6 +726,9 @@ int _ltt_field_statedump(struct ltt_session *session, { int ret = 0; + if (!field->written) + return 0; + switch (field->type.atype) { case atype_integer: ret = lttng_metadata_printf(session, @@ -869,6 +898,7 @@ int _ltt_event_metadata_statedump(struct ltt_session *session, struct ltt_event *event) { int ret = 0; + int loglevel = TRACE_DEFAULT; if (event->metadata_dumped || !CMM_ACCESS_ONCE(session->active)) return 0; @@ -891,13 +921,14 @@ int _ltt_event_metadata_statedump(struct ltt_session *session, if (ret) goto end; - if (event->desc->loglevel) { - ret = lttng_metadata_printf(session, - " loglevel = %d;\n", - *(*event->desc->loglevel)); - if (ret) - goto end; - } + if (event->desc->loglevel) + loglevel = *(*event->desc->loglevel); + + ret = lttng_metadata_printf(session, + " loglevel = %d;\n", + loglevel); + if (ret) + goto end; if (event->ctx) { ret = lttng_metadata_printf(session, @@ -995,7 +1026,7 @@ 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" - " uint32_t events_discarded;\n" + " unsigned long events_discarded;\n" " uint32_t content_size;\n" " uint32_t packet_size;\n" " uint32_t cpu_id;\n" @@ -1065,7 +1096,7 @@ uint64_t measure_clock_offset(void) return 0; monotonic[1] = trace_clock_read64(); offset = (monotonic[0] + monotonic[1]) >> 1; - realtime = rts.tv_sec * 1000000000ULL; + realtime = (uint64_t) rts.tv_sec * 1000000000ULL; realtime += rts.tv_nsec; offset = realtime - offset; return offset; @@ -1078,10 +1109,12 @@ static int _ltt_session_metadata_statedump(struct ltt_session *session) { unsigned char *uuid_c = session->uuid; - char uuid_s[37], clock_uuid_s[CLOCK_UUID_LEN]; + char uuid_s[LTTNG_UST_UUID_STR_LEN], + clock_uuid_s[LTTNG_UST_UUID_STR_LEN]; struct ltt_channel *chan; struct ltt_event *event; int ret = 0; + char procname[LTTNG_UST_PROCNAME_LEN] = ""; if (!CMM_ACCESS_ONCE(session->active)) return 0; @@ -1104,6 +1137,7 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) "typealias integer { size = 16; align = %u; signed = false; } := uint16_t;\n" "typealias integer { size = 32; align = %u; signed = false; } := uint32_t;\n" "typealias integer { size = 64; align = %u; signed = false; } := uint64_t;\n" + "typealias integer { size = %u; align = %u; signed = false; } := unsigned long;\n" "typealias integer { size = 5; align = 1; signed = false; } := uint5_t;\n" "typealias integer { size = 27; align = 1; signed = false; } := uint27_t;\n" "\n" @@ -1122,8 +1156,10 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) lttng_alignof(uint16_t) * CHAR_BIT, lttng_alignof(uint32_t) * CHAR_BIT, lttng_alignof(uint64_t) * CHAR_BIT, - CTF_VERSION_MAJOR, - CTF_VERSION_MINOR, + sizeof(unsigned long) * CHAR_BIT, + lttng_alignof(unsigned long) * CHAR_BIT, + CTF_SPEC_MAJOR, + CTF_SPEC_MINOR, uuid_s, #if (BYTE_ORDER == BIG_ENDIAN) "be" @@ -1134,6 +1170,28 @@ int _ltt_session_metadata_statedump(struct ltt_session *session) if (ret) goto end; + /* ignore error, just use empty string if error. */ + lttng_ust_getprocname(procname); + procname[LTTNG_UST_PROCNAME_LEN - 1] = '\0'; + ret = lttng_metadata_printf(session, + "env {\n" + " vpid = %d;\n" + " procname = \"%s\";\n" + " domain = \"ust\";\n" + " tracer_name = \"lttng-ust\";\n" + " tracer_major = %u;\n" + " tracer_minor = %u;\n" + " tracer_patchlevel = %u;\n" + "};\n\n", + (int) getpid(), + procname, + LTTNG_UST_MAJOR_VERSION, + LTTNG_UST_MINOR_VERSION, + LTTNG_UST_PATCHLEVEL_VERSION + ); + if (ret) + goto end; + ret = lttng_metadata_printf(session, "clock {\n" " name = %s;\n", @@ -1310,6 +1368,8 @@ struct session_wildcard *add_wildcard(struct ltt_channel *chan, if (!e) return ERR_PTR(-ENOMEM); memcpy(&e->name[0], event_param->name, name_len); + e->loglevel_type = event_param->loglevel_type; + e->loglevel = event_param->loglevel; cds_list_add(&e->list, &wildcard_list); CDS_INIT_LIST_HEAD(&e->session_list); } @@ -1363,6 +1423,7 @@ void _remove_wildcard(struct session_wildcard *wildcard) cds_list_del(&wildcard->entry->list); free(wildcard->entry); } + free(wildcard->filter_bytecode); free(wildcard); } @@ -1421,3 +1482,16 @@ int ltt_wildcard_disable(struct session_wildcard *wildcard) wildcard->enabled = 0; return 0; } + +/* + * Take the TLS "fault" in libuuid if dlopen'd, which can take the + * dynamic linker mutex, outside of the UST lock, since the UST lock is + * taken in constructors, which are called with dynamic linker mutex + * held. + */ +void lttng_fixup_event_tls(void) +{ + unsigned char uuid[LTTNG_UST_UUID_STR_LEN]; + + (void) lttng_ust_uuid_generate(uuid); +}