2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
10 #include "../command.h"
12 #include "common/argpar/argpar.h"
13 #include "common/dynamic-array.h"
14 #include "common/mi-lttng.h"
15 /* For lttng_condition_type_str(). */
16 #include "lttng/condition/condition-internal.h"
17 #include "lttng/condition/on-event.h"
18 #include "lttng/condition/on-event-internal.h"
19 /* For lttng_domain_type_str(). */
20 #include "lttng/domain-internal.h"
21 #include "lttng/event-rule/event-rule-internal.h"
22 #include "lttng/event-rule/kernel-probe.h"
23 #include "lttng/event-rule/kernel-probe-internal.h"
24 #include "lttng/event-rule/syscall.h"
25 #include "lttng/event-rule/tracepoint.h"
26 #include "lttng/event-rule/userspace-probe.h"
27 #include "lttng/map-key.h"
28 #include "lttng/map-key-internal.h"
29 #include "lttng/trigger/trigger-internal.h"
30 #include "lttng/kernel-probe.h"
32 #ifdef LTTNG_EMBED_HELP
33 static const char help_msg
[] =
34 #include <lttng-list-triggers.1.h>
44 struct argpar_opt_descr list_trigger_options
[] = {
45 { OPT_HELP
, 'h', "help", false },
46 { OPT_LIST_OPTIONS
, '\0', "list-options", false },
47 ARGPAR_OPT_DESCR_SENTINEL
,
51 void print_event_rule_tracepoint(const struct lttng_event_rule
*event_rule
)
53 enum lttng_event_rule_status event_rule_status
;
54 enum lttng_domain_type domain_type
;
58 const struct lttng_log_level_rule
*log_level_rule
= NULL
;
59 unsigned int exclusions_count
;
62 event_rule_status
= lttng_event_rule_tracepoint_get_pattern(
63 event_rule
, &pattern
);
64 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
66 event_rule_status
= lttng_event_rule_tracepoint_get_domain_type(
67 event_rule
, &domain_type
);
68 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
70 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern
,
71 lttng_domain_type_str(domain_type
));
73 event_rule_status
= lttng_event_rule_tracepoint_get_filter(
75 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
76 _MSG(", filter: %s", filter
);
78 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
81 event_rule_status
= lttng_event_rule_tracepoint_get_log_level_rule(
82 event_rule
, &log_level_rule
);
83 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
84 enum lttng_log_level_rule_status llr_status
;
85 const char *log_level_op
;
87 switch (lttng_log_level_rule_get_type(log_level_rule
)) {
88 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
:
89 llr_status
= lttng_log_level_rule_exactly_get_level(
90 log_level_rule
, &log_level
);
93 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
:
95 llr_status
= lttng_log_level_rule_at_least_as_severe_as_get_level(
96 log_level_rule
, &log_level
);
102 assert(llr_status
== LTTNG_LOG_LEVEL_RULE_STATUS_OK
);
104 /* TODO: here the raw level value must be printed since the
105 * value could have no known string equivalent, the string
106 * representation is only a "convenience".
108 _MSG(", log level %s %s", log_level_op
,
109 mi_lttng_loglevel_string(
110 log_level
, domain_type
));
112 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
115 event_rule_status
= lttng_event_rule_tracepoint_get_exclusions_count(
116 event_rule
, &exclusions_count
);
117 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
118 if (exclusions_count
> 0) {
119 _MSG(", exclusions: ");
120 for (i
= 0; i
< exclusions_count
; i
++) {
121 const char *exclusion
;
123 event_rule_status
= lttng_event_rule_tracepoint_get_exclusion_at_index(
124 event_rule
, i
, &exclusion
);
125 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
127 _MSG("%s%s", i
> 0 ? "," : "", exclusion
);
134 static void print_kernel_probe_location(
135 const struct lttng_kernel_probe_location
*location
)
137 enum lttng_kernel_probe_location_status status
;
138 switch (lttng_kernel_probe_location_get_type(location
)) {
139 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS
:
143 status
= lttng_kernel_probe_location_address_get_address(
145 if (status
!= LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK
) {
146 ERR("Getting kernel probe location address failed.");
150 _MSG("0x%" PRIx64
, address
);
154 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET
:
157 const char *symbol_name
;
159 symbol_name
= lttng_kernel_probe_location_symbol_get_name(
162 ERR("Getting kernel probe location symbol name failed.");
166 status
= lttng_kernel_probe_location_symbol_get_offset(
168 if (status
!= LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK
) {
169 ERR("Getting kernel probe location address failed.");
174 _MSG("%s", symbol_name
);
176 _MSG("%s+0x%" PRIx64
, symbol_name
, offset
);
189 void print_event_rule_kernel_probe(const struct lttng_event_rule
*event_rule
)
191 enum lttng_event_rule_status event_rule_status
;
193 const struct lttng_kernel_probe_location
*location
;
195 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE
);
197 event_rule_status
= lttng_event_rule_kernel_probe_get_event_name(event_rule
, &name
);
198 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
199 ERR("Failed to get kprobe event rule's name.");
203 event_rule_status
= lttng_event_rule_kernel_probe_get_location(
204 event_rule
, &location
);
205 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
206 ERR("Failed to get kprobe event rule's location.");
210 _MSG(" rule: %s (type: probe, location: ", name
);
212 print_kernel_probe_location(location
);
221 void print_event_rule_userspace_probe(const struct lttng_event_rule
*event_rule
)
223 enum lttng_event_rule_status event_rule_status
;
225 const struct lttng_userspace_probe_location
*location
;
226 enum lttng_userspace_probe_location_type userspace_probe_location_type
;
228 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE
);
230 event_rule_status
= lttng_event_rule_userspace_probe_get_event_name(event_rule
, &name
);
231 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
232 ERR("Failed to get uprobe event rule's name.");
236 event_rule_status
= lttng_event_rule_userspace_probe_get_location(
237 event_rule
, &location
);
238 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
239 ERR("Failed to get uprobe event rule's location.");
243 _MSG(" rule: %s (type: userspace probe, location: ", name
);
245 userspace_probe_location_type
=
246 lttng_userspace_probe_location_get_type(location
);
248 switch (userspace_probe_location_type
) {
249 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
251 const char *binary_path
, *function_name
;
253 binary_path
= lttng_userspace_probe_location_function_get_binary_path(
255 function_name
= lttng_userspace_probe_location_function_get_function_name(
258 _MSG("%s:%s", binary_path
, function_name
);
261 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
262 _MSG("SDT not implemented yet");
275 void print_event_rule_syscall(const struct lttng_event_rule
*event_rule
)
277 const char *pattern
, *filter
;
278 enum lttng_event_rule_status event_rule_status
;
280 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_SYSCALL
);
282 event_rule_status
= lttng_event_rule_syscall_get_pattern(
283 event_rule
, &pattern
);
284 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
286 _MSG(" rule: %s (type: syscall", pattern
);
288 event_rule_status
= lttng_event_rule_syscall_get_filter(
289 event_rule
, &filter
);
290 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
291 _MSG(", filter: %s", filter
);
293 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
300 void print_event_rule(const struct lttng_event_rule
*event_rule
)
302 const enum lttng_event_rule_type event_rule_type
=
303 lttng_event_rule_get_type(event_rule
);
305 switch (event_rule_type
) {
306 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
307 print_event_rule_tracepoint(event_rule
);
309 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE
:
310 print_event_rule_kernel_probe(event_rule
);
312 case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE
:
313 print_event_rule_userspace_probe(event_rule
);
315 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
316 print_event_rule_syscall(event_rule
);
324 void print_one_event_expr(const struct lttng_event_expr
*event_expr
)
326 enum lttng_event_expr_type type
;
328 type
= lttng_event_expr_get_type(event_expr
);
331 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
: {
334 name
= lttng_event_expr_event_payload_field_get_name(event_expr
);
340 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
: {
343 name
= lttng_event_expr_channel_context_field_get_name(event_expr
);
344 _MSG("$ctx.%s", name
);
349 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
: {
350 const char *provider_name
;
351 const char *type_name
;
354 lttng_event_expr_app_specific_context_field_get_provider_name(
357 lttng_event_expr_app_specific_context_field_get_type_name(
360 _MSG("$app.%s:%s", provider_name
, type_name
);
365 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
: {
367 const struct lttng_event_expr
*parent_expr
;
368 enum lttng_event_expr_status status
;
370 parent_expr
= lttng_event_expr_array_field_element_get_parent_expr(
372 assert(parent_expr
!= NULL
);
374 print_one_event_expr(parent_expr
);
376 status
= lttng_event_expr_array_field_element_get_index(
378 assert(status
== LTTNG_EVENT_EXPR_STATUS_OK
);
391 void print_condition_on_event(const struct lttng_condition
*condition
)
393 const struct lttng_event_rule
*event_rule
;
394 enum lttng_condition_status condition_status
;
395 unsigned int cap_desc_count
, i
;
396 uint64_t error_count
;
399 lttng_condition_on_event_get_rule(condition
, &event_rule
);
400 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
402 print_event_rule(event_rule
);
405 = lttng_condition_on_event_get_capture_descriptor_count(
406 condition
, &cap_desc_count
);
407 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
409 error_count
= lttng_condition_on_event_get_error_count(condition
);
410 MSG(" tracer notifications discarded: %ld", error_count
);
412 if (cap_desc_count
> 0) {
415 for (i
= 0; i
< cap_desc_count
; i
++) {
416 const struct lttng_event_expr
*cap_desc
=
417 lttng_condition_on_event_get_capture_descriptor_at_index(
421 print_one_event_expr(cap_desc
);
428 void print_map_key(const struct lttng_map_key
*key
)
430 unsigned int i
, token_count
;
431 enum lttng_map_key_status key_status
;
434 key_status
= lttng_map_key_get_token_count(key
, &token_count
);
435 assert(key_status
== LTTNG_MAP_KEY_STATUS_OK
);
437 for (i
= 0; i
< token_count
; i
++) {
438 const struct lttng_map_key_token
*token
=
439 lttng_map_key_get_token_at_index(key
, i
);
442 switch (token
->type
) {
443 case LTTNG_MAP_KEY_TOKEN_TYPE_STRING
:
445 const struct lttng_map_key_token_string
*str_token
;
446 str_token
= (typeof(str_token
)) token
;
447 _MSG("%s", str_token
->string
);
450 case LTTNG_MAP_KEY_TOKEN_TYPE_VARIABLE
:
452 const struct lttng_map_key_token_variable
*var_token
;
453 var_token
= (typeof(var_token
)) token
;
455 switch (var_token
->type
) {
456 case LTTNG_MAP_KEY_TOKEN_VARIABLE_TYPE_EVENT_NAME
:
457 _MSG("${EVENT_NAME}");
459 case LTTNG_MAP_KEY_TOKEN_VARIABLE_TYPE_PROVIDER_NAME
:
460 _MSG("${PROVIDER_NAME}");
476 void print_one_incr_value_action(const struct lttng_action
*action
)
478 enum lttng_action_status action_status
;
479 const char *session_name
, *map_name
;
480 const struct lttng_map_key
*key
;
482 action_status
= lttng_action_incr_value_get_session_name(
483 action
, &session_name
);
484 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
486 action_status
= lttng_action_incr_value_get_map_name(
488 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
490 action_status
= lttng_action_incr_value_get_key(
492 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
494 MSG("increment value:");
495 MSG(" session: `%s`", session_name
);
496 MSG(" map: `%s`", map_name
);
501 void print_one_action(const struct lttng_action
*action
)
503 enum lttng_action_type action_type
;
504 enum lttng_action_status action_status
;
507 action_type
= lttng_action_get_type(action
);
508 assert(action_type
!= LTTNG_ACTION_TYPE_GROUP
);
510 switch (action_type
) {
511 case LTTNG_ACTION_TYPE_INCREMENT_VALUE
:
512 print_one_incr_value_action(action
);
514 case LTTNG_ACTION_TYPE_NOTIFY
:
517 case LTTNG_ACTION_TYPE_START_SESSION
:
518 action_status
= lttng_action_start_session_get_session_name(
520 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
521 MSG("start session `%s`", value
);
523 case LTTNG_ACTION_TYPE_STOP_SESSION
:
524 action_status
= lttng_action_stop_session_get_session_name(
526 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
527 MSG("stop session `%s`", value
);
529 case LTTNG_ACTION_TYPE_ROTATE_SESSION
:
530 action_status
= lttng_action_rotate_session_get_session_name(
532 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
533 MSG("rotate session `%s`", value
);
535 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
:
537 const struct lttng_snapshot_output
*output
;
539 action_status
= lttng_action_snapshot_session_get_session_name(
541 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
542 _MSG("snapshot session `%s`", value
);
544 action_status
= lttng_action_snapshot_session_get_output(
546 if (action_status
== LTTNG_ACTION_STATUS_OK
) {
549 const char *ctrl_url
, *data_url
;
550 bool starts_with_file
, starts_with_net
, starts_with_net6
;
552 ctrl_url
= lttng_snapshot_output_get_ctrl_url(output
);
553 assert(ctrl_url
&& strlen(ctrl_url
) > 0);
555 data_url
= lttng_snapshot_output_get_data_url(output
);
558 starts_with_file
= strncmp(ctrl_url
, "file://", strlen("file://")) == 0;
559 starts_with_net
= strncmp(ctrl_url
, "net://", strlen("net://")) == 0;
560 starts_with_net6
= strncmp(ctrl_url
, "net6://", strlen("net6://")) == 0;
562 if (ctrl_url
[0] == '/' || starts_with_file
) {
563 if (starts_with_file
) {
564 ctrl_url
+= strlen("file://");
567 _MSG(", path: %s", ctrl_url
);
568 } else if (starts_with_net
|| starts_with_net6
) {
569 _MSG(", url: %s", ctrl_url
);
571 assert(strlen(data_url
) > 0);
573 _MSG(", control url: %s, data url: %s", ctrl_url
, data_url
);
576 name
= lttng_snapshot_output_get_name(output
);
578 if (strlen(name
) > 0) {
579 _MSG(", name: %s", name
);
582 max_size
= lttng_snapshot_output_get_maxsize(output
);
583 if (max_size
!= -1ULL) {
584 _MSG(", max size: %" PRIu64
, max_size
);
598 void print_one_trigger(const struct lttng_trigger
*trigger
)
600 const struct lttng_condition
*condition
;
601 enum lttng_condition_type condition_type
;
602 const struct lttng_action
*action
;
603 enum lttng_action_type action_type
;
604 enum lttng_trigger_status trigger_status
;
606 enum lttng_trigger_firing_policy firing_policy_type
;
610 trigger_status
= lttng_trigger_get_name(trigger
, &name
);
611 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
613 trigger_status
= lttng_trigger_get_owner_uid(trigger
, &trigger_uid
);
614 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
616 MSG("- id: %s", name
);
617 MSG(" user id: %d", trigger_uid
);
619 trigger_status
= lttng_trigger_get_firing_policy(
620 trigger
, &firing_policy_type
, &threshold
);
621 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
622 ERR("Failed to get trigger's policy.");
626 switch (firing_policy_type
) {
627 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N
:
629 MSG(" firing policy: after every %" PRIu64
" occurences", threshold
);
632 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N
:
633 MSG(" firing policy: once after %" PRIu64
" occurences", threshold
);
639 condition
= lttng_trigger_get_const_condition(trigger
);
640 condition_type
= lttng_condition_get_type(condition
);
641 MSG(" condition: %s", lttng_condition_type_str(condition_type
));
642 switch (condition_type
) {
643 case LTTNG_CONDITION_TYPE_ON_EVENT
:
644 print_condition_on_event(condition
);
647 MSG(" (condition type not handled in %s)", __func__
);
651 action
= lttng_trigger_get_const_action(trigger
);
652 action_type
= lttng_action_get_type(action
);
653 if (action_type
== LTTNG_ACTION_TYPE_GROUP
) {
654 unsigned int count
, i
;
655 enum lttng_action_status action_status
;
659 action_status
= lttng_action_group_get_count(action
, &count
);
660 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
662 for (i
= 0; i
< count
; i
++) {
663 const struct lttng_action
*subaction
=
664 lttng_action_group_get_at_index(
668 print_one_action(subaction
);
672 print_one_action(action
);
680 int compare_triggers_by_name(const void *a
, const void *b
)
682 const struct lttng_trigger
*trigger_a
= *((const struct lttng_trigger
**) a
);
683 const struct lttng_trigger
*trigger_b
= *((const struct lttng_trigger
**) b
);
684 const char *name_a
, *name_b
;
685 enum lttng_trigger_status trigger_status
;
687 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
688 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
690 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
691 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
693 return strcmp(name_a
, name_b
);
696 int cmd_list_triggers(int argc
, const char **argv
)
699 struct argpar_parse_ret argpar_parse_ret
= {};
700 struct lttng_triggers
*triggers
= NULL
;
702 struct lttng_dynamic_pointer_array sorted_triggers
;
703 enum lttng_trigger_status trigger_status
;
704 unsigned int num_triggers
;
706 lttng_dynamic_pointer_array_init(&sorted_triggers
, NULL
);
708 argpar_parse_ret
= argpar_parse(
709 argc
- 1, argv
+ 1, list_trigger_options
, true);
710 if (!argpar_parse_ret
.items
) {
711 ERR("%s", argpar_parse_ret
.error
);
715 for (i
= 0; i
< argpar_parse_ret
.items
->n_items
; i
++) {
716 const struct argpar_item
*item
=
717 argpar_parse_ret
.items
->items
[i
];
719 if (item
->type
== ARGPAR_ITEM_TYPE_OPT
) {
720 const struct argpar_item_opt
*item_opt
=
721 (const struct argpar_item_opt
*) item
;
723 switch (item_opt
->descr
->id
) {
729 case OPT_LIST_OPTIONS
:
730 list_cmd_options_argpar(stdout
,
731 list_trigger_options
);
740 const struct argpar_item_non_opt
*item_non_opt
=
741 (const struct argpar_item_non_opt
*) item
;
743 ERR("Unexpected argument: %s", item_non_opt
->arg
);
747 ret
= lttng_list_triggers(&triggers
);
748 if (ret
!= LTTNG_OK
) {
749 ERR("Error listing triggers: %s.", lttng_strerror(-ret
));
753 trigger_status
= lttng_triggers_get_count(triggers
, &num_triggers
);
754 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
755 ERR("Failed to get trigger count.");
759 for (i
= 0; i
< num_triggers
; i
++) {
760 const int add_ret
= lttng_dynamic_pointer_array_add_pointer(
762 (void *) lttng_triggers_get_at_index(triggers
, i
));
765 ERR("Failed to allocate array of struct lttng_trigger *.");
770 qsort(sorted_triggers
.array
.buffer
.data
, num_triggers
,
771 sizeof(struct lttng_trigger
*),
772 compare_triggers_by_name
);
774 for (i
= 0; i
< num_triggers
; i
++) {
775 const struct lttng_trigger
*trigger_to_print
=
776 (const struct lttng_trigger
*)
777 lttng_dynamic_pointer_array_get_pointer(
778 &sorted_triggers
, i
);
780 print_one_trigger(trigger_to_print
);
790 argpar_parse_ret_fini(&argpar_parse_ret
);
791 lttng_triggers_destroy(triggers
);
792 lttng_dynamic_pointer_array_reset(&sorted_triggers
);