X-Git-Url: http://git.efficios.com/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng%2Fcommands%2Fenable_events.c;h=1ed3a0ab77c435d5dbe80b5fbfb95778e9c0ec2c;hp=3263c588ad9bf83c8c79bef5c4abc091f044e5d2;hb=4fc83d948cea6b10484e65f004a6c167e71ac440;hpb=49d4e302bc85172e1bced944b0ff51fefa579931 diff --git a/src/bin/lttng/commands/enable_events.c b/src/bin/lttng/commands/enable_events.c index 3263c588a..1ed3a0ab7 100644 --- a/src/bin/lttng/commands/enable_events.c +++ b/src/bin/lttng/commands/enable_events.c @@ -15,12 +15,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#define _GNU_SOURCE +#define _LGPL_SOURCE #include #include #include #include -#include #include #include #include @@ -28,6 +27,7 @@ #include #include +#include /* Mi dependancy */ #include @@ -47,17 +47,18 @@ static char *opt_session_name; static int opt_userspace; static int opt_jul; static int opt_log4j; +static int opt_python; static int opt_enable_all; static char *opt_probe; static char *opt_function; -static char *opt_function_entry_symbol; static char *opt_channel_name; static char *opt_filter; static char *opt_exclude; -#if 0 -/* Not implemented yet */ -static char *opt_cmd_name; -static pid_t opt_pid; + +#ifdef LTTNG_EMBED_HELP +static const char help_msg[] = +#include +; #endif enum { @@ -65,7 +66,6 @@ enum { OPT_TRACEPOINT, OPT_PROBE, OPT_FUNCTION, - OPT_FUNCTION_ENTRY, OPT_SYSCALL, OPT_USERSPACE, OPT_LOGLEVEL, @@ -88,16 +88,10 @@ static struct poptOption long_options[] = { {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0}, {"jul", 'j', POPT_ARG_VAL, &opt_jul, 1, 0, 0}, {"log4j", 'l', POPT_ARG_VAL, &opt_log4j, 1, 0, 0}, + {"python", 'p', POPT_ARG_VAL, &opt_python, 1, 0, 0}, {"tracepoint", 0, POPT_ARG_NONE, 0, OPT_TRACEPOINT, 0, 0}, {"probe", 0, POPT_ARG_STRING, &opt_probe, OPT_PROBE, 0, 0}, {"function", 0, POPT_ARG_STRING, &opt_function, OPT_FUNCTION, 0, 0}, -#if 0 - /* - * Currently removed from lttng kernel tracer. Removed from - * lttng UI to discourage its use. - */ - {"function:entry", 0, POPT_ARG_STRING, &opt_function_entry_symbol, OPT_FUNCTION_ENTRY, 0, 0}, -#endif {"syscall", 0, POPT_ARG_NONE, 0, OPT_SYSCALL, 0, 0}, {"loglevel", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL, 0, 0}, {"loglevel-only", 0, POPT_ARG_STRING, 0, OPT_LOGLEVEL_ONLY, 0, 0}, @@ -107,141 +101,6 @@ static struct poptOption long_options[] = { {0, 0, 0, 0, 0, 0, 0} }; -/* - * usage - */ -static void usage(FILE *ofp) -{ - fprintf(ofp, "usage: lttng enable-event NAME[,NAME2,...] [-k|-u] [OPTIONS] \n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Options:\n"); - fprintf(ofp, " -h, --help Show this help\n"); - fprintf(ofp, " --list-options Simple listing of options\n"); - fprintf(ofp, " -s, --session NAME Apply to session name\n"); - fprintf(ofp, " -c, --channel NAME Apply to this channel\n"); - fprintf(ofp, " -a, --all Enable all tracepoints and syscalls\n"); - fprintf(ofp, " -k, --kernel Apply for the kernel tracer\n"); - fprintf(ofp, " -u, --userspace Apply to the user-space tracer\n"); - fprintf(ofp, " -j, --jul Apply for Java application using JUL\n"); - fprintf(ofp, " -l, --log4j Apply for Java application using LOG4j\n"); - fprintf(ofp, "\n"); - fprintf(ofp, "Event options:\n"); - fprintf(ofp, " --tracepoint Tracepoint event (default)\n"); - fprintf(ofp, " - userspace tracer supports wildcards at end of string.\n"); - fprintf(ofp, " Don't forget to quote to deal with bash expansion.\n"); - fprintf(ofp, " e.g.:\n"); - fprintf(ofp, " \"*\"\n"); - fprintf(ofp, " \"app_component:na*\"\n"); - fprintf(ofp, " --probe (addr | symbol | symbol+offset)\n"); - fprintf(ofp, " Dynamic probe.\n"); - fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); - fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); - fprintf(ofp, " --function (addr | symbol | symbol+offset)\n"); - fprintf(ofp, " Dynamic function entry/return probe.\n"); - fprintf(ofp, " Addr and offset can be octal (0NNN...),\n"); - fprintf(ofp, " decimal (NNN...) or hexadecimal (0xNNN...)\n"); -#if 0 - fprintf(ofp, " --function:entry symbol\n"); - fprintf(ofp, " Function tracer event\n"); -#endif - fprintf(ofp, " --syscall System call event\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " --loglevel name\n"); - fprintf(ofp, " Tracepoint loglevel range from 0 to loglevel.\n"); - fprintf(ofp, " For JUL/LOG4j domain, see the table below for the range values.\n"); - fprintf(ofp, " --loglevel-only name\n"); - fprintf(ofp, " Tracepoint loglevel (only this loglevel)\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " The loglevel or loglevel-only options should be\n"); - fprintf(ofp, " combined with a tracepoint name or tracepoint\n"); - fprintf(ofp, " wildcard.\n"); - fprintf(ofp, " Available loglevels:\n"); - fprintf(ofp, " (higher value is more verbose)\n"); - fprintf(ofp, " TRACE_EMERG = 0\n"); - fprintf(ofp, " TRACE_ALERT = 1\n"); - fprintf(ofp, " TRACE_CRIT = 2\n"); - fprintf(ofp, " TRACE_ERR = 3\n"); - fprintf(ofp, " TRACE_WARNING = 4\n"); - fprintf(ofp, " TRACE_NOTICE = 5\n"); - fprintf(ofp, " TRACE_INFO = 6\n"); - fprintf(ofp, " TRACE_DEBUG_SYSTEM = 7\n"); - fprintf(ofp, " TRACE_DEBUG_PROGRAM = 8\n"); - fprintf(ofp, " TRACE_DEBUG_PROCESS = 9\n"); - fprintf(ofp, " TRACE_DEBUG_MODULE = 10\n"); - fprintf(ofp, " TRACE_DEBUG_UNIT = 11\n"); - fprintf(ofp, " TRACE_DEBUG_FUNCTION = 12\n"); - fprintf(ofp, " TRACE_DEBUG_LINE = 13\n"); - fprintf(ofp, " TRACE_DEBUG = 14\n"); - fprintf(ofp, " (shortcuts such as \"system\" are allowed)\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " Available JUL domain loglevels:\n"); - fprintf(ofp, " JUL_OFF = INT32_MAX\n"); - fprintf(ofp, " JUL_SEVERE = %d\n", LTTNG_LOGLEVEL_JUL_SEVERE); - fprintf(ofp, " JUL_WARNING = %d\n", LTTNG_LOGLEVEL_JUL_WARNING); - fprintf(ofp, " JUL_INFO = %d\n", LTTNG_LOGLEVEL_JUL_INFO); - fprintf(ofp, " JUL_CONFIG = %d\n", LTTNG_LOGLEVEL_JUL_CONFIG); - fprintf(ofp, " JUL_FINE = %d\n", LTTNG_LOGLEVEL_JUL_FINE); - fprintf(ofp, " JUL_FINER = %d\n", LTTNG_LOGLEVEL_JUL_FINER); - fprintf(ofp, " JUL_FINEST = %d\n", LTTNG_LOGLEVEL_JUL_FINEST); - fprintf(ofp, " JUL_ALL = INT32_MIN\n"); - fprintf(ofp, " (shortcuts such as \"severe\" are allowed)\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " Available LOG4j domain loglevels:\n"); - fprintf(ofp, " LOG4J_OFF = INT32_MAX\n"); - fprintf(ofp, " LOG4J_FATAL = %d\n", LTTNG_LOGLEVEL_LOG4J_FATAL); - fprintf(ofp, " LOG4J_ERROR = %d\n", LTTNG_LOGLEVEL_LOG4J_ERROR); - fprintf(ofp, " LOG4J_WARN = %d\n", LTTNG_LOGLEVEL_LOG4J_WARN); - fprintf(ofp, " LOG4J_INFO = %d\n", LTTNG_LOGLEVEL_LOG4J_INFO); - fprintf(ofp, " LOG4J_DEBUG = %d\n", LTTNG_LOGLEVEL_LOG4J_DEBUG); - fprintf(ofp, " LOG4J_TRACE = %d\n", LTTNG_LOGLEVEL_LOG4J_TRACE); - fprintf(ofp, " LOG4J_ALL = INT32_MIN\n"); - fprintf(ofp, " (shortcuts such as \"severe\" are allowed)\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " -f, --filter \'expression\'\n"); - fprintf(ofp, " Filter expression on event fields and context.\n"); - fprintf(ofp, " Event recording depends on evaluation.\n"); - fprintf(ofp, " Only specify on first activation of\n"); - fprintf(ofp, " a given event within a session.\n"); - fprintf(ofp, " Filter only allowed when enabling\n"); - fprintf(ofp, " events within a session before tracing\n"); - fprintf(ofp, " is started. If the filter fails to link\n"); - fprintf(ofp, " with the event within the traced domain,\n"); - fprintf(ofp, " the event will be discarded. Currently,\n"); - fprintf(ofp, " filter is only implemented for the user-space\n"); - fprintf(ofp, " tracer.\n"); - fprintf(ofp, " Expression examples:.\n"); - fprintf(ofp, " \n"); - fprintf(ofp, " 'intfield > 500 && intfield < 503'\n"); - fprintf(ofp, " '(strfield == \"test\" || intfield != 10) && intfield > 33'\n"); - fprintf(ofp, " 'doublefield > 1.1 && intfield < 5.3'\n"); - fprintf(ofp, " \n"); - fprintf(ofp, " Wildcards are allowed at the end of strings:\n"); - fprintf(ofp, " 'seqfield1 == \"te*\"'\n"); - fprintf(ofp, " In string literals, the escape character is '\\'.\n"); - fprintf(ofp, " Use '\\*' for the '*' character, and '\\\\' for\n"); - fprintf(ofp, " the '\\' character. Wildcard match any sequence of,\n"); - fprintf(ofp, " characters including an empty sub-string (match 0 or\n"); - fprintf(ofp, " more characters).\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " Context information can be used for filtering. The\n"); - fprintf(ofp, " examples below show usage of context filtering on\n"); - fprintf(ofp, " process name (with a wildcard), process ID range, and\n"); - fprintf(ofp, " unique thread ID for filtering. The process and\n"); - fprintf(ofp, " thread ID of running applications can be found under\n"); - fprintf(ofp, " columns \"PID\" and \"LWP\" of the \"ps -eLf\" command.\n"); - fprintf(ofp, "\n"); - fprintf(ofp, " '$ctx.procname == \"demo*\"'\n"); - fprintf(ofp, " '$ctx.vpid >= 4433 && $ctx.vpid < 4455'\n"); - fprintf(ofp, " '$ctx.vtid == 1234'\n"); - fprintf(ofp, " -x, --exclude LIST\n"); - fprintf(ofp, " Add exclusions to UST tracepoints:\n"); - fprintf(ofp, " Events that match any of the items\n"); - fprintf(ofp, " in the comma-separated LIST are not\n"); - fprintf(ofp, " enabled, even if they match a wildcard\n"); - fprintf(ofp, " definition of the event.\n"); - fprintf(ofp, "\n"); -} - /* * Parse probe options. */ @@ -321,6 +180,10 @@ static int loglevel_log4j_str_to_value(const char *inputstr) int i = 0; char str[LTTNG_SYMBOL_NAME_LEN]; + if (!inputstr || strlen(inputstr) == 0) { + return -1; + } + /* * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is * added at the end of the loop so a the upper bound we avoid the overflow. @@ -360,6 +223,10 @@ static int loglevel_jul_str_to_value(const char *inputstr) int i = 0; char str[LTTNG_SYMBOL_NAME_LEN]; + if (!inputstr || strlen(inputstr) == 0) { + return -1; + } + /* * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is * added at the end of the loop so a the upper bound we avoid the overflow. @@ -393,6 +260,45 @@ static int loglevel_jul_str_to_value(const char *inputstr) } } +/* + * Maps Python loglevel from string to value + */ +static int loglevel_python_str_to_value(const char *inputstr) +{ + int i = 0; + char str[LTTNG_SYMBOL_NAME_LEN]; + + if (!inputstr || strlen(inputstr) == 0) { + return -1; + } + + /* + * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is + * added at the end of the loop so a the upper bound we avoid the overflow. + */ + while (i < (LTTNG_SYMBOL_NAME_LEN - 1) && inputstr[i] != '\0') { + str[i] = toupper(inputstr[i]); + i++; + } + str[i] = '\0'; + + if (!strcmp(str, "PYTHON_CRITICAL") || !strcmp(str, "CRITICAL")) { + return LTTNG_LOGLEVEL_PYTHON_CRITICAL; + } else if (!strcmp(str, "PYTHON_ERROR") || !strcmp(str, "ERROR")) { + return LTTNG_LOGLEVEL_PYTHON_ERROR; + } else if (!strcmp(str, "PYTHON_WARNING") || !strcmp(str, "WARNING")) { + return LTTNG_LOGLEVEL_PYTHON_WARNING; + } else if (!strcmp(str, "PYTHON_INFO") || !strcmp(str, "INFO")) { + return LTTNG_LOGLEVEL_PYTHON_INFO; + } else if (!strcmp(str, "PYTNON_DEBUG") || !strcmp(str, "DEBUG")) { + return LTTNG_LOGLEVEL_PYTHON_DEBUG; + } else if (!strcmp(str, "PYTHON_NOTSET") || !strcmp(str, "NOTSET")) { + return LTTNG_LOGLEVEL_PYTHON_NOTSET; + } else { + return -1; + } +} + /* * Maps loglevel from string to value */ @@ -402,6 +308,10 @@ int loglevel_str_to_value(const char *inputstr) int i = 0; char str[LTTNG_SYMBOL_NAME_LEN]; + if (!inputstr || strlen(inputstr) == 0) { + return -1; + } + /* * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is * added at the end of the loop so a the upper bound we avoid the overflow. @@ -514,7 +424,10 @@ char *print_exclusions(int count, char **names) /* add length of preamble + one for NUL - one for last (missing) comma */ length += strlen(preamble); - ret = malloc(length); + ret = zmalloc(length); + if (!ret) { + return NULL; + } strncpy(ret, preamble, length); for (i = 0; i < count; i++) { strcat(ret, names[i]); @@ -573,11 +486,25 @@ int check_exclusion_subsets(const char *event_name, goto error; } if (e == '*') { + char *string; + char **new_exclusion_list; + /* Excluder is a proper subset of event */ + string = lttng_strndup(next_excluder, excluder_length); + if (!string) { + PERROR("lttng_strndup error"); + goto error; + } + new_exclusion_list = realloc(exclusion_list, + sizeof(char *) * (exclusion_count + 1)); + if (!new_exclusion_list) { + PERROR("realloc"); + free(string); + goto error; + } + exclusion_list = new_exclusion_list; exclusion_count++; - exclusion_list = realloc(exclusion_list, sizeof(char **) * exclusion_count); - exclusion_list[exclusion_count - 1] = strndup(next_excluder, excluder_length); - + exclusion_list[exclusion_count - 1] = string; break; } if (x != e) { @@ -614,6 +541,24 @@ end: *exclusion_list_ptr = exclusion_list; return ret; } + +static void warn_on_truncated_exclusion_names(char **exclusion_list, + int exclusion_count, int *warn) +{ + size_t i = 0; + + for (i = 0; i < exclusion_count; ++i) { + const char *name = exclusion_list[i]; + size_t len = strlen(name); + + if (len >= LTTNG_SYMBOL_NAME_LEN) { + WARN("Event exclusion \"%s\" will be truncated", + name); + *warn = 1; + } + } +} + /* * Enabling event using the lttng API. * Note: in case of error only the last error code will be return. @@ -632,11 +577,6 @@ static int enable_events(char *session_name) memset(&dom, 0, sizeof(dom)); if (opt_kernel) { - if (opt_filter) { - ERR("Filter not implement for kernel tracing yet"); - ret = CMD_ERROR; - goto error; - } if (opt_loglevel) { WARN("Kernel loglevels are not supported."); } @@ -658,16 +598,31 @@ static int enable_events(char *session_name) dom.type = LTTNG_DOMAIN_LOG4J; /* Default. */ dom.buf_type = LTTNG_BUFFER_PER_UID; + } else if (opt_python) { + dom.type = LTTNG_DOMAIN_PYTHON; + /* Default. */ + dom.buf_type = LTTNG_BUFFER_PER_UID; } else { - print_missing_domain(); - ret = CMD_ERROR; - goto error; + /* Checked by the caller. */ + assert(0); } - if (opt_kernel && opt_exclude) { - ERR("Event name exclusions are not yet implemented for kernel events"); - ret = CMD_ERROR; - goto error; + if (opt_exclude) { + switch (dom.type) { + case LTTNG_DOMAIN_KERNEL: + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: + ERR("Event name exclusions are not yet implemented for %s events", + get_domain_str(dom.type)); + ret = CMD_ERROR; + goto error; + case LTTNG_DOMAIN_UST: + /* Exclusions supported */ + break; + default: + assert(0); + } } channel_name = opt_channel_name; @@ -692,7 +647,7 @@ static int enable_events(char *session_name) /* Default setup for enable all */ if (opt_kernel) { ev.type = opt_event_type; - ev.name[0] = '\0'; + strcpy(ev.name, "*"); /* kernel loglevels not implemented */ ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else { @@ -700,13 +655,15 @@ static int enable_events(char *session_name) strcpy(ev.name, "*"); ev.loglevel_type = opt_loglevel_type; if (opt_loglevel) { - assert(opt_userspace || opt_jul || opt_log4j); + assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev.loglevel = loglevel_str_to_value(opt_loglevel); } else if (opt_jul) { ev.loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel); + } else if (opt_python) { + ev.loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev.loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); @@ -714,11 +671,15 @@ static int enable_events(char *session_name) goto error; } } else { - assert(opt_userspace || opt_jul || opt_log4j); + assert(opt_userspace || opt_jul || opt_log4j || opt_python); if (opt_userspace) { ev.loglevel = -1; - } else if (opt_jul || opt_log4j) { + } else if (opt_jul) { ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL; + } else if (opt_log4j) { + ev.loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; + } else if (opt_python) { + ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } } @@ -730,6 +691,9 @@ static int enable_events(char *session_name) goto error; } ev.exclusion = 1; + + warn_on_truncated_exclusion_names(exclusion_list, + exclusion_count, &warn); } if (!opt_filter) { ret = lttng_enable_event_with_exclusions(handle, @@ -743,6 +707,16 @@ static int enable_events(char *session_name) print_channel_name(channel_name), session_name); warn = 1; break; + case LTTNG_ERR_TRACE_ALREADY_STARTED: + { + const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; + ERR("Events: %s (channel %s, session %s)", + msg, + print_channel_name(channel_name), + session_name); + error = 1; + break; + } default: ERR("Events: %s (channel %s, session %s)", lttng_strerror(ret), @@ -760,6 +734,12 @@ static int enable_events(char *session_name) case LTTNG_EVENT_TRACEPOINT: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); + + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, @@ -768,6 +748,12 @@ static int enable_events(char *session_name) free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); + + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } MSG("All %s tracepoints%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, @@ -777,13 +763,20 @@ static int enable_events(char *session_name) break; case LTTNG_EVENT_SYSCALL: if (opt_kernel) { - MSG("All kernel system calls are enabled in channel %s", + MSG("All %s system calls are enabled in channel %s", + get_domain_str(dom.type), print_channel_name(channel_name)); } break; case LTTNG_EVENT_ALL: if (opt_loglevel && dom.type != LTTNG_DOMAIN_KERNEL) { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); + + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } MSG("All %s events%s are enabled in channel %s for loglevel %s", get_domain_str(dom.type), exclusion_string, @@ -792,6 +785,12 @@ static int enable_events(char *session_name) free(exclusion_string); } else { char *exclusion_string = print_exclusions(exclusion_count, exclusion_list); + + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } MSG("All %s events%s are enabled in channel %s", get_domain_str(dom.type), exclusion_string, @@ -819,6 +818,16 @@ static int enable_events(char *session_name) print_channel_name(channel_name), session_name); warn = 1; break; + case LTTNG_ERR_TRACE_ALREADY_STARTED: + { + const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; + ERR("All events: %s (channel %s, session %s, filter \'%s\')", + msg, + print_channel_name(channel_name), + session_name, opt_filter); + error = 1; + break; + } default: ERR("All events: %s (channel %s, session %s, filter \'%s\')", lttng_strerror(command_ret), @@ -853,7 +862,7 @@ static int enable_events(char *session_name) ev.enabled = 0; success = 0; } - ret = mi_lttng_event(writer, &ev, 1); + ret = mi_lttng_event(writer, &ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; @@ -900,9 +909,12 @@ static int enable_events(char *session_name) print_channel_name(channel_name)); switch (opt_event_type) { - case LTTNG_EVENT_ALL: /* Default behavior is tracepoint */ - ev.type = LTTNG_EVENT_TRACEPOINT; - /* Fall-through */ + case LTTNG_EVENT_ALL: /* Enable tracepoints and syscalls */ + /* If event name differs from *, select tracepoint. */ + if (strcmp(ev.name, "*")) { + ev.type = LTTNG_EVENT_TRACEPOINT; + } + break; case LTTNG_EVENT_TRACEPOINT: break; case LTTNG_EVENT_PROBE: @@ -921,14 +933,9 @@ static int enable_events(char *session_name) goto error; } break; - case LTTNG_EVENT_FUNCTION_ENTRY: - strncpy(ev.attr.ftrace.symbol_name, opt_function_entry_symbol, - LTTNG_SYMBOL_NAME_LEN); - ev.attr.ftrace.symbol_name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; - break; case LTTNG_EVENT_SYSCALL: - MSG("per-syscall selection not supported yet. Use \"-a\" " - "for all syscalls."); + ev.type = LTTNG_EVENT_SYSCALL; + break; default: ret = CMD_UNDEFINED; goto error; @@ -937,14 +944,6 @@ static int enable_events(char *session_name) /* kernel loglevels not implemented */ ev.loglevel_type = LTTNG_EVENT_LOGLEVEL_ALL; } else if (opt_userspace) { /* User-space tracer action */ -#if 0 - if (opt_cmd_name != NULL || opt_pid) { - MSG("Only supporting tracing all UST processes (-u) for now."); - ret = CMD_UNDEFINED; - goto error; - } -#endif - DBG("Enabling UST event %s for channel %s, loglevel %s", event_name, print_channel_name(channel_name), opt_loglevel ? : ""); @@ -959,7 +958,6 @@ static int enable_events(char *session_name) break; case LTTNG_EVENT_PROBE: case LTTNG_EVENT_FUNCTION: - case LTTNG_EVENT_FUNCTION_ENTRY: case LTTNG_EVENT_SYSCALL: default: ERR("Event type not available for user-space tracing"); @@ -988,6 +986,9 @@ static int enable_events(char *session_name) if (ret == CMD_ERROR) { goto error; } + + warn_on_truncated_exclusion_names( + exclusion_list, exclusion_count, &warn); } ev.loglevel_type = opt_loglevel_type; @@ -1001,7 +1002,7 @@ static int enable_events(char *session_name) } else { ev.loglevel = -1; } - } else if (opt_jul || opt_log4j) { + } else if (opt_jul || opt_log4j || opt_python) { if (opt_event_type != LTTNG_EVENT_ALL && opt_event_type != LTTNG_EVENT_TRACEPOINT) { ERR("Event type not supported for domain."); @@ -1015,6 +1016,8 @@ static int enable_events(char *session_name) ev.loglevel = loglevel_jul_str_to_value(opt_loglevel); } else if (opt_log4j) { ev.loglevel = loglevel_log4j_str_to_value(opt_loglevel); + } else if (opt_python) { + ev.loglevel = loglevel_python_str_to_value(opt_loglevel); } if (ev.loglevel == -1) { ERR("Unknown loglevel %s", opt_loglevel); @@ -1026,15 +1029,15 @@ static int enable_events(char *session_name) ev.loglevel = LTTNG_LOGLEVEL_JUL_ALL; } else if (opt_log4j) { ev.loglevel = LTTNG_LOGLEVEL_LOG4J_ALL; + } else if (opt_python) { + ev.loglevel = LTTNG_LOGLEVEL_PYTHON_DEBUG; } } ev.type = LTTNG_EVENT_TRACEPOINT; strncpy(ev.name, event_name, LTTNG_SYMBOL_NAME_LEN); ev.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0'; } else { - print_missing_domain(); - ret = CMD_ERROR; - goto error; + assert(0); } if (!opt_filter) { @@ -1044,6 +1047,11 @@ static int enable_events(char *session_name) &ev, channel_name, NULL, exclusion_count, exclusion_list); exclusion_string = print_exclusions(exclusion_count, exclusion_list); + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } if (command_ret < 0) { /* Turn ret to positive value to handle the positive error code */ switch (-command_ret) { @@ -1054,6 +1062,17 @@ static int enable_events(char *session_name) print_channel_name(channel_name), session_name); warn = 1; break; + case LTTNG_ERR_TRACE_ALREADY_STARTED: + { + const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; + ERR("Event %s%s: %s (channel %s, session %s)", event_name, + exclusion_string, + msg, + print_channel_name(channel_name), + session_name); + error = 1; + break; + } default: ERR("Event %s%s: %s (channel %s, session %s)", event_name, exclusion_string, @@ -1067,17 +1086,29 @@ static int enable_events(char *session_name) } error_holder = command_ret; } else { - /* So we don't print the default channel name for agent domain. */ - if (dom.type == LTTNG_DOMAIN_JUL || - dom.type == LTTNG_DOMAIN_LOG4J) { - MSG("%s event %s%s enabled.", - get_domain_str(dom.type), event_name, - exclusion_string); - } else { + switch (dom.type) { + case LTTNG_DOMAIN_KERNEL: + case LTTNG_DOMAIN_UST: MSG("%s event %s%s created in channel %s", - get_domain_str(dom.type), event_name, - exclusion_string, - print_channel_name(channel_name)); + get_domain_str(dom.type), + event_name, + exclusion_string, + print_channel_name(channel_name)); + break; + case LTTNG_DOMAIN_JUL: + case LTTNG_DOMAIN_LOG4J: + case LTTNG_DOMAIN_PYTHON: + /* + * Don't print the default channel + * name for agent domains. + */ + MSG("%s event %s%s enabled", + get_domain_str(dom.type), + event_name, + exclusion_string); + break; + default: + assert(0); } } free(exclusion_string); @@ -1092,7 +1123,11 @@ static int enable_events(char *session_name) command_ret = lttng_enable_event_with_exclusions(handle, &ev, channel_name, opt_filter, exclusion_count, exclusion_list); exclusion_string = print_exclusions(exclusion_count, exclusion_list); - + if (!exclusion_string) { + PERROR("Cannot allocate exclusion_string"); + error = 1; + goto end; + } if (command_ret < 0) { switch (-command_ret) { case LTTNG_ERR_FILTER_EXIST: @@ -1103,6 +1138,17 @@ static int enable_events(char *session_name) print_channel_name(channel_name), session_name); warn = 1; break; + case LTTNG_ERR_TRACE_ALREADY_STARTED: + { + const char *msg = "The command tried to enable an event in a new domain for a session that has already been started once."; + ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name, + exclusion_string, + msg, + print_channel_name(channel_name), + session_name, opt_filter); + error = 1; + break; + } default: ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev.name, exclusion_string, @@ -1132,7 +1178,7 @@ static int enable_events(char *session_name) ev.enabled = 1; } - ret = mi_lttng_event(writer, &ev, 1); + ret = mi_lttng_event(writer, &ev, 1, handle->domain.type); if (ret) { ret = CMD_ERROR; goto error; @@ -1220,7 +1266,7 @@ int cmd_enable_events(int argc, const char **argv) while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_HELP: - usage(stdout); + SHOW_HELP(); goto end; case OPT_TRACEPOINT: opt_event_type = LTTNG_EVENT_TRACEPOINT; @@ -1231,9 +1277,6 @@ int cmd_enable_events(int argc, const char **argv) case OPT_FUNCTION: opt_event_type = LTTNG_EVENT_FUNCTION; break; - case OPT_FUNCTION_ENTRY: - opt_event_type = LTTNG_EVENT_FUNCTION_ENTRY; - break; case OPT_SYSCALL: opt_event_type = LTTNG_EVENT_SYSCALL; break; @@ -1256,7 +1299,6 @@ int cmd_enable_events(int argc, const char **argv) case OPT_EXCLUDE: break; default: - usage(stderr); ret = CMD_UNDEFINED; goto end; } @@ -1273,6 +1315,13 @@ int cmd_enable_events(int argc, const char **argv) } } + ret = print_missing_or_multiple_domains( + opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python); + if (ret) { + ret = CMD_ERROR; + goto end; + } + /* Mi check */ if (lttng_opt_mi) { writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi); @@ -1301,7 +1350,6 @@ int cmd_enable_events(int argc, const char **argv) opt_event_list = (char*) poptGetArg(pc); if (opt_event_list == NULL && opt_enable_all == 0) { ERR("Missing event name(s).\n"); - usage(stderr); ret = CMD_ERROR; goto end; }