X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=lttng%2Fcommands%2Flist.c;h=991ad28d6b01c7238fff29ee3cf912e651d1b826;hp=50dad9a2b4efc3aa57cb747c72820cea36773add;hb=4dbd54a14d42213c0b80fa6d797ddd416cd0330d;hpb=9a745bc7cbb8247543e38420fb8ba74f1756942d diff --git a/lttng/commands/list.c b/lttng/commands/list.c index 50dad9a2b..991ad28d6 100644 --- a/lttng/commands/list.c +++ b/lttng/commands/list.c @@ -28,6 +28,7 @@ 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; @@ -38,6 +39,7 @@ const char *indent8 = " "; enum { OPT_HELP = 1, + OPT_USERSPACE, }; static struct lttng_handle *handle; @@ -46,7 +48,7 @@ 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}, @@ -82,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; @@ -107,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. @@ -115,9 +270,18 @@ 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"); + + 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) { @@ -128,12 +292,17 @@ 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; } /* @@ -152,45 +321,12 @@ static int list_events(const char *channel_name) 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; - case LTTNG_EVENT_SYSCALL: - MSG("%s (type: syscall) [enabled: %d]", indent6, - events[i].enabled); - break; - case LTTNG_EVENT_NOOP: - MSG("%s (type: noop) [enabled: %d]", indent6, - events[i].enabled); - break; - case LTTNG_EVENT_ALL: - /* We should never have "all" events in list. */ - assert(0); - break; - } + print_events(&events[i]); } MSG(""); @@ -210,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); @@ -239,7 +375,7 @@ static int list_channels(const char *channel_name) 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(handle, &channels); if (count < 0) { @@ -313,14 +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; @@ -366,6 +502,10 @@ static int list_domains(void) switch (domains[i].type) { case LTTNG_DOMAIN_KERNEL: MSG(" - Kernel"); + break; + case LTTNG_DOMAIN_UST: + MSG(" - UST global"); + break; default: break; } @@ -384,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; @@ -402,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; @@ -409,16 +553,19 @@ 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); @@ -427,13 +574,20 @@ int cmd_list(int argc, const char **argv) } 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; } @@ -457,20 +611,22 @@ int cmd_list(int argc, const char **argv) if (ret < 0) { goto end; } - } else if (opt_userspace) { - /* TODO: Userspace domain */ } else { /* We want all domain(s) */ - ret = lttng_list_domains(handle, &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;