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 printf(" 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 printf(", 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 printf(", 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 printf(", 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 printf("%s%s", i
> 0 ? "," : "", exclusion
);
107 void print_event_rule_kprobe(const struct lttng_event_rule
*event_rule
)
109 enum lttng_event_rule_status event_rule_status
;
110 const char *name
, *symbol_name
;
113 event_rule_status
= lttng_event_rule_kprobe_get_name(event_rule
, &name
);
114 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
115 fprintf(stderr
, "Failed to get kprobe event rule's name.\n");
119 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_KPROBE
);
121 printf(" rule: %s (type: probe, location: ", name
);
123 // FIXME: When the location has been specified by address, this field
124 // contains the address as a string. The only downside is that we are
125 // missing a `0x` prefix.
126 symbol_name
= lttng_event_rule_kprobe_get_symbol_name(event_rule
);
127 printf("%s", symbol_name
);
129 offset
= lttng_event_rule_kprobe_get_offset(event_rule
);
131 printf("+0x%" PRIx64
, offset
);
141 void print_event_rule_uprobe(const struct lttng_event_rule
*event_rule
)
143 enum lttng_event_rule_status event_rule_status
;
145 const struct lttng_userspace_probe_location
*location
;
146 enum lttng_userspace_probe_location_type userspace_probe_location_type
;
148 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_UPROBE
);
150 event_rule_status
= lttng_event_rule_uprobe_get_name(event_rule
, &name
);
151 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
152 fprintf(stderr
, "Failed to get uprobe event rule's name.\n");
156 event_rule_status
= lttng_event_rule_uprobe_get_location(event_rule
, &location
);
157 if (event_rule_status
!= LTTNG_EVENT_RULE_STATUS_OK
) {
158 fprintf(stderr
, "Failed to get uprobe event rule's location.\n");
162 printf(" rule: %s (type: userspace probe, location: ", name
);
164 userspace_probe_location_type
=
165 lttng_userspace_probe_location_get_type(location
);
167 switch (userspace_probe_location_type
) {
168 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
:
170 const char *binary_path
, *function_name
;
172 binary_path
= lttng_userspace_probe_location_function_get_binary_path(location
);
173 function_name
= lttng_userspace_probe_location_function_get_function_name(location
);
175 printf("%s:%s", binary_path
, function_name
);
179 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
:
180 printf("SDT not implemented yet");
194 void print_event_rule_syscall(const struct lttng_event_rule
*event_rule
)
196 const char *pattern
, *filter
;
197 enum lttng_event_rule_status event_rule_status
;
199 assert(lttng_event_rule_get_type(event_rule
) == LTTNG_EVENT_RULE_TYPE_SYSCALL
);
201 event_rule_status
= lttng_event_rule_syscall_get_pattern(event_rule
, &pattern
);
202 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
);
204 printf(" - rule: %s (type: syscall", pattern
);
206 event_rule_status
= lttng_event_rule_syscall_get_filter(
207 event_rule
, &filter
);
208 if (event_rule_status
== LTTNG_EVENT_RULE_STATUS_OK
) {
209 printf(", filter: %s", filter
);
211 assert(event_rule_status
== LTTNG_EVENT_RULE_STATUS_UNSET
);
218 void print_event_rule(const struct lttng_event_rule
*event_rule
)
220 enum lttng_event_rule_type event_rule_type
=
221 lttng_event_rule_get_type(event_rule
);
223 switch (event_rule_type
) {
224 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT
:
225 print_event_rule_tracepoint(event_rule
);
228 case LTTNG_EVENT_RULE_TYPE_KPROBE
:
229 print_event_rule_kprobe(event_rule
);
232 case LTTNG_EVENT_RULE_TYPE_UPROBE
:
233 print_event_rule_uprobe(event_rule
);
236 case LTTNG_EVENT_RULE_TYPE_SYSCALL
:
237 print_event_rule_syscall(event_rule
);
246 void print_condition_event_rule_hit(const struct lttng_condition
*condition
)
248 const struct lttng_event_rule
*event_rule
;
249 enum lttng_condition_status condition_status
;
252 lttng_condition_event_rule_get_rule(condition
, &event_rule
);
253 assert(condition_status
== LTTNG_CONDITION_STATUS_OK
);
255 print_event_rule(event_rule
);
259 void print_one_action(const struct lttng_action
*action
)
261 enum lttng_action_type action_type
;
262 enum lttng_action_status action_status
;
265 action_type
= lttng_action_get_type(action
);
266 assert(action_type
!= LTTNG_ACTION_TYPE_GROUP
);
268 switch (action_type
) {
269 case LTTNG_ACTION_TYPE_NOTIFY
:
273 case LTTNG_ACTION_TYPE_START_SESSION
:
274 action_status
= lttng_action_start_session_get_session_name(
276 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
277 printf("start session `%s`\n", value
);
280 case LTTNG_ACTION_TYPE_STOP_SESSION
:
281 action_status
= lttng_action_stop_session_get_session_name(
283 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
284 printf("stop session `%s`\n", value
);
287 case LTTNG_ACTION_TYPE_ROTATE_SESSION
:
288 action_status
= lttng_action_rotate_session_get_session_name(
290 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
291 printf("rotate session `%s`\n", value
);
294 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
:
296 const struct lttng_snapshot_output
*output
;
298 action_status
= lttng_action_snapshot_session_get_session_name(
300 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
301 printf("snapshot session `%s`", value
);
303 action_status
= lttng_action_snapshot_session_get_output_const(
305 if (action_status
== LTTNG_ACTION_STATUS_OK
) {
308 const char *ctrl_url
, *data_url
;
309 bool starts_with_file
, starts_with_net
, starts_with_net6
;
311 ctrl_url
= lttng_snapshot_output_get_ctrl_url(output
);
312 assert(ctrl_url
&& strlen(ctrl_url
) > 0);
314 data_url
= lttng_snapshot_output_get_data_url(output
);
317 starts_with_file
= strncmp(ctrl_url
, "file://", strlen("file://")) == 0;
318 starts_with_net
= strncmp(ctrl_url
, "net://", strlen("net://")) == 0;
319 starts_with_net6
= strncmp(ctrl_url
, "net6://", strlen("net6://")) == 0;
321 if (ctrl_url
[0] == '/' || starts_with_file
) {
322 if (starts_with_file
) {
323 ctrl_url
+= strlen("file://");
326 printf(", path: %s", ctrl_url
);
327 } else if (starts_with_net
|| starts_with_net6
) {
328 printf(", url: %s", ctrl_url
);
330 assert(strlen(data_url
) > 0);
332 printf(", control url: %s, data url: %s", ctrl_url
, data_url
);
335 name
= lttng_snapshot_output_get_name(output
);
337 if (strlen(name
) > 0) {
338 printf(", name: %s", name
);
341 max_size
= lttng_snapshot_output_get_maxsize(output
);
342 if (max_size
!= -1ULL) {
343 printf(", max size: %" PRIu64
, max_size
);
357 void print_one_trigger(const struct lttng_trigger
*trigger
)
359 const struct lttng_condition
*condition
;
360 enum lttng_condition_type condition_type
;
361 const struct lttng_action
*action
;
362 enum lttng_action_type action_type
;
363 enum lttng_trigger_status trigger_status
;
365 enum lttng_trigger_firing_policy_type policy_type
;
366 unsigned long long threshold
;
368 trigger_status
= lttng_trigger_get_name(trigger
, &name
);
369 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
370 printf("- id: %s\n", name
);
372 trigger_status
= lttng_trigger_get_firing_policy(trigger
,
373 &policy_type
, &threshold
);
374 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
375 fprintf(stderr
, "Failed to get trigger's firing policy.\n");
379 switch (policy_type
) {
380 case LTTNG_TRIGGER_FIRE_EVERY_N
:
382 printf(" firing policy: after every %llu occurences\n", threshold
);
386 case LTTNG_TRIGGER_FIRE_ONCE_AFTER_N
:
387 printf(" firing policy: once after %llu occurences\n", threshold
);
394 condition
= lttng_trigger_get_const_condition(trigger
);
395 condition_type
= lttng_condition_get_type(condition
);
396 printf(" condition: %s\n",
397 lttng_condition_type_str(condition_type
));
399 switch (condition_type
) {
400 case LTTNG_CONDITION_TYPE_EVENT_RULE_HIT
:
401 print_condition_event_rule_hit(condition
);
405 printf(" (condition type not handled in %s)\n", __func__
);
409 action
= lttng_trigger_get_const_action(trigger
);
410 action_type
= lttng_action_get_type(action
);
411 if (action_type
== LTTNG_ACTION_TYPE_GROUP
) {
412 enum lttng_action_status action_status
;
413 unsigned int count
, i
;
415 printf(" actions:\n");
417 action_status
= lttng_action_group_get_count(action
, &count
);
418 assert(action_status
== LTTNG_ACTION_STATUS_OK
);
420 for (i
= 0; i
< count
; i
++) {
421 const struct lttng_action
*subaction
=
422 lttng_action_group_get_at_index_const(action
, i
);
425 print_one_action(subaction
);
429 print_one_action(action
);
437 int compare_triggers_by_name(const void *a
, const void *b
)
439 const struct lttng_trigger
*trigger_a
= *((const struct lttng_trigger
**) a
);
440 const struct lttng_trigger
*trigger_b
= *((const struct lttng_trigger
**) b
);
441 const char *name_a
, *name_b
;
442 enum lttng_trigger_status trigger_status
;
444 trigger_status
= lttng_trigger_get_name(trigger_a
, &name_a
);
445 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
447 trigger_status
= lttng_trigger_get_name(trigger_b
, &name_b
);
448 assert(trigger_status
== LTTNG_TRIGGER_STATUS_OK
);
450 return strcmp(name_a
, name_b
);
453 int cmd_list_triggers(int argc
, const char **argv
)
456 struct argpar_parse_ret argpar_parse_ret
= { 0 };
457 struct lttng_triggers
*triggers
= NULL
;
459 const struct lttng_trigger
**sorted_triggers
= NULL
;
460 enum lttng_trigger_status trigger_status
;
461 unsigned int num_triggers
;
463 argpar_parse_ret
= argpar_parse(argc
- 1, argv
+ 1,
464 list_trigger_options
, true);
465 if (!argpar_parse_ret
.items
) {
466 fprintf(stderr
, "Error: %s\n", argpar_parse_ret
.error
);
470 for (i
= 0; i
< argpar_parse_ret
.items
->n_items
; i
++) {
471 struct argpar_item
*item
= argpar_parse_ret
.items
->items
[i
];
473 if (item
->type
== ARGPAR_ITEM_TYPE_OPT
) {
474 struct argpar_item_opt
*item_opt
=
475 (struct argpar_item_opt
*) item
;
477 switch (item_opt
->descr
->id
) {
483 case OPT_LIST_OPTIONS
:
484 list_cmd_options_argpar(stdout
,
485 list_trigger_options
);
494 struct argpar_item_non_opt
*item_non_opt
=
495 (struct argpar_item_non_opt
*) item
;
497 fprintf(stderr
, "Unexpected argument: %s\n", item_non_opt
->arg
);
501 ret
= lttng_list_triggers(&triggers
);
503 fprintf(stderr
, "Error listing triggers: %s.\n",
504 lttng_strerror(ret
));
508 trigger_status
= lttng_triggers_get_count(triggers
, &num_triggers
);
509 if (trigger_status
!= LTTNG_TRIGGER_STATUS_OK
) {
510 fprintf(stderr
, "Failed to get trigger count.\n");
514 sorted_triggers
= calloc(num_triggers
, sizeof(struct lttng_trigger
*));
515 if (!sorted_triggers
) {
516 fprintf(stderr
, "Failed to allocate array of struct lttng_trigger *.\n");
520 for (i
= 0; i
< num_triggers
; i
++) {
521 sorted_triggers
[i
] = lttng_triggers_get_at_index(triggers
, i
);
524 qsort(sorted_triggers
, num_triggers
, sizeof(struct lttng_trigger
*),
525 compare_triggers_by_name
);
527 for (i
= 0; i
< num_triggers
; i
++) {
528 print_one_trigger(sorted_triggers
[i
]);
537 argpar_parse_ret_fini(&argpar_parse_ret
);
538 lttng_triggers_destroy(triggers
);