3 #include "../command.h"
5 #include "common/argpar/argpar.h"
6 #include "common/mi-lttng.h"
7 #include "lttng/condition/condition-internal.h"
8 #include "lttng/condition/event-rule.h"
9 #include "lttng/domain-internal.h"
10 #include "lttng/event-rule/event-rule-internal.h"
11 #include "lttng/event-rule/kprobe.h"
12 #include "lttng/event-rule/kprobe-internal.h"
13 #include "lttng/event-rule/syscall.h"
14 #include "lttng/event-rule/tracepoint.h"
15 #include "lttng/event-rule/uprobe.h"
16 #include "lttng/trigger/trigger-internal.h"
18 #ifdef LTTNG_EMBED_HELP
19 static const char help_msg
[] =
20 #include <lttng-list-trigger.1.h>
30 struct argpar_opt_descr list_trigger_options
[] = {
31 { OPT_HELP
, 'h', "help", false },
32 { OPT_LIST_OPTIONS
, '\0', "list-options", false },
33 ARGPAR_OPT_DESCR_SENTINEL
,
37 void print_event_rule_tracepoint(const struct lttng_event_rule
*event_rule
)
39 enum lttng_event_rule_status event_rule_status
;
40 enum lttng_domain_type domain_type
;
44 unsigned int exclusions_count
;
47 event_rule_status
= lttng_event_rule_tracepoint_get_pattern(
48 event_rule
, &pattern
);
49 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
51 event_rule_status
= lttng_event_rule_tracepoint_get_domain_type(
52 event_rule
, &domain_type
);
53 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
55 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern
,
56 lttng_domain_type_str(domain_type
));
58 event_rule_status
= lttng_event_rule_tracepoint_get_filter(
60 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
61 _MSG(", filter: %s", filter
);
63 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
66 event_rule_status
= lttng_event_rule_tracepoint_get_loglevel(
67 event_rule
, &loglevel
);
68 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
69 enum lttng_loglevel_type loglevel_type
;
70 const char *loglevel_op
;
72 event_rule_status
= lttng_event_rule_tracepoint_get_loglevel_type(
73 event_rule
, &loglevel_type
);
74 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
75 assert(loglevel_type
== LTTNG_EVENT_LOGLEVEL_RANGE
||
76 loglevel_type
== LTTNG_EVENT_LOGLEVEL_SINGLE
);
78 loglevel_op
= (loglevel_type
== LTTNG_EVENT_LOGLEVEL_RANGE
? "<=" : "==");
80 _MSG(", log level %s %s", loglevel_op
,
81 mi_lttng_loglevel_string(loglevel
, domain_type
));
83 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
86 event_rule_status
= lttng_event_rule_tracepoint_get_exclusions_count(
87 event_rule
, &exclusions_count
);
88 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
89 if (exclusions_count
> 0) {
90 _MSG(", exclusions: ");
91 for (i
= 0; i
< exclusions_count
; i
++) {
92 const char *exclusion
;
94 event_rule_status
= lttng_event_rule_tracepoint_get_exclusion_at_index(
95 event_rule
, i
, &exclusion
);
96 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
98 _MSG("%s%s", i
> 0 ? "," : "", exclusion
);
106 void print_event_rule_kprobe(const struct lttng_event_rule
*event_rule
)
108 enum lttng_event_rule_status event_rule_status
;
109 const char *name
, *symbol_name
;
112 event_rule_status
= lttng_event_rule_kprobe_get_name(event_rule
, &name
);
113 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
114 ERR("Failed to get kprobe event rule's name.");
118 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_KPROBE
);
120 _MSG(" rule: %s (type: probe, location: ", name
);
122 // FIXME: When the location has been specified by address, this field
123 // contains the address as a string. The only downside is that we are
124 // missing a `0x` prefix.
125 symbol_name
= lttng_event_rule_kprobe_get_symbol_name(event_rule
);
126 _MSG("%s", symbol_name
);
128 offset
= lttng_event_rule_kprobe_get_offset(event_rule
);
130 _MSG("+0x%" PRIx64
, offset
);
140 void print_event_rule_uprobe(const struct lttng_event_rule
*event_rule
)
142 enum lttng_event_rule_status event_rule_status
;
144 const struct lttng_userspace_probe_location
*location
;
145 enum lttng_userspace_probe_location_type userspace_probe_location_type
;
147 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_UPROBE
);
149 event_rule_status
= lttng_event_rule_uprobe_get_name(event_rule
, &name
);
150 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
151 ERR("Failed to get uprobe event rule's name.");
155 event_rule_status
= lttng_event_rule_uprobe_get_location(event_rule
, &location
);
156 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
157 ERR("Failed to get uprobe event rule's location.");
161 _MSG(" rule: %s (type: userspace probe, location: ", name
);
163 userspace_probe_location_type
=
164 lttng_userspace_probe_location_get_type(location
);
166 switch (userspace_probe_location_type
) {
167 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
169 const char *binary_path
, *function_name
;
171 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
172 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
174 _MSG("%s:%s", binary_path
, function_name
);
178 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
179 _MSG("SDT not implemented yet");
193 void print_event_rule_syscall(const struct lttng_event_rule
*event_rule
)
195 const char *pattern
, *filter
;
196 enum lttng_event_rule_status event_rule_status
;
198 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_SYSCALL
);
200 event_rule_status
= lttng_event_rule_syscall_get_pattern(event_rule
, &pattern
);
201 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
203 _MSG(" - rule: %s (type: syscall", pattern
);
205 event_rule_status
= lttng_event_rule_syscall_get_filter(
206 event_rule
, &filter
);
207 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
208 _MSG(", filter: %s", filter
);
210 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
217 void print_event_rule(const struct lttng_event_rule
*event_rule
)
219 enum lttng_event_rule_type event_rule_type
=
220 lttng_event_rule_get_type(event_rule
);
222 switch (event_rule_type
) {
223 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
224 print_event_rule_tracepoint(event_rule
);
227 case LTTNG_EVENT_RULE_TYPE_KPROBE
:
228 print_event_rule_kprobe(event_rule
);
231 case LTTNG_EVENT_RULE_TYPE_UPROBE
:
232 print_event_rule_uprobe(event_rule
);
235 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
236 print_event_rule_syscall(event_rule
);
245 void print_one_event_expr(const struct lttng_event_expr
*event_expr
)
247 enum lttng_event_expr_type type
;
249 type
= lttng_event_expr_get_type(event_expr
);
252 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
: {
255 name
= lttng_event_expr_event_payload_field_get_name(event_expr
);
261 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
: {
264 name
= lttng_event_expr_channel_context_field_get_name(event_expr
);
265 _MSG("$ctx.%s", name
);
270 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
: {
271 const char *provider_name
;
272 const char *type_name
;
275 lttng_event_expr_app_specific_context_field_get_provider_name(
278 lttng_event_expr_app_specific_context_field_get_type_name(
281 _MSG("$app.%s:%s", provider_name
, type_name
);
286 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
: {
288 const struct lttng_event_expr
*parent_expr
;
289 enum lttng_event_expr_status status
;
291 parent_expr
= lttng_event_expr_array_field_element_get_parent_expr(
293 assert(parent_expr
!= NULL
);
295 print_one_event_expr(parent_expr
);
297 status
= lttng_event_expr_array_field_element_get_index(
299 assert(status
== LTTNG_EVENT_EXPR_STATUS_OK
);
312 void print_condition_event_rule_hit(const struct lttng_condition
*condition
)
314 const struct lttng_event_rule
*event_rule
;
315 enum lttng_condition_status condition_status
;
316 unsigned int cap_desc_count
, i
;
319 lttng_condition_event_rule_get_rule(condition
, &event_rule
);
320 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
322 print_event_rule(event_rule
);
325 = lttng_condition_event_rule_get_capture_descriptor_count(
326 condition
, &cap_desc_count
);
327 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
329 if (cap_desc_count
> 0) {
332 for (i
= 0; i
< cap_desc_count
; i
++) {
333 const struct lttng_event_expr
*cap_desc
=
334 lttng_condition_event_rule_get_capture_descriptor_at_index(
338 print_one_event_expr(cap_desc
);
345 void print_one_action(const struct lttng_action
*action
)
347 enum lttng_action_type action_type
;
348 enum lttng_action_status action_status
;
351 action_type
= lttng_action_get_type(action
);
352 assert(action_type
!= LTTNG_ACTION_TYPE_GROUP
);
354 switch (action_type
) {
355 case LTTNG_ACTION_TYPE_NOTIFY
:
359 case LTTNG_ACTION_TYPE_START_SESSION
:
360 action_status
= lttng_action_start_session_get_session_name(
362 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
363 MSG("start session `%s`", value
);
366 case LTTNG_ACTION_TYPE_STOP_SESSION
:
367 action_status
= lttng_action_stop_session_get_session_name(
369 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
370 MSG("stop session `%s`", value
);
373 case LTTNG_ACTION_TYPE_ROTATE_SESSION
:
374 action_status
= lttng_action_rotate_session_get_session_name(
376 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
377 MSG("rotate session `%s`", value
);
380 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
:
382 const struct lttng_snapshot_output
*output
;
384 action_status
= lttng_action_snapshot_session_get_session_name(
386 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
387 _MSG("snapshot session `%s`", value
);
389 action_status
= lttng_action_snapshot_session_get_output_const(
391 if (action_status
== LTTNG_ACTION_STATUS_OK
) {
394 const char *ctrl_url
, *data_url
;
395 bool starts_with_file
, starts_with_net
, starts_with_net6
;
397 ctrl_url
= lttng_snapshot_output_get_ctrl_url(output
);
398 assert(ctrl_url
&& strlen(ctrl_url
) > 0);
400 data_url
= lttng_snapshot_output_get_data_url(output
);
403 starts_with_file
= strncmp(ctrl_url
, "file://", strlen("file://")) == 0;
404 starts_with_net
= strncmp(ctrl_url
, "net://", strlen("net://")) == 0;
405 starts_with_net6
= strncmp(ctrl_url
, "net6://", strlen("net6://")) == 0;
407 if (ctrl_url
[0] == '/' || starts_with_file
) {
408 if (starts_with_file
) {
409 ctrl_url
+= strlen("file://");
412 _MSG(", path: %s", ctrl_url
);
413 } else if (starts_with_net
|| starts_with_net6
) {
414 _MSG(", url: %s", ctrl_url
);
416 assert(strlen(data_url
) > 0);
418 _MSG(", control url: %s, data url: %s", ctrl_url
, data_url
);
421 name
= lttng_snapshot_output_get_name(output
);
423 if (strlen(name
) > 0) {
424 _MSG(", name: %s", name
);
427 max_size
= lttng_snapshot_output_get_maxsize(output
);
428 if (max_size
!= -1ULL) {
429 _MSG(", max size: %" PRIu64
, max_size
);
443 void print_one_trigger(const struct lttng_trigger
*trigger
)
445 const struct lttng_condition
*condition
;
446 enum lttng_condition_type condition_type
;
447 const struct lttng_action
*action
;
448 enum lttng_action_type action_type
;
449 enum lttng_trigger_status trigger_status
;
451 enum lttng_trigger_firing_policy_type policy_type
;
452 unsigned long long threshold
;
454 trigger_status
= lttng_trigger_get_name(trigger
, &name
);
455 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
456 MSG("- id: %s", name
);
458 trigger_status
= lttng_trigger_get_firing_policy(trigger
,
459 &policy_type
, &threshold
);
460 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
461 ERR("Failed to get trigger's firing policy.");
465 switch (policy_type
) {
466 case LTTNG_TRIGGER_FIRE_EVERY_N
:
468 MSG(" firing policy: after every %llu occurences", threshold
);
472 case LTTNG_TRIGGER_FIRE_ONCE_AFTER_N
:
473 MSG(" firing policy: once after %llu occurences", threshold
);
480 condition
= lttng_trigger_get_const_condition(trigger
);
481 condition_type
= lttng_condition_get_type(condition
);
482 MSG(" condition: %s",
483 lttng_condition_type_str(condition_type
));
485 switch (condition_type
) {
486 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
487 print_condition_event_rule_hit(condition
);
491 MSG(" (condition type not handled in %s)", __func__
);
495 action
= lttng_trigger_get_const_action(trigger
);
496 action_type
= lttng_action_get_type(action
);
497 if (action_type
== LTTNG_ACTION_TYPE_GROUP
) {
498 enum lttng_action_status action_status
;
499 unsigned int count
, i
;
503 action_status
= lttng_action_group_get_count(action
, &count
);
504 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
506 for (i
= 0; i
< count
; i
++) {
507 const struct lttng_action
*subaction
=
508 lttng_action_group_get_at_index_const(action
, i
);
511 print_one_action(subaction
);
515 print_one_action(action
);
523 int compare_triggers_by_name(const void *a
, const void *b
)
525 const struct lttng_trigger
*trigger_a
= *((const struct lttng_trigger
**) a
);
526 const struct lttng_trigger
*trigger_b
= *((const struct lttng_trigger
**) b
);
527 const char *name_a
, *name_b
;
528 enum lttng_trigger_status trigger_status
;
530 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
531 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
533 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
534 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
536 return strcmp(name_a
, name_b
);
539 int cmd_list_triggers(int argc
, const char **argv
)
542 struct argpar_parse_ret argpar_parse_ret
= { 0 };
543 struct lttng_triggers
*triggers
= NULL
;
545 const struct lttng_trigger
**sorted_triggers
= NULL
;
546 enum lttng_trigger_status trigger_status
;
547 unsigned int num_triggers
;
549 argpar_parse_ret
= argpar_parse(argc
- 1, argv
+ 1,
550 list_trigger_options
, true);
551 if (!argpar_parse_ret
.items
) {
552 ERR("%s", argpar_parse_ret
.error
);
556 for (i
= 0; i
< argpar_parse_ret
.items
->n_items
; i
++) {
557 struct argpar_item
*item
= argpar_parse_ret
.items
->items
[i
];
559 if (item
->type
== ARGPAR_ITEM_TYPE_OPT
) {
560 struct argpar_item_opt
*item_opt
=
561 (struct argpar_item_opt
*) item
;
563 switch (item_opt
->descr
->id
) {
569 case OPT_LIST_OPTIONS
:
570 list_cmd_options_argpar(stdout
,
571 list_trigger_options
);
580 struct argpar_item_non_opt
*item_non_opt
=
581 (struct argpar_item_non_opt
*) item
;
583 ERR("Unexpected argument: %s", item_non_opt
->arg
);
587 ret
= lttng_list_triggers(&triggers
);
589 ERR("Error listing triggers: %s.",
590 lttng_strerror(ret
));
594 trigger_status
= lttng_triggers_get_count(triggers
, &num_triggers
);
595 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
596 ERR("Failed to get trigger count.");
600 sorted_triggers
= calloc(num_triggers
, sizeof(struct lttng_trigger
*));
601 if (!sorted_triggers
) {
602 ERR("Failed to allocate array of struct lttng_trigger *.");
606 for (i
= 0; i
< num_triggers
; i
++) {
607 sorted_triggers
[i
] = lttng_triggers_get_at_index(triggers
, i
);
610 qsort(sorted_triggers
, num_triggers
, sizeof(struct lttng_trigger
*),
611 compare_triggers_by_name
);
613 for (i
= 0; i
< num_triggers
; i
++) {
614 print_one_trigger(sorted_triggers
[i
]);
623 argpar_parse_ret_fini(&argpar_parse_ret
);
624 lttng_triggers_destroy(triggers
);