X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Fcommands%2Flist.c;h=8c1dadac8e5dc66bddebe81d7a564c9fc7c20555;hp=bce40ff6c91596cb1c209003a06ef0bf339696c3;hb=e4baff1ed855ca743e95068ca6449fd906d2d833;hpb=9f19cc17a942a7089fc209a2527d8b2960c83a00 diff --git a/lttng/commands/list.c b/lttng/commands/list.c index bce40ff6c..8c1dadac8 100644 --- a/lttng/commands/list.c +++ b/lttng/commands/list.c @@ -22,11 +22,13 @@ #include #include #include +#include #include "../cmd.h" static int opt_pid; static int opt_userspace; +static char *opt_cmd_name; static int opt_kernel; static char *opt_channel; static int opt_domain; @@ -37,13 +39,16 @@ const char *indent8 = " "; enum { OPT_HELP = 1, + OPT_USERSPACE, }; +static struct lttng_handle *handle; + static struct poptOption long_options[] = { /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */ {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0}, {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0}, - {"userspace", 'u', POPT_ARG_VAL, &opt_userspace, 1, 0, 0}, + {"userspace", 'u', POPT_ARG_STRING | POPT_ARGFLAG_OPTIONAL, &opt_cmd_name, OPT_USERSPACE, 0, 0}, {"pid", 'p', POPT_ARG_INT, &opt_pid, 0, 0, 0}, {"channel", 'c', POPT_ARG_STRING, &opt_channel, 0, 0, 0}, {"domain", 'd', POPT_ARG_VAL, &opt_domain, 1, 0, 0}, @@ -79,7 +84,6 @@ static void usage(FILE *ofp) * On success, return an allocated string pointer to the proc cmdline. * On error, return NULL. */ -#ifdef DISABLE static char *get_cmdline_by_pid(pid_t pid) { int ret; @@ -104,7 +108,161 @@ static char *get_cmdline_by_pid(pid_t pid) end: return cmdline; } -#endif /* DISABLE */ + +static +const char *active_string(int value) +{ + switch (value) { + case 0: return " [inactive]"; + case 1: return " [active]"; + case -1: return ""; + default: return NULL; + } +} + +static +const char *enabled_string(int value) +{ + switch (value) { + case 0: return " [disabled]"; + case 1: return " [enabled]"; + case -1: return ""; + default: return NULL; + } +} + +static +const char *loglevel_string_pre(const char *loglevel) +{ + if (loglevel[0] == '\0') { + return ""; + } else { + return " (loglevel: "; + } +} + +static +const char *loglevel_string_post(const char *loglevel) +{ + if (loglevel[0] == '\0') { + return ""; + } else { + return ")"; + } +} + +/* + * Pretty print single event. + */ +static void print_events(struct lttng_event *event) +{ + switch (event->type) { + case LTTNG_EVENT_TRACEPOINT: + { + char ll_value[LTTNG_SYMBOL_NAME_LEN] = ""; + + if (event->loglevel[0] != '\0') { + int ret; + + ret = snprintf(ll_value, LTTNG_SYMBOL_NAME_LEN, + ", %lld", (long long) event->loglevel_value); + if (ret < 0) + ERR("snprintf error"); + } + MSG("%s%s%s%s%s%s (type: tracepoint)%s", indent6, + event->name, + loglevel_string_pre(event->loglevel), + event->loglevel, + ll_value, + loglevel_string_post(event->loglevel), + enabled_string(event->enabled)); + break; + } + case LTTNG_EVENT_PROBE: + MSG("%s%s (type: probe)%s", indent6, + event->name, enabled_string(event->enabled)); + if (event->attr.probe.addr != 0) { + MSG("%saddr: 0x%" PRIx64, indent8, event->attr.probe.addr); + } else { + MSG("%soffset: 0x%" PRIx64, indent8, event->attr.probe.offset); + MSG("%ssymbol: %s", indent8, event->attr.probe.symbol_name); + } + break; + case LTTNG_EVENT_FUNCTION: + case LTTNG_EVENT_FUNCTION_ENTRY: + MSG("%s%s (type: function)%s", indent6, + event->name, enabled_string(event->enabled)); + MSG("%ssymbol: \"%s\"", indent8, event->attr.ftrace.symbol_name); + break; + case LTTNG_EVENT_SYSCALL: + MSG("%s (type: syscall)%s", indent6, + enabled_string(event->enabled)); + break; + case LTTNG_EVENT_NOOP: + MSG("%s (type: noop)%s", indent6, + enabled_string(event->enabled)); + break; + case LTTNG_EVENT_TRACEPOINT_LOGLEVEL: + MSG("%s%s (type: tracepoint loglevel)%s", indent6, + event->name, + enabled_string(event->enabled)); + break; + case LTTNG_EVENT_ALL: + /* We should never have "all" events in list. */ + assert(0); + break; + } +} + +/* + * Ask session daemon for all user space tracepoints available. + */ +static int list_ust_events(void) +{ + int i, size; + struct lttng_domain domain; + struct lttng_handle *handle; + struct lttng_event *event_list; + pid_t cur_pid = 0; + + DBG("Getting UST tracing events"); + + domain.type = LTTNG_DOMAIN_UST; + + handle = lttng_create_handle(NULL, &domain); + if (handle == NULL) { + goto error; + } + + size = lttng_list_tracepoints(handle, &event_list); + if (size < 0) { + ERR("Unable to list UST events"); + return size; + } + + MSG("UST events:\n-------------"); + + if (size == 0) { + MSG("None"); + } + + for (i = 0; i < size; i++) { + if (cur_pid != event_list[i].pid) { + cur_pid = event_list[i].pid; + MSG("\nPID: %d - Name: %s", cur_pid, get_cmdline_by_pid(cur_pid)); + } + print_events(&event_list[i]); + } + + MSG(""); + + free(event_list); + + return CMD_SUCCESS; + +error: + return -1; +} /* * Ask for all trace events in the kernel and pretty print them. @@ -112,11 +270,20 @@ end: static int list_kernel_events(void) { int i, size; + struct lttng_domain domain; + struct lttng_handle *handle; struct lttng_event *event_list; - DBG("Getting all tracing events"); + DBG("Getting kernel tracing events"); - size = lttng_list_kernel_events(&event_list); + domain.type = LTTNG_DOMAIN_KERNEL; + + handle = lttng_create_handle(NULL, &domain); + if (handle == NULL) { + goto error; + } + + size = lttng_list_tracepoints(handle, &event_list); if (size < 0) { ERR("Unable to list kernel events"); return size; @@ -125,24 +292,28 @@ static int list_kernel_events(void) MSG("Kernel events:\n-------------"); for (i = 0; i < size; i++) { - MSG(" %s", event_list[i].name); + print_events(&event_list[i]); } + MSG(""); + free(event_list); return CMD_SUCCESS; + +error: + return -1; } /* * List events of channel of session and domain. */ -static int list_events(struct lttng_domain *dom, - const char *session_name, const char *channel_name) +static int list_events(const char *channel_name) { int ret, count, i; struct lttng_event *events = NULL; - count = lttng_list_events(dom, session_name, channel_name, &events); + count = lttng_list_events(handle, channel_name, &events); if (count < 0) { ret = count; goto error; @@ -150,33 +321,12 @@ static int list_events(struct lttng_domain *dom, MSG("\n%sEvents:", indent4); if (count == 0) { - MSG("%sNone", indent6); + MSG("%sNone\n", indent6); goto end; } for (i = 0; i < count; i++) { - switch (events[i].type) { - case LTTNG_EVENT_TRACEPOINT: - MSG("%s%s (type: tracepoint) [enabled: %d]", indent6, - events[i].name, events[i].enabled); - break; - case LTTNG_EVENT_PROBE: - MSG("%s%s (type: probe) [enabled: %d]", indent6, - events[i].name, events[i].enabled); - if (events[i].attr.probe.addr != 0) { - MSG("%saddr: 0x%" PRIx64, indent8, events[i].attr.probe.addr); - } else { - MSG("%soffset: 0x%" PRIx64, indent8, events[i].attr.probe.offset); - MSG("%ssymbol: %s", indent8, events[i].attr.probe.symbol_name); - } - break; - case LTTNG_EVENT_FUNCTION: - case LTTNG_EVENT_FUNCTION_ENTRY: - MSG("%s%s (type: function) [enabled: %d]", indent6, - events[i].name, events[i].enabled); - MSG("%ssymbol: \"%s\"", indent8, events[i].attr.ftrace.symbol_name); - break; - } + print_events(&events[i]); } MSG(""); @@ -196,7 +346,7 @@ error: */ static void print_channel(struct lttng_channel *channel) { - MSG("- %s (enabled: %d):\n", channel->name, channel->enabled); + MSG("- %s:%s\n", channel->name, enabled_string(channel->enabled)); MSG("%sAttributes:", indent4); MSG("%soverwrite mode: %d", indent6, channel->attr.overwrite); @@ -219,16 +369,15 @@ static void print_channel(struct lttng_channel *channel) * * If channel_name is NULL, all channels are listed. */ -static int list_channels(struct lttng_domain *dom, - const char *session_name, const char *channel_name) +static int list_channels(const char *channel_name) { int count, i, ret = CMD_SUCCESS; unsigned int chan_found = 0; struct lttng_channel *channels = NULL; - DBG("Listing channel(s) (%s)", channel_name); + DBG("Listing channel(s) (%s)", channel_name ? : ""); - count = lttng_list_channels(dom, session_name, &channels); + count = lttng_list_channels(handle, &channels); if (count < 0) { ret = count; goto error; @@ -252,9 +401,9 @@ static int list_channels(struct lttng_domain *dom, print_channel(&channels[i]); /* Listing events per channel */ - ret = list_events(dom, session_name, channels[i].name); + ret = list_events(channels[i].name); if (ret < 0) { - MSG("%s", lttng_get_readable_code(ret)); + MSG("%s", lttng_strerror(ret)); } if (chan_found) { @@ -300,13 +449,14 @@ static int list_sessions(const char *session_name) if (session_name != NULL) { if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) { session_found = 1; - MSG("Tracing session %s:", session_name); + MSG("Tracing session %s:%s", session_name, active_string(sessions[i].enabled)); MSG("%sTrace path: %s\n", indent4, sessions[i].path); break; } + continue; } - MSG(" %d) %s (%s)", i + 1, sessions[i].name, sessions[i].path); + MSG(" %d) %s (%s)%s", i + 1, sessions[i].name, sessions[i].path, active_string(sessions[i].enabled)); if (session_found) { break; @@ -320,7 +470,7 @@ static int list_sessions(const char *session_name) } if (session_name == NULL) { - MSG("\nUse lttng list -s for a detail listing"); + MSG("\nUse lttng list for more details"); } return CMD_SUCCESS; @@ -332,14 +482,14 @@ error: /* * List available domain(s) for a session. */ -static int list_domains(const char *session_name) +static int list_domains(void) { int i, count, ret = CMD_SUCCESS; struct lttng_domain *domains = NULL; MSG("Domains:\n-------------"); - count = lttng_list_domains(session_name, &domains); + count = lttng_list_domains(handle, &domains); if (count < 0) { ret = count; goto error; @@ -352,6 +502,10 @@ static int list_domains(const char *session_name) switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: MSG(" - Kernel"); + break; + case LTTNG_DOMAIN_UST: + MSG(" - UST global"); + break; default: break; } @@ -370,6 +524,7 @@ error: int cmd_list(int argc, const char **argv) { int opt, i, ret = CMD_SUCCESS; + int nb_domain; const char *session_name; static poptContext pc; struct lttng_domain domain; @@ -388,6 +543,9 @@ int cmd_list(int argc, const char **argv) case OPT_HELP: usage(stderr); goto end; + case OPT_USERSPACE: + opt_userspace = 1; + break; default: usage(stderr); ret = CMD_UNDEFINED; @@ -395,22 +553,41 @@ int cmd_list(int argc, const char **argv) } } - if (opt_userspace || opt_pid != 0) { - MSG("*** Userspace tracing not implemented ***\n"); + if (opt_pid != 0) { + MSG("*** Userspace tracing not implemented for PID ***\n"); } /* Get session name (trailing argument) */ session_name = poptGetArg(pc); - DBG("Session name: %s", session_name); + DBG2("Session name: %s", session_name); + + if (opt_kernel) { + domain.type = LTTNG_DOMAIN_KERNEL; + } else if (opt_userspace) { + DBG2("Listing userspace global domain"); + domain.type = LTTNG_DOMAIN_UST; + } + + handle = lttng_create_handle(session_name, &domain); + if (handle == NULL) { + goto end; + } if (session_name == NULL) { + if (!opt_kernel && !opt_userspace) { + ret = list_sessions(NULL); + if (ret < 0) { + goto end; + } + } if (opt_kernel) { ret = list_kernel_events(); if (ret < 0) { goto end; } - } else { - ret = list_sessions(NULL); + } + if (opt_userspace) { + ret = list_ust_events(); if (ret < 0) { goto end; } @@ -424,37 +601,46 @@ int cmd_list(int argc, const char **argv) /* Domain listing */ if (opt_domain) { - ret = list_domains(session_name); + ret = list_domains(); goto end; } if (opt_kernel) { - domain.type = LTTNG_DOMAIN_KERNEL; /* Channel listing */ - ret = list_channels(&domain, session_name, opt_channel); + ret = list_channels(opt_channel); if (ret < 0) { goto end; } - } else if (opt_userspace) { - /* TODO: Userspace domain */ } else { /* We want all domain(s) */ - ret = lttng_list_domains(session_name, &domains); - if (ret < 0) { + nb_domain = lttng_list_domains(handle, &domains); + if (nb_domain < 0) { + ret = nb_domain; goto end; } - for (i = 0; i < ret; i++) { + for (i = 0; i < nb_domain; i++) { switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: MSG("=== Domain: Kernel ===\n"); break; + case LTTNG_DOMAIN_UST: + MSG("=== Domain: UST global ===\n"); + break; default: MSG("=== Domain: Unimplemented ===\n"); break; } - ret = list_channels(&domains[i], session_name, opt_channel); + /* Clean handle before creating a new one */ + lttng_destroy_handle(handle); + + handle = lttng_create_handle(session_name, &domains[i]); + if (handle == NULL) { + goto end; + } + + ret = list_channels(opt_channel); if (ret < 0) { goto end; } @@ -466,5 +652,7 @@ end: if (domains) { free(domains); } + lttng_destroy_handle(handle); + return ret; }