2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
4 * SPDX-License-Identifier: GPL-2.0-only
14 #include <sys/types.h>
19 #include <common/sessiond-comm/sessiond-comm.h>
20 #include <common/compat/string.h>
21 #include <common/compat/getenv.h>
22 #include <common/string-utils/string-utils.h>
23 #include <common/utils.h>
25 #include <lttng/constant.h>
27 #include <common/mi-lttng.h>
29 #include "../command.h"
30 #include "../uprobe.h"
32 #if (LTTNG_SYMBOL_NAME_LEN == 256)
33 #define LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API "255"
36 static char *opt_event_list
;
37 static int opt_event_type
;
38 static const char *opt_loglevel
;
39 static int opt_loglevel_type
;
40 static int opt_kernel
;
41 static char *opt_session_name
;
42 static int opt_userspace
;
45 static int opt_python
;
46 static int opt_enable_all
;
47 static char *opt_probe
;
48 static char *opt_userspace_probe
;
49 static char *opt_function
;
50 static char *opt_channel_name
;
51 static char *opt_filter
;
52 static char *opt_exclude
;
54 #ifdef LTTNG_EMBED_HELP
55 static const char help_msg
[] =
56 #include <lttng-enable-event.1.h>
75 static struct lttng_handle
*handle
;
76 static struct mi_writer
*writer
;
78 static struct poptOption long_options
[] = {
79 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
80 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
81 {"session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, 0, 0},
82 {"all", 'a', POPT_ARG_VAL
, &opt_enable_all
, 1, 0, 0},
83 {"channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, 0, 0},
84 {"kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, 0, 0},
85 {"userspace", 'u', POPT_ARG_NONE
, 0, OPT_USERSPACE
, 0, 0},
86 {"jul", 'j', POPT_ARG_VAL
, &opt_jul
, 1, 0, 0},
87 {"log4j", 'l', POPT_ARG_VAL
, &opt_log4j
, 1, 0, 0},
88 {"python", 'p', POPT_ARG_VAL
, &opt_python
, 1, 0, 0},
89 {"tracepoint", 0, POPT_ARG_NONE
, 0, OPT_TRACEPOINT
, 0, 0},
90 {"probe", 0, POPT_ARG_STRING
, &opt_probe
, OPT_PROBE
, 0, 0},
91 {"userspace-probe",0, POPT_ARG_STRING
, &opt_userspace_probe
, OPT_USERSPACE_PROBE
, 0, 0},
92 {"function", 0, POPT_ARG_STRING
, &opt_function
, OPT_FUNCTION
, 0, 0},
93 {"syscall", 0, POPT_ARG_NONE
, 0, OPT_SYSCALL
, 0, 0},
94 {"loglevel", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL
, 0, 0},
95 {"loglevel-only", 0, POPT_ARG_STRING
, 0, OPT_LOGLEVEL_ONLY
, 0, 0},
96 {"list-options", 0, POPT_ARG_NONE
, NULL
, OPT_LIST_OPTIONS
, NULL
, NULL
},
97 {"filter", 'f', POPT_ARG_STRING
, &opt_filter
, OPT_FILTER
, 0, 0},
98 {"exclude", 'x', POPT_ARG_STRING
, &opt_exclude
, OPT_EXCLUDE
, 0, 0},
103 * Parse probe options.
105 static int parse_probe_opts(struct lttng_event
*ev
, char *opt
)
107 int ret
= CMD_SUCCESS
;
110 #define S_HEX_LEN_SCANF_IS_A_BROKEN_API "18" /* 18 is (19 - 1) (\0 is extra) */
111 char name
[LTTNG_SYMBOL_NAME_LEN
];
118 /* Check for symbol+offset */
119 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
120 "[^'+']+%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", name
, s_hex
);
122 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
123 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
124 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
125 if (*s_hex
== '\0') {
126 ERR("Invalid probe offset %s", s_hex
);
130 ev
->attr
.probe
.offset
= strtoul(s_hex
, NULL
, 0);
131 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
132 ev
->attr
.probe
.addr
= 0;
136 /* Check for symbol */
137 if (isalpha(name
[0]) || name
[0] == '_') {
138 match
= sscanf(opt
, "%" LTTNG_SYMBOL_NAME_LEN_SCANF_IS_A_BROKEN_API
"s",
141 strncpy(ev
->attr
.probe
.symbol_name
, name
, LTTNG_SYMBOL_NAME_LEN
);
142 ev
->attr
.probe
.symbol_name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
143 DBG("probe symbol %s", ev
->attr
.probe
.symbol_name
);
144 ev
->attr
.probe
.offset
= 0;
145 DBG("probe offset %" PRIu64
, ev
->attr
.probe
.offset
);
146 ev
->attr
.probe
.addr
= 0;
151 /* Check for address */
152 match
= sscanf(opt
, "%" S_HEX_LEN_SCANF_IS_A_BROKEN_API
"s", s_hex
);
155 * Return an error if the first character of the tentative
156 * address is NULL or not a digit. It can be "0" if the address
157 * is in hexadecimal and can be 1 to 9 if it's in decimal.
159 if (*s_hex
== '\0' || !isdigit(*s_hex
)) {
160 ERR("Invalid probe description %s", s_hex
);
164 ev
->attr
.probe
.addr
= strtoul(s_hex
, NULL
, 0);
165 DBG("probe addr %" PRIu64
, ev
->attr
.probe
.addr
);
166 ev
->attr
.probe
.offset
= 0;
167 memset(ev
->attr
.probe
.symbol_name
, 0, LTTNG_SYMBOL_NAME_LEN
);
179 * Maps LOG4j loglevel from string to value
182 int loglevel_log4j_str_to_value(const char *inputstr
)
185 char str
[LTTNG_SYMBOL_NAME_LEN
];
187 if (!inputstr
|| strlen(inputstr
) == 0) {
192 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
193 * added at the end of the loop so a the upper bound we avoid the overflow.
195 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
196 str
[i
] = toupper(inputstr
[i
]);
201 if (!strcmp(str
, "LOG4J_OFF") || !strcmp(str
, "OFF")) {
202 return LTTNG_LOGLEVEL_LOG4J_OFF
;
203 } else if (!strcmp(str
, "LOG4J_FATAL") || !strcmp(str
, "FATAL")) {
204 return LTTNG_LOGLEVEL_LOG4J_FATAL
;
205 } else if (!strcmp(str
, "LOG4J_ERROR") || !strcmp(str
, "ERROR")) {
206 return LTTNG_LOGLEVEL_LOG4J_ERROR
;
207 } else if (!strcmp(str
, "LOG4J_WARN") || !strcmp(str
, "WARN")) {
208 return LTTNG_LOGLEVEL_LOG4J_WARN
;
209 } else if (!strcmp(str
, "LOG4J_INFO") || !strcmp(str
, "INFO")) {
210 return LTTNG_LOGLEVEL_LOG4J_INFO
;
211 } else if (!strcmp(str
, "LOG4J_DEBUG") || !strcmp(str
, "DEBUG")) {
212 return LTTNG_LOGLEVEL_LOG4J_DEBUG
;
213 } else if (!strcmp(str
, "LOG4J_TRACE") || !strcmp(str
, "TRACE")) {
214 return LTTNG_LOGLEVEL_LOG4J_TRACE
;
215 } else if (!strcmp(str
, "LOG4J_ALL") || !strcmp(str
, "ALL")) {
216 return LTTNG_LOGLEVEL_LOG4J_ALL
;
223 * Maps JUL loglevel from string to value
226 int loglevel_jul_str_to_value(const char *inputstr
)
229 char str
[LTTNG_SYMBOL_NAME_LEN
];
231 if (!inputstr
|| strlen(inputstr
) == 0) {
236 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
237 * added at the end of the loop so a the upper bound we avoid the overflow.
239 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
240 str
[i
] = toupper(inputstr
[i
]);
245 if (!strcmp(str
, "JUL_OFF") || !strcmp(str
, "OFF")) {
246 return LTTNG_LOGLEVEL_JUL_OFF
;
247 } else if (!strcmp(str
, "JUL_SEVERE") || !strcmp(str
, "SEVERE")) {
248 return LTTNG_LOGLEVEL_JUL_SEVERE
;
249 } else if (!strcmp(str
, "JUL_WARNING") || !strcmp(str
, "WARNING")) {
250 return LTTNG_LOGLEVEL_JUL_WARNING
;
251 } else if (!strcmp(str
, "JUL_INFO") || !strcmp(str
, "INFO")) {
252 return LTTNG_LOGLEVEL_JUL_INFO
;
253 } else if (!strcmp(str
, "JUL_CONFIG") || !strcmp(str
, "CONFIG")) {
254 return LTTNG_LOGLEVEL_JUL_CONFIG
;
255 } else if (!strcmp(str
, "JUL_FINE") || !strcmp(str
, "FINE")) {
256 return LTTNG_LOGLEVEL_JUL_FINE
;
257 } else if (!strcmp(str
, "JUL_FINER") || !strcmp(str
, "FINER")) {
258 return LTTNG_LOGLEVEL_JUL_FINER
;
259 } else if (!strcmp(str
, "JUL_FINEST") || !strcmp(str
, "FINEST")) {
260 return LTTNG_LOGLEVEL_JUL_FINEST
;
261 } else if (!strcmp(str
, "JUL_ALL") || !strcmp(str
, "ALL")) {
262 return LTTNG_LOGLEVEL_JUL_ALL
;
269 * Maps Python loglevel from string to value
272 int loglevel_python_str_to_value(const char *inputstr
)
275 char str
[LTTNG_SYMBOL_NAME_LEN
];
277 if (!inputstr
|| strlen(inputstr
) == 0) {
282 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
283 * added at the end of the loop so a the upper bound we avoid the overflow.
285 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
286 str
[i
] = toupper(inputstr
[i
]);
291 if (!strcmp(str
, "PYTHON_CRITICAL") || !strcmp(str
, "CRITICAL")) {
292 return LTTNG_LOGLEVEL_PYTHON_CRITICAL
;
293 } else if (!strcmp(str
, "PYTHON_ERROR") || !strcmp(str
, "ERROR")) {
294 return LTTNG_LOGLEVEL_PYTHON_ERROR
;
295 } else if (!strcmp(str
, "PYTHON_WARNING") || !strcmp(str
, "WARNING")) {
296 return LTTNG_LOGLEVEL_PYTHON_WARNING
;
297 } else if (!strcmp(str
, "PYTHON_INFO") || !strcmp(str
, "INFO")) {
298 return LTTNG_LOGLEVEL_PYTHON_INFO
;
299 } else if (!strcmp(str
, "PYTNON_DEBUG") || !strcmp(str
, "DEBUG")) {
300 return LTTNG_LOGLEVEL_PYTHON_DEBUG
;
301 } else if (!strcmp(str
, "PYTHON_NOTSET") || !strcmp(str
, "NOTSET")) {
302 return LTTNG_LOGLEVEL_PYTHON_NOTSET
;
309 * Maps loglevel from string to value
312 int loglevel_str_to_value(const char *inputstr
)
315 char str
[LTTNG_SYMBOL_NAME_LEN
];
317 if (!inputstr
|| strlen(inputstr
) == 0) {
322 * Loop up to LTTNG_SYMBOL_NAME_LEN minus one because the NULL bytes is
323 * added at the end of the loop so a the upper bound we avoid the overflow.
325 while (i
< (LTTNG_SYMBOL_NAME_LEN
- 1) && inputstr
[i
] != '\0') {
326 str
[i
] = toupper(inputstr
[i
]);
330 if (!strcmp(str
, "TRACE_EMERG") || !strcmp(str
, "EMERG")) {
331 return LTTNG_LOGLEVEL_EMERG
;
332 } else if (!strcmp(str
, "TRACE_ALERT") || !strcmp(str
, "ALERT")) {
333 return LTTNG_LOGLEVEL_ALERT
;
334 } else if (!strcmp(str
, "TRACE_CRIT") || !strcmp(str
, "CRIT")) {
335 return LTTNG_LOGLEVEL_CRIT
;
336 } else if (!strcmp(str
, "TRACE_ERR") || !strcmp(str
, "ERR")) {
337 return LTTNG_LOGLEVEL_ERR
;
338 } else if (!strcmp(str
, "TRACE_WARNING") || !strcmp(str
, "WARNING")) {
339 return LTTNG_LOGLEVEL_WARNING
;
340 } else if (!strcmp(str
, "TRACE_NOTICE") || !strcmp(str
, "NOTICE")) {
341 return LTTNG_LOGLEVEL_NOTICE
;
342 } else if (!strcmp(str
, "TRACE_INFO") || !strcmp(str
, "INFO")) {
343 return LTTNG_LOGLEVEL_INFO
;
344 } else if (!strcmp(str
, "TRACE_DEBUG_SYSTEM") || !strcmp(str
, "DEBUG_SYSTEM") || !strcmp(str
, "SYSTEM")) {
345 return LTTNG_LOGLEVEL_DEBUG_SYSTEM
;
346 } else if (!strcmp(str
, "TRACE_DEBUG_PROGRAM") || !strcmp(str
, "DEBUG_PROGRAM") || !strcmp(str
, "PROGRAM")) {
347 return LTTNG_LOGLEVEL_DEBUG_PROGRAM
;
348 } else if (!strcmp(str
, "TRACE_DEBUG_PROCESS") || !strcmp(str
, "DEBUG_PROCESS") || !strcmp(str
, "PROCESS")) {
349 return LTTNG_LOGLEVEL_DEBUG_PROCESS
;
350 } else if (!strcmp(str
, "TRACE_DEBUG_MODULE") || !strcmp(str
, "DEBUG_MODULE") || !strcmp(str
, "MODULE")) {
351 return LTTNG_LOGLEVEL_DEBUG_MODULE
;
352 } else if (!strcmp(str
, "TRACE_DEBUG_UNIT") || !strcmp(str
, "DEBUG_UNIT") || !strcmp(str
, "UNIT")) {
353 return LTTNG_LOGLEVEL_DEBUG_UNIT
;
354 } else if (!strcmp(str
, "TRACE_DEBUG_FUNCTION") || !strcmp(str
, "DEBUG_FUNCTION") || !strcmp(str
, "FUNCTION")) {
355 return LTTNG_LOGLEVEL_DEBUG_FUNCTION
;
356 } else if (!strcmp(str
, "TRACE_DEBUG_LINE") || !strcmp(str
, "DEBUG_LINE") || !strcmp(str
, "LINE")) {
357 return LTTNG_LOGLEVEL_DEBUG_LINE
;
358 } else if (!strcmp(str
, "TRACE_DEBUG") || !strcmp(str
, "DEBUG")) {
359 return LTTNG_LOGLEVEL_DEBUG
;
366 const char *print_channel_name(const char *name
)
368 return name
? : DEFAULT_CHANNEL_NAME
;
372 const char *print_raw_channel_name(const char *name
)
374 return name
? : "<default>";
378 * Mi print exlcusion list
381 int mi_print_exclusion(char **names
)
384 int count
= names
? strutils_array_of_strings_len(names
) : 0;
392 ret
= mi_lttng_writer_open_element(writer
, config_element_exclusions
);
397 for (i
= 0; i
< count
; i
++) {
398 ret
= mi_lttng_writer_write_element_string(writer
,
399 config_element_exclusion
, names
[i
]);
405 /* Close exclusions element */
406 ret
= mi_lttng_writer_close_element(writer
);
413 * Return allocated string for pretty-printing exclusion names.
416 char *print_exclusions(char **names
)
420 const char preamble
[] = " excluding ";
422 int count
= names
? strutils_array_of_strings_len(names
) : 0;
428 /* calculate total required length */
429 for (i
= 0; i
< count
; i
++) {
430 length
+= strlen(names
[i
]) + 4;
433 length
+= sizeof(preamble
);
434 ret
= zmalloc(length
);
438 strncpy(ret
, preamble
, length
);
439 for (i
= 0; i
< count
; i
++) {
441 strcat(ret
, names
[i
]);
443 if (i
!= count
- 1) {
452 int check_exclusion_subsets(const char *event_name
, const char *exclusion
)
456 const char *e
= event_name
;
457 const char *x
= exclusion
;
459 /* Scan both the excluder and the event letter by letter */
473 /* Event is a subset of the excluder */
474 ERR("Event %s: %s excludes all events from %s",
475 event_name
, exclusion
, event_name
);
481 * Reached the end of the event name before the
482 * end of the exclusion: this is valid.
504 WARN("Event %s: %s does not exclude any events from %s",
505 event_name
, exclusion
, event_name
);
512 int create_exclusion_list_and_validate(const char *event_name
,
513 const char *exclusions_arg
,
514 char ***exclusion_list
)
517 char **exclusions
= NULL
;
519 /* Event name must be a valid globbing pattern to allow exclusions. */
520 if (!strutils_is_star_glob_pattern(event_name
)) {
521 ERR("Event %s: Exclusions can only be used with a globbing pattern",
526 /* Split exclusions. */
527 exclusions
= strutils_split(exclusions_arg
, ',', true);
533 * If the event name is a star-at-end only globbing pattern,
534 * then we can validate the individual exclusions. Otherwise
535 * all exclusions are passed to the session daemon.
537 if (strutils_is_star_at_the_end_only_glob_pattern(event_name
)) {
538 char * const *exclusion
;
540 for (exclusion
= exclusions
; *exclusion
; exclusion
++) {
541 if (!strutils_is_star_glob_pattern(*exclusion
) ||
542 strutils_is_star_at_the_end_only_glob_pattern(*exclusion
)) {
543 ret
= check_exclusion_subsets(event_name
, *exclusion
);
551 *exclusion_list
= exclusions
;
557 strutils_free_null_terminated_array_of_strings(exclusions
);
563 static void warn_on_truncated_exclusion_names(char * const *exclusion_list
,
566 char * const *exclusion
;
568 for (exclusion
= exclusion_list
; *exclusion
; exclusion
++) {
569 if (strlen(*exclusion
) >= LTTNG_SYMBOL_NAME_LEN
) {
570 WARN("Event exclusion \"%s\" will be truncated",
578 * Enabling event using the lttng API.
579 * Note: in case of error only the last error code will be return.
581 static int enable_events(char *session_name
)
583 int ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
;
584 int error_holder
= CMD_SUCCESS
, warn
= 0, error
= 0, success
= 1;
585 char *event_name
, *channel_name
= NULL
;
586 struct lttng_event
*ev
;
587 struct lttng_domain dom
;
588 char **exclusion_list
= NULL
;
589 struct lttng_userspace_probe_location
*uprobe_loc
= NULL
;
591 memset(&dom
, 0, sizeof(dom
));
593 ev
= lttng_event_create();
601 WARN("Kernel loglevels are not supported.");
605 /* Create lttng domain */
607 dom
.type
= LTTNG_DOMAIN_KERNEL
;
608 dom
.buf_type
= LTTNG_BUFFER_GLOBAL
;
609 } else if (opt_userspace
) {
610 dom
.type
= LTTNG_DOMAIN_UST
;
612 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
613 } else if (opt_jul
) {
614 dom
.type
= LTTNG_DOMAIN_JUL
;
616 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
617 } else if (opt_log4j
) {
618 dom
.type
= LTTNG_DOMAIN_LOG4J
;
620 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
621 } else if (opt_python
) {
622 dom
.type
= LTTNG_DOMAIN_PYTHON
;
624 dom
.buf_type
= LTTNG_BUFFER_PER_UID
;
626 /* Checked by the caller. */
632 case LTTNG_DOMAIN_KERNEL
:
633 case LTTNG_DOMAIN_JUL
:
634 case LTTNG_DOMAIN_LOG4J
:
635 case LTTNG_DOMAIN_PYTHON
:
636 ERR("Event name exclusions are not yet implemented for %s events",
637 get_domain_str(dom
.type
));
640 case LTTNG_DOMAIN_UST
:
641 /* Exclusions supported */
649 * Adding a filter to a probe, function or userspace-probe would be
650 * denied by the kernel tracer as it's not supported at the moment. We
651 * do an early check here to warn the user.
653 if (opt_filter
&& opt_kernel
) {
654 switch (opt_event_type
) {
655 case LTTNG_EVENT_ALL
:
656 case LTTNG_EVENT_TRACEPOINT
:
657 case LTTNG_EVENT_SYSCALL
:
659 case LTTNG_EVENT_PROBE
:
660 case LTTNG_EVENT_USERSPACE_PROBE
:
661 case LTTNG_EVENT_FUNCTION
:
662 ERR("Filter expressions are not supported for %s events",
663 get_event_type_str(opt_event_type
));
672 channel_name
= opt_channel_name
;
674 handle
= lttng_create_handle(session_name
, &dom
);
675 if (handle
== NULL
) {
682 /* Open a events element */
683 ret
= mi_lttng_writer_open_element(writer
, config_element_events
);
690 if (opt_enable_all
) {
691 /* Default setup for enable all */
693 ev
->type
= opt_event_type
;
694 strcpy(ev
->name
, "*");
695 /* kernel loglevels not implemented */
696 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
698 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
699 strcpy(ev
->name
, "*");
700 ev
->loglevel_type
= opt_loglevel_type
;
702 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
704 ev
->loglevel
= loglevel_str_to_value(opt_loglevel
);
705 } else if (opt_jul
) {
706 ev
->loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
707 } else if (opt_log4j
) {
708 ev
->loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
709 } else if (opt_python
) {
710 ev
->loglevel
= loglevel_python_str_to_value(opt_loglevel
);
712 if (ev
->loglevel
== -1) {
713 ERR("Unknown loglevel %s", opt_loglevel
);
714 ret
= -LTTNG_ERR_INVALID
;
718 assert(opt_userspace
|| opt_jul
|| opt_log4j
|| opt_python
);
721 } else if (opt_jul
) {
722 ev
->loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
723 } else if (opt_log4j
) {
724 ev
->loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
725 } else if (opt_python
) {
726 ev
->loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
732 ret
= create_exclusion_list_and_validate("*",
733 opt_exclude
, &exclusion_list
);
740 warn_on_truncated_exclusion_names(exclusion_list
,
744 ret
= lttng_enable_event_with_exclusions(handle
,
747 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
751 case LTTNG_ERR_KERN_EVENT_EXIST
:
752 WARN("Kernel events already enabled (channel %s, session %s)",
753 print_channel_name(channel_name
), session_name
);
756 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
758 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
759 ERR("Events: %s (channel %s, session %s)",
761 print_channel_name(channel_name
),
767 ERR("Events: %s (channel %s, session %s)",
769 ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
770 ? print_raw_channel_name(channel_name
)
771 : print_channel_name(channel_name
),
779 switch (opt_event_type
) {
780 case LTTNG_EVENT_TRACEPOINT
:
781 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
782 char *exclusion_string
= print_exclusions(exclusion_list
);
784 if (!exclusion_string
) {
785 PERROR("Cannot allocate exclusion_string");
789 MSG("All %s tracepoints%s are enabled in channel %s for loglevel %s",
790 get_domain_str(dom
.type
),
792 print_channel_name(channel_name
),
794 free(exclusion_string
);
796 char *exclusion_string
= print_exclusions(exclusion_list
);
798 if (!exclusion_string
) {
799 PERROR("Cannot allocate exclusion_string");
803 MSG("All %s tracepoints%s are enabled in channel %s",
804 get_domain_str(dom
.type
),
806 print_channel_name(channel_name
));
807 free(exclusion_string
);
810 case LTTNG_EVENT_SYSCALL
:
812 MSG("All %s system calls are enabled in channel %s",
813 get_domain_str(dom
.type
),
814 print_channel_name(channel_name
));
817 case LTTNG_EVENT_ALL
:
818 if (opt_loglevel
&& dom
.type
!= LTTNG_DOMAIN_KERNEL
) {
819 char *exclusion_string
= print_exclusions(exclusion_list
);
821 if (!exclusion_string
) {
822 PERROR("Cannot allocate exclusion_string");
826 MSG("All %s events%s are enabled in channel %s for loglevel %s",
827 get_domain_str(dom
.type
),
829 print_channel_name(channel_name
),
831 free(exclusion_string
);
833 char *exclusion_string
= print_exclusions(exclusion_list
);
835 if (!exclusion_string
) {
836 PERROR("Cannot allocate exclusion_string");
840 MSG("All %s events%s are enabled in channel %s",
841 get_domain_str(dom
.type
),
843 print_channel_name(channel_name
));
844 free(exclusion_string
);
849 * We should not be here since lttng_enable_event should have
850 * failed on the event type.
857 command_ret
= lttng_enable_event_with_exclusions(handle
, ev
, channel_name
,
859 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
861 if (command_ret
< 0) {
862 switch (-command_ret
) {
863 case LTTNG_ERR_FILTER_EXIST
:
864 WARN("Filter on all events is already enabled"
865 " (channel %s, session %s)",
866 print_channel_name(channel_name
), session_name
);
869 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
871 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
872 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
874 print_channel_name(channel_name
),
875 session_name
, opt_filter
);
880 ERR("All events: %s (channel %s, session %s, filter \'%s\')",
881 lttng_strerror(command_ret
),
882 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
883 ? print_raw_channel_name(channel_name
)
884 : print_channel_name(channel_name
),
885 session_name
, opt_filter
);
889 error_holder
= command_ret
;
892 MSG("Filter '%s' successfully set", opt_filter
);
897 /* The wildcard * is used for kernel and ust domain to
898 * represent ALL. We copy * in event name to force the wildcard use
901 * Note: this is strictly for semantic and printing while in
902 * machine interface mode.
904 strcpy(ev
->name
, "*");
906 /* If we reach here the events are enabled */
907 if (!error
&& !warn
) {
913 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
919 /* print exclusion */
920 ret
= mi_print_exclusion(exclusion_list
);
927 ret
= mi_lttng_writer_write_element_bool(writer
,
928 mi_lttng_element_command_success
, success
);
934 /* Close event element */
935 ret
= mi_lttng_writer_close_element(writer
);
945 /* Strip event list */
946 event_name
= strtok(opt_event_list
, ",");
947 while (event_name
!= NULL
) {
948 /* Copy name and type of the event */
949 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
950 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
951 ev
->type
= opt_event_type
;
953 /* Kernel tracer action */
955 DBG("Enabling kernel event %s for channel %s",
957 print_channel_name(channel_name
));
959 switch (opt_event_type
) {
960 case LTTNG_EVENT_ALL
: /* Enable tracepoints and syscalls */
961 /* If event name differs from *, select tracepoint. */
962 if (strcmp(ev
->name
, "*")) {
963 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
966 case LTTNG_EVENT_TRACEPOINT
:
968 case LTTNG_EVENT_PROBE
:
969 ret
= parse_probe_opts(ev
, opt_probe
);
971 ERR("Unable to parse probe options");
976 case LTTNG_EVENT_USERSPACE_PROBE
:
977 assert(ev
->type
== LTTNG_EVENT_USERSPACE_PROBE
);
979 ret
= parse_userspace_probe_opts(opt_userspace_probe
, &uprobe_loc
);
982 case CMD_UNSUPPORTED
:
984 * Error message describing
985 * what is not supported was
986 * printed in the function.
991 ERR("Unable to parse userspace probe options");
997 ret
= lttng_event_set_userspace_probe_location(ev
, uprobe_loc
);
999 WARN("Failed to set probe location on event");
1004 /* Ownership of the uprobe location was transferred to the event. */
1007 case LTTNG_EVENT_FUNCTION
:
1008 ret
= parse_probe_opts(ev
, opt_function
);
1010 ERR("Unable to parse function probe options");
1015 case LTTNG_EVENT_SYSCALL
:
1016 ev
->type
= LTTNG_EVENT_SYSCALL
;
1019 ret
= CMD_UNDEFINED
;
1023 /* kernel loglevels not implemented */
1024 ev
->loglevel_type
= LTTNG_EVENT_LOGLEVEL_ALL
;
1025 } else if (opt_userspace
) { /* User-space tracer action */
1026 DBG("Enabling UST event %s for channel %s, loglevel %s", event_name
,
1027 print_channel_name(channel_name
), opt_loglevel
? : "<all>");
1029 switch (opt_event_type
) {
1030 case LTTNG_EVENT_ALL
: /* Default behavior is tracepoint */
1032 case LTTNG_EVENT_TRACEPOINT
:
1033 /* Copy name and type of the event */
1034 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
1035 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1036 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1038 case LTTNG_EVENT_PROBE
:
1039 case LTTNG_EVENT_FUNCTION
:
1040 case LTTNG_EVENT_SYSCALL
:
1041 case LTTNG_EVENT_USERSPACE_PROBE
:
1043 ERR("Event type not available for user-space tracing");
1044 ret
= CMD_UNSUPPORTED
;
1050 if (opt_event_type
!= LTTNG_EVENT_ALL
&& opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1051 ERR("Exclusion option can only be used with tracepoint events");
1055 /* Free previously allocated items */
1056 strutils_free_null_terminated_array_of_strings(
1058 exclusion_list
= NULL
;
1059 ret
= create_exclusion_list_and_validate(
1060 event_name
, opt_exclude
,
1067 warn_on_truncated_exclusion_names(
1068 exclusion_list
, &warn
);
1071 ev
->loglevel_type
= opt_loglevel_type
;
1073 ev
->loglevel
= loglevel_str_to_value(opt_loglevel
);
1074 if (ev
->loglevel
== -1) {
1075 ERR("Unknown loglevel %s", opt_loglevel
);
1076 ret
= -LTTNG_ERR_INVALID
;
1082 } else if (opt_jul
|| opt_log4j
|| opt_python
) {
1083 if (opt_event_type
!= LTTNG_EVENT_ALL
&&
1084 opt_event_type
!= LTTNG_EVENT_TRACEPOINT
) {
1085 ERR("Event type not supported for domain.");
1086 ret
= CMD_UNSUPPORTED
;
1090 ev
->loglevel_type
= opt_loglevel_type
;
1093 ev
->loglevel
= loglevel_jul_str_to_value(opt_loglevel
);
1094 } else if (opt_log4j
) {
1095 ev
->loglevel
= loglevel_log4j_str_to_value(opt_loglevel
);
1096 } else if (opt_python
) {
1097 ev
->loglevel
= loglevel_python_str_to_value(opt_loglevel
);
1099 if (ev
->loglevel
== -1) {
1100 ERR("Unknown loglevel %s", opt_loglevel
);
1101 ret
= -LTTNG_ERR_INVALID
;
1106 ev
->loglevel
= LTTNG_LOGLEVEL_JUL_ALL
;
1107 } else if (opt_log4j
) {
1108 ev
->loglevel
= LTTNG_LOGLEVEL_LOG4J_ALL
;
1109 } else if (opt_python
) {
1110 ev
->loglevel
= LTTNG_LOGLEVEL_PYTHON_DEBUG
;
1113 ev
->type
= LTTNG_EVENT_TRACEPOINT
;
1114 strncpy(ev
->name
, event_name
, LTTNG_SYMBOL_NAME_LEN
);
1115 ev
->name
[LTTNG_SYMBOL_NAME_LEN
- 1] = '\0';
1121 char *exclusion_string
;
1123 command_ret
= lttng_enable_event_with_exclusions(handle
,
1126 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
1128 exclusion_string
= print_exclusions(exclusion_list
);
1129 if (!exclusion_string
) {
1130 PERROR("Cannot allocate exclusion_string");
1134 if (command_ret
< 0) {
1135 /* Turn ret to positive value to handle the positive error code */
1136 switch (-command_ret
) {
1137 case LTTNG_ERR_KERN_EVENT_EXIST
:
1138 WARN("Kernel event %s%s already enabled (channel %s, session %s)",
1141 print_channel_name(channel_name
), session_name
);
1144 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1146 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1147 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1150 print_channel_name(channel_name
),
1155 case LTTNG_ERR_SDT_PROBE_SEMAPHORE
:
1156 ERR("SDT probes %s guarded by semaphores are not supported (channel %s, session %s)",
1157 event_name
, print_channel_name(channel_name
),
1162 ERR("Event %s%s: %s (channel %s, session %s)", event_name
,
1164 lttng_strerror(command_ret
),
1165 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1166 ? print_raw_channel_name(channel_name
)
1167 : print_channel_name(channel_name
),
1172 error_holder
= command_ret
;
1175 case LTTNG_DOMAIN_KERNEL
:
1176 case LTTNG_DOMAIN_UST
:
1177 MSG("%s event %s%s created in channel %s",
1178 get_domain_str(dom
.type
),
1181 print_channel_name(channel_name
));
1183 case LTTNG_DOMAIN_JUL
:
1184 case LTTNG_DOMAIN_LOG4J
:
1185 case LTTNG_DOMAIN_PYTHON
:
1187 * Don't print the default channel
1188 * name for agent domains.
1190 MSG("%s event %s%s enabled",
1191 get_domain_str(dom
.type
),
1199 free(exclusion_string
);
1203 char *exclusion_string
;
1205 /* Filter present */
1208 command_ret
= lttng_enable_event_with_exclusions(handle
, ev
, channel_name
,
1210 exclusion_list
? strutils_array_of_strings_len(exclusion_list
) : 0,
1212 exclusion_string
= print_exclusions(exclusion_list
);
1213 if (!exclusion_string
) {
1214 PERROR("Cannot allocate exclusion_string");
1218 if (command_ret
< 0) {
1219 switch (-command_ret
) {
1220 case LTTNG_ERR_FILTER_EXIST
:
1221 WARN("Filter on event %s%s is already enabled"
1222 " (channel %s, session %s)",
1225 print_channel_name(channel_name
), session_name
);
1228 case LTTNG_ERR_TRACE_ALREADY_STARTED
:
1230 const char *msg
= "The command tried to enable an event in a new domain for a session that has already been started once.";
1231 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
->name
,
1234 print_channel_name(channel_name
),
1235 session_name
, opt_filter
);
1240 ERR("Event %s%s: %s (channel %s, session %s, filter \'%s\')", ev
->name
,
1242 lttng_strerror(command_ret
),
1243 command_ret
== -LTTNG_ERR_NEED_CHANNEL_NAME
1244 ? print_raw_channel_name(channel_name
)
1245 : print_channel_name(channel_name
),
1246 session_name
, opt_filter
);
1250 error_holder
= command_ret
;
1253 MSG("Event %s%s: Filter '%s' successfully set",
1254 event_name
, exclusion_string
,
1257 free(exclusion_string
);
1268 ret
= mi_lttng_event(writer
, ev
, 1, handle
->domain
.type
);
1274 /* print exclusion */
1275 ret
= mi_print_exclusion(exclusion_list
);
1282 ret
= mi_lttng_writer_write_element_bool(writer
,
1283 mi_lttng_element_command_success
, success
);
1289 /* Close event element */
1290 ret
= mi_lttng_writer_close_element(writer
);
1298 event_name
= strtok(NULL
, ",");
1299 /* Reset warn, error and success */
1306 /* Close events element */
1307 ret
= mi_lttng_writer_close_element(writer
);
1320 lttng_destroy_handle(handle
);
1321 strutils_free_null_terminated_array_of_strings(exclusion_list
);
1322 lttng_userspace_probe_location_destroy(uprobe_loc
);
1324 /* Overwrite ret with error_holder if there was an actual error with
1325 * enabling an event.
1327 ret
= error_holder
? error_holder
: ret
;
1329 lttng_event_destroy(ev
);
1334 * Add event to trace session
1336 int cmd_enable_events(int argc
, const char **argv
)
1338 int opt
, ret
= CMD_SUCCESS
, command_ret
= CMD_SUCCESS
, success
= 1;
1339 static poptContext pc
;
1340 char *session_name
= NULL
;
1341 const char *leftover
= NULL
;
1342 int event_type
= -1;
1344 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
1345 poptReadDefaultConfig(pc
, 0);
1347 /* Default event type */
1348 opt_event_type
= LTTNG_EVENT_ALL
;
1350 while ((opt
= poptGetNextOpt(pc
)) != -1) {
1355 case OPT_TRACEPOINT
:
1356 opt_event_type
= LTTNG_EVENT_TRACEPOINT
;
1359 opt_event_type
= LTTNG_EVENT_PROBE
;
1361 case OPT_USERSPACE_PROBE
:
1362 opt_event_type
= LTTNG_EVENT_USERSPACE_PROBE
;
1365 opt_event_type
= LTTNG_EVENT_FUNCTION
;
1368 opt_event_type
= LTTNG_EVENT_SYSCALL
;
1374 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_RANGE
;
1375 opt_loglevel
= poptGetOptArg(pc
);
1377 case OPT_LOGLEVEL_ONLY
:
1378 opt_loglevel_type
= LTTNG_EVENT_LOGLEVEL_SINGLE
;
1379 opt_loglevel
= poptGetOptArg(pc
);
1381 case OPT_LIST_OPTIONS
:
1382 list_cmd_options(stdout
, long_options
);
1389 ret
= CMD_UNDEFINED
;
1393 /* Validate event type. Multiple event type are not supported. */
1394 if (event_type
== -1) {
1395 event_type
= opt_event_type
;
1397 if (event_type
!= opt_event_type
) {
1398 ERR("Multiple event type not supported.");
1405 ret
= print_missing_or_multiple_domains(
1406 opt_kernel
+ opt_userspace
+ opt_jul
+ opt_log4j
+ opt_python
);
1414 writer
= mi_lttng_writer_create(fileno(stdout
), lttng_opt_mi
);
1416 ret
= -LTTNG_ERR_NOMEM
;
1420 /* Open command element */
1421 ret
= mi_lttng_writer_command_open(writer
,
1422 mi_lttng_element_command_enable_event
);
1428 /* Open output element */
1429 ret
= mi_lttng_writer_open_element(writer
,
1430 mi_lttng_element_command_output
);
1437 opt_event_list
= (char*) poptGetArg(pc
);
1438 if (opt_event_list
== NULL
&& opt_enable_all
== 0) {
1439 ERR("Missing event name(s).\n");
1444 leftover
= poptGetArg(pc
);
1446 ERR("Unknown argument: %s", leftover
);
1451 if (!opt_session_name
) {
1452 session_name
= get_session_name();
1453 if (session_name
== NULL
) {
1454 command_ret
= CMD_ERROR
;
1459 session_name
= opt_session_name
;
1462 command_ret
= enable_events(session_name
);
1471 /* Close output element */
1472 ret
= mi_lttng_writer_close_element(writer
);
1478 ret
= mi_lttng_writer_write_element_bool(writer
,
1479 mi_lttng_element_command_success
, success
);
1485 /* Command element close */
1486 ret
= mi_lttng_writer_command_close(writer
);
1495 if (writer
&& mi_lttng_writer_destroy(writer
)) {
1496 /* Preserve original error code */
1497 ret
= ret
? ret
: LTTNG_ERR_MI_IO_FAIL
;
1500 if (opt_session_name
== NULL
) {
1504 /* Overwrite ret if an error occurred in enable_events */
1505 ret
= command_ret
? command_ret
: ret
;
1507 poptFreeContext(pc
);