lttng-ctl: Introduce lttng_log_level_rule
[lttng-tools.git] / src / bin / lttng / commands / list_triggers.c
1 /*
2 * Copyright (C) 2021 Simon Marchi <simon.marchi@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #include <stdio.h>
9
10 #include "../command.h"
11
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 /* For lttng_domain_type_str(). */
18 #include "lttng/domain-internal.h"
19 #include "../loglevel.h"
20
21 #ifdef LTTNG_EMBED_HELP
22 static const char help_msg[] =
23 #include <lttng-list-triggers.1.h>
24 ;
25 #endif
26
27 enum {
28 OPT_HELP,
29 OPT_LIST_OPTIONS,
30 };
31
32 static const
33 struct argpar_opt_descr list_trigger_options[] = {
34 { OPT_HELP, 'h', "help", false },
35 { OPT_LIST_OPTIONS, '\0', "list-options", false },
36 ARGPAR_OPT_DESCR_SENTINEL,
37 };
38
39 /*
40 * Returns the human-readable log level name associated with a numerical value
41 * if there is one. The Log4j and JUL domains have discontinuous log level
42 * values (a value can fall between two labels). In those cases, NULL is
43 * returned.
44 */
45 static const char *get_pretty_loglevel_name(
46 enum lttng_domain_type domain, int loglevel)
47 {
48 const char *name = NULL;
49
50 switch (domain) {
51 case LTTNG_DOMAIN_UST:
52 name = loglevel_value_to_name(loglevel);
53 break;
54 case LTTNG_DOMAIN_LOG4J:
55 name = loglevel_log4j_value_to_name(loglevel);
56 break;
57 case LTTNG_DOMAIN_JUL:
58 name = loglevel_jul_value_to_name(loglevel);
59 break;
60 case LTTNG_DOMAIN_PYTHON:
61 name = loglevel_python_value_to_name(loglevel);
62 break;
63 default:
64 break;
65 }
66
67 return name;
68 }
69
70 static
71 void print_event_rule_tracepoint(const struct lttng_event_rule *event_rule)
72 {
73 enum lttng_event_rule_status event_rule_status;
74 enum lttng_domain_type domain_type;
75 const char *pattern;
76 const char *filter;
77 int log_level;
78 const struct lttng_log_level_rule *log_level_rule = NULL;
79 unsigned int exclusions_count;
80 int i;
81
82 event_rule_status = lttng_event_rule_tracepoint_get_pattern(
83 event_rule, &pattern);
84 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
85
86 event_rule_status = lttng_event_rule_tracepoint_get_domain_type(
87 event_rule, &domain_type);
88 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
89
90 _MSG(" rule: %s (type: tracepoint, domain: %s", pattern,
91 lttng_domain_type_str(domain_type));
92
93 event_rule_status = lttng_event_rule_tracepoint_get_filter(
94 event_rule, &filter);
95 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
96 _MSG(", filter: %s", filter);
97 } else {
98 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
99 }
100
101 event_rule_status = lttng_event_rule_tracepoint_get_log_level_rule(
102 event_rule, &log_level_rule);
103 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
104 enum lttng_log_level_rule_status llr_status;
105 const char *log_level_op;
106 const char *pretty_loglevel_name;
107
108 switch (lttng_log_level_rule_get_type(log_level_rule)) {
109 case LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY:
110 log_level_op = "is";
111 llr_status = lttng_log_level_rule_exactly_get_level(
112 log_level_rule, &log_level);
113 break;
114 case LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS:
115 log_level_op = "at least";
116 llr_status = lttng_log_level_rule_at_least_as_severe_as_get_level(
117 log_level_rule, &log_level);
118 break;
119 default:
120 abort();
121 }
122
123 assert(llr_status == LTTNG_LOG_LEVEL_RULE_STATUS_OK);
124
125 pretty_loglevel_name = get_pretty_loglevel_name(
126 domain_type, log_level);
127 if (pretty_loglevel_name) {
128 _MSG(", log level %s %s", log_level_op,
129 pretty_loglevel_name);
130 } else {
131 _MSG(", log level %s %d", log_level_op, log_level);
132 }
133 } else {
134 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
135 }
136
137 event_rule_status = lttng_event_rule_tracepoint_get_exclusions_count(
138 event_rule, &exclusions_count);
139 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
140 if (exclusions_count > 0) {
141 _MSG(", exclusions: ");
142 for (i = 0; i < exclusions_count; i++) {
143 const char *exclusion;
144
145 event_rule_status = lttng_event_rule_tracepoint_get_exclusion_at_index(
146 event_rule, i, &exclusion);
147 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
148
149 _MSG("%s%s", i > 0 ? "," : "", exclusion);
150 }
151 }
152
153 MSG(")");
154 }
155
156 static void print_kernel_probe_location(
157 const struct lttng_kernel_probe_location *location)
158 {
159 enum lttng_kernel_probe_location_status status;
160 switch (lttng_kernel_probe_location_get_type(location)) {
161 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS:
162 {
163 uint64_t address;
164
165 status = lttng_kernel_probe_location_address_get_address(
166 location, &address);
167 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
168 ERR("Getting kernel probe location address failed.");
169 goto end;
170 }
171
172 _MSG("0x%" PRIx64, address);
173
174 break;
175 }
176 case LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET:
177 {
178 uint64_t offset;
179 const char *symbol_name;
180
181 symbol_name = lttng_kernel_probe_location_symbol_get_name(
182 location);
183 if (!symbol_name) {
184 ERR("Getting kernel probe location symbol name failed.");
185 goto end;
186 }
187
188 status = lttng_kernel_probe_location_symbol_get_offset(
189 location, &offset);
190 if (status != LTTNG_KERNEL_PROBE_LOCATION_STATUS_OK) {
191 ERR("Getting kernel probe location address failed.");
192 goto end;
193 }
194
195 if (offset == 0) {
196 _MSG("%s", symbol_name);
197 } else {
198 _MSG("%s+0x%" PRIx64, symbol_name, offset);
199 }
200
201 break;
202 }
203 default:
204 abort();
205 };
206 end:
207 return;
208 }
209
210 static
211 void print_event_rule_kernel_probe(const struct lttng_event_rule *event_rule)
212 {
213 enum lttng_event_rule_status event_rule_status;
214 const char *name;
215 const struct lttng_kernel_probe_location *location;
216
217 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE);
218
219 event_rule_status = lttng_event_rule_kernel_probe_get_event_name(event_rule, &name);
220 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
221 ERR("Failed to get kprobe event rule's name.");
222 goto end;
223 }
224
225 event_rule_status = lttng_event_rule_kernel_probe_get_location(
226 event_rule, &location);
227 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
228 ERR("Failed to get kprobe event rule's location.");
229 goto end;
230 }
231
232 _MSG(" rule: %s (type: probe, location: ", name);
233
234 print_kernel_probe_location(location);
235
236 MSG(")");
237
238 end:
239 return;
240 }
241
242 static
243 void print_event_rule_userspace_probe(const struct lttng_event_rule *event_rule)
244 {
245 enum lttng_event_rule_status event_rule_status;
246 const char *name;
247 const struct lttng_userspace_probe_location *location;
248 enum lttng_userspace_probe_location_type userspace_probe_location_type;
249
250 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE);
251
252 event_rule_status = lttng_event_rule_userspace_probe_get_event_name(
253 event_rule, &name);
254 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
255 ERR("Failed to get uprobe event rule's name.");
256 goto end;
257 }
258
259 event_rule_status = lttng_event_rule_userspace_probe_get_location(
260 event_rule, &location);
261 if (event_rule_status != LTTNG_EVENT_RULE_STATUS_OK) {
262 ERR("Failed to get uprobe event rule's location.");
263 goto end;
264 }
265
266 _MSG(" rule: %s (type: userspace probe, location: ", name);
267
268 userspace_probe_location_type =
269 lttng_userspace_probe_location_get_type(location);
270
271 switch (userspace_probe_location_type) {
272 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
273 {
274 const char *binary_path, *function_name;
275
276 binary_path = lttng_userspace_probe_location_function_get_binary_path(
277 location);
278 function_name = lttng_userspace_probe_location_function_get_function_name(
279 location);
280
281 _MSG("%s:%s", binary_path, function_name);
282 break;
283 }
284 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
285 _MSG("SDT not implemented yet");
286 break;
287 default:
288 abort();
289 }
290
291 MSG(")");
292
293 end:
294 return;
295 }
296
297 static
298 void print_event_rule_syscall(const struct lttng_event_rule *event_rule)
299 {
300 const char *pattern, *filter;
301 enum lttng_event_rule_status event_rule_status;
302
303 assert(lttng_event_rule_get_type(event_rule) == LTTNG_EVENT_RULE_TYPE_SYSCALL);
304
305 event_rule_status = lttng_event_rule_syscall_get_pattern(
306 event_rule, &pattern);
307 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_OK);
308
309 _MSG(" rule: %s (type: syscall", pattern);
310
311 event_rule_status = lttng_event_rule_syscall_get_filter(
312 event_rule, &filter);
313 if (event_rule_status == LTTNG_EVENT_RULE_STATUS_OK) {
314 _MSG(", filter: %s", filter);
315 } else {
316 assert(event_rule_status == LTTNG_EVENT_RULE_STATUS_UNSET);
317 }
318
319 MSG(")");
320 }
321
322 static
323 void print_event_rule(const struct lttng_event_rule *event_rule)
324 {
325 const enum lttng_event_rule_type event_rule_type =
326 lttng_event_rule_get_type(event_rule);
327
328 switch (event_rule_type) {
329 case LTTNG_EVENT_RULE_TYPE_TRACEPOINT:
330 print_event_rule_tracepoint(event_rule);
331 break;
332 case LTTNG_EVENT_RULE_TYPE_KERNEL_PROBE:
333 print_event_rule_kernel_probe(event_rule);
334 break;
335 case LTTNG_EVENT_RULE_TYPE_USERSPACE_PROBE:
336 print_event_rule_userspace_probe(event_rule);
337 break;
338 case LTTNG_EVENT_RULE_TYPE_SYSCALL:
339 print_event_rule_syscall(event_rule);
340 break;
341 default:
342 abort();
343 }
344 }
345
346 static
347 void print_one_event_expr(const struct lttng_event_expr *event_expr)
348 {
349 enum lttng_event_expr_type type;
350
351 type = lttng_event_expr_get_type(event_expr);
352
353 switch (type) {
354 case LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD:
355 {
356 const char *name;
357
358 name = lttng_event_expr_event_payload_field_get_name(
359 event_expr);
360 _MSG("%s", name);
361
362 break;
363 }
364 case LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD:
365 {
366 const char *name;
367
368 name = lttng_event_expr_channel_context_field_get_name(
369 event_expr);
370 _MSG("$ctx.%s", name);
371
372 break;
373 }
374 case LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD:
375 {
376 const char *provider_name;
377 const char *type_name;
378
379 provider_name = lttng_event_expr_app_specific_context_field_get_provider_name(
380 event_expr);
381 type_name = lttng_event_expr_app_specific_context_field_get_type_name(
382 event_expr);
383
384 _MSG("$app.%s:%s", provider_name, type_name);
385
386 break;
387 }
388 case LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT:
389 {
390 unsigned int index;
391 const struct lttng_event_expr *parent_expr;
392 enum lttng_event_expr_status status;
393
394 parent_expr = lttng_event_expr_array_field_element_get_parent_expr(
395 event_expr);
396 assert(parent_expr != NULL);
397
398 print_one_event_expr(parent_expr);
399
400 status = lttng_event_expr_array_field_element_get_index(
401 event_expr, &index);
402 assert(status == LTTNG_EVENT_EXPR_STATUS_OK);
403
404 _MSG("[%u]", index);
405
406 break;
407 }
408 default:
409 abort();
410 }
411 }
412
413 static
414 void print_condition_on_event(const struct lttng_condition *condition)
415 {
416 const struct lttng_event_rule *event_rule;
417 enum lttng_condition_status condition_status;
418 unsigned int cap_desc_count, i;
419
420 condition_status =
421 lttng_condition_on_event_get_rule(condition, &event_rule);
422 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
423
424 print_event_rule(event_rule);
425
426 condition_status =
427 lttng_condition_on_event_get_capture_descriptor_count(
428 condition, &cap_desc_count);
429 assert(condition_status == LTTNG_CONDITION_STATUS_OK);
430
431 if (cap_desc_count > 0) {
432 MSG(" captures:");
433
434 for (i = 0; i < cap_desc_count; i++) {
435 const struct lttng_event_expr *cap_desc =
436 lttng_condition_on_event_get_capture_descriptor_at_index(
437 condition, i);
438
439 _MSG(" - ");
440 print_one_event_expr(cap_desc);
441 MSG("");
442 }
443 }
444 }
445
446 static
447 void print_one_action(const struct lttng_action *action)
448 {
449 enum lttng_action_type action_type;
450 enum lttng_action_status action_status;
451 const char *value;
452
453 action_type = lttng_action_get_type(action);
454 assert(action_type != LTTNG_ACTION_TYPE_GROUP);
455
456 switch (action_type) {
457 case LTTNG_ACTION_TYPE_NOTIFY:
458 MSG("notify");
459 break;
460 case LTTNG_ACTION_TYPE_START_SESSION:
461 action_status = lttng_action_start_session_get_session_name(
462 action, &value);
463 assert(action_status == LTTNG_ACTION_STATUS_OK);
464 MSG("start session `%s`", value);
465 break;
466 case LTTNG_ACTION_TYPE_STOP_SESSION:
467 action_status = lttng_action_stop_session_get_session_name(
468 action, &value);
469 assert(action_status == LTTNG_ACTION_STATUS_OK);
470 MSG("stop session `%s`", value);
471 break;
472 case LTTNG_ACTION_TYPE_ROTATE_SESSION:
473 action_status = lttng_action_rotate_session_get_session_name(
474 action, &value);
475 assert(action_status == LTTNG_ACTION_STATUS_OK);
476 MSG("rotate session `%s`", value);
477 break;
478 case LTTNG_ACTION_TYPE_SNAPSHOT_SESSION:
479 {
480 const struct lttng_snapshot_output *output;
481
482 action_status = lttng_action_snapshot_session_get_session_name(
483 action, &value);
484 assert(action_status == LTTNG_ACTION_STATUS_OK);
485 _MSG("snapshot session `%s`", value);
486
487 action_status = lttng_action_snapshot_session_get_output(
488 action, &output);
489 if (action_status == LTTNG_ACTION_STATUS_OK) {
490 const char *name;
491 uint64_t max_size;
492 const char *ctrl_url, *data_url;
493 bool starts_with_file, starts_with_net, starts_with_net6;
494
495 ctrl_url = lttng_snapshot_output_get_ctrl_url(output);
496 assert(ctrl_url && strlen(ctrl_url) > 0);
497
498 data_url = lttng_snapshot_output_get_data_url(output);
499 assert(data_url);
500
501 starts_with_file = strncmp(ctrl_url, "file://", strlen("file://")) == 0;
502 starts_with_net = strncmp(ctrl_url, "net://", strlen("net://")) == 0;
503 starts_with_net6 = strncmp(ctrl_url, "net6://", strlen("net6://")) == 0;
504
505 if (ctrl_url[0] == '/' || starts_with_file) {
506 if (starts_with_file) {
507 ctrl_url += strlen("file://");
508 }
509
510 _MSG(", path: %s", ctrl_url);
511 } else if (starts_with_net || starts_with_net6) {
512 _MSG(", url: %s", ctrl_url);
513 } else {
514 assert(strlen(data_url) > 0);
515
516 _MSG(", control url: %s, data url: %s", ctrl_url, data_url);
517 }
518
519 name = lttng_snapshot_output_get_name(output);
520 assert(name);
521 if (strlen(name) > 0) {
522 _MSG(", name: %s", name);
523 }
524
525 max_size = lttng_snapshot_output_get_maxsize(output);
526 if (max_size != -1ULL) {
527 _MSG(", max size: %" PRIu64, max_size);
528 }
529 }
530
531 MSG("");
532 break;
533 }
534
535 default:
536 abort();
537 }
538 }
539
540 static
541 void print_one_trigger(const struct lttng_trigger *trigger)
542 {
543 const struct lttng_condition *condition;
544 enum lttng_condition_type condition_type;
545 const struct lttng_action *action;
546 enum lttng_action_type action_type;
547 enum lttng_trigger_status trigger_status;
548 const char *name;
549 enum lttng_trigger_firing_policy firing_policy_type;
550 uint64_t threshold;
551 uid_t trigger_uid;
552
553 trigger_status = lttng_trigger_get_name(trigger, &name);
554 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
555
556 trigger_status = lttng_trigger_get_owner_uid(trigger, &trigger_uid);
557 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
558
559 MSG("- id: %s", name);
560 MSG(" user id: %d", trigger_uid);
561
562 trigger_status = lttng_trigger_get_firing_policy(
563 trigger, &firing_policy_type, &threshold);
564 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
565 ERR("Failed to get trigger's policy.");
566 goto end;
567 }
568
569 switch (firing_policy_type) {
570 case LTTNG_TRIGGER_FIRING_POLICY_EVERY_N:
571 if (threshold > 1) {
572 MSG(" firing policy: after every %" PRIu64 " occurences", threshold);
573 }
574 break;
575 case LTTNG_TRIGGER_FIRING_POLICY_ONCE_AFTER_N:
576 MSG(" firing policy: once after %" PRIu64 " occurences", threshold);
577 break;
578 default:
579 abort();
580 }
581
582 condition = lttng_trigger_get_const_condition(trigger);
583 condition_type = lttng_condition_get_type(condition);
584 MSG(" condition: %s", lttng_condition_type_str(condition_type));
585 switch (condition_type) {
586 case LTTNG_CONDITION_TYPE_ON_EVENT:
587 print_condition_on_event(condition);
588 break;
589 default:
590 MSG(" (condition type not handled in %s)", __func__);
591 break;
592 }
593
594 action = lttng_trigger_get_const_action(trigger);
595 action_type = lttng_action_get_type(action);
596 if (action_type == LTTNG_ACTION_TYPE_GROUP) {
597 unsigned int count, i;
598 enum lttng_action_status action_status;
599
600 MSG(" actions:");
601
602 action_status = lttng_action_group_get_count(action, &count);
603 assert(action_status == LTTNG_ACTION_STATUS_OK);
604
605 for (i = 0; i < count; i++) {
606 const struct lttng_action *subaction =
607 lttng_action_group_get_at_index(
608 action, i);
609
610 _MSG(" ");
611 print_one_action(subaction);
612 }
613 } else {
614 _MSG(" action:");
615 print_one_action(action);
616 }
617
618 end:
619 return;
620 }
621
622 static
623 int compare_triggers_by_name(const void *a, const void *b)
624 {
625 const struct lttng_trigger *trigger_a = *((const struct lttng_trigger **) a);
626 const struct lttng_trigger *trigger_b = *((const struct lttng_trigger **) b);
627 const char *name_a, *name_b;
628 enum lttng_trigger_status trigger_status;
629
630 trigger_status = lttng_trigger_get_name(trigger_a, &name_a);
631 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
632
633 trigger_status = lttng_trigger_get_name(trigger_b, &name_b);
634 assert(trigger_status == LTTNG_TRIGGER_STATUS_OK);
635
636 return strcmp(name_a, name_b);
637 }
638
639 int cmd_list_triggers(int argc, const char **argv)
640 {
641 int ret;
642 struct argpar_parse_ret argpar_parse_ret = {};
643 struct lttng_triggers *triggers = NULL;
644 int i;
645 struct lttng_dynamic_pointer_array sorted_triggers;
646 enum lttng_trigger_status trigger_status;
647 unsigned int num_triggers;
648
649 lttng_dynamic_pointer_array_init(&sorted_triggers, NULL);
650
651 argpar_parse_ret = argpar_parse(
652 argc - 1, argv + 1, list_trigger_options, true);
653 if (!argpar_parse_ret.items) {
654 ERR("%s", argpar_parse_ret.error);
655 goto error;
656 }
657
658 for (i = 0; i < argpar_parse_ret.items->n_items; i++) {
659 const struct argpar_item *item =
660 argpar_parse_ret.items->items[i];
661
662 if (item->type == ARGPAR_ITEM_TYPE_OPT) {
663 const struct argpar_item_opt *item_opt =
664 (const struct argpar_item_opt *) item;
665
666 switch (item_opt->descr->id) {
667 case OPT_HELP:
668 SHOW_HELP();
669 ret = 0;
670 goto end;
671
672 case OPT_LIST_OPTIONS:
673 list_cmd_options_argpar(stdout,
674 list_trigger_options);
675 ret = 0;
676 goto end;
677
678 default:
679 abort();
680 }
681
682 } else {
683 const struct argpar_item_non_opt *item_non_opt =
684 (const struct argpar_item_non_opt *) item;
685
686 ERR("Unexpected argument: %s", item_non_opt->arg);
687 }
688 }
689
690 ret = lttng_list_triggers(&triggers);
691 if (ret != LTTNG_OK) {
692 ERR("Error listing triggers: %s.", lttng_strerror(-ret));
693 goto error;
694 }
695
696 trigger_status = lttng_triggers_get_count(triggers, &num_triggers);
697 if (trigger_status != LTTNG_TRIGGER_STATUS_OK) {
698 ERR("Failed to get trigger count.");
699 goto error;
700 }
701
702 for (i = 0; i < num_triggers; i++) {
703 const int add_ret = lttng_dynamic_pointer_array_add_pointer(
704 &sorted_triggers,
705 (void *) lttng_triggers_get_at_index(triggers, i));
706
707 if (add_ret) {
708 ERR("Failed to allocate array of struct lttng_trigger *.");
709 goto error;
710 }
711 }
712
713 qsort(sorted_triggers.array.buffer.data, num_triggers,
714 sizeof(struct lttng_trigger *),
715 compare_triggers_by_name);
716
717 for (i = 0; i < num_triggers; i++) {
718 const struct lttng_trigger *trigger_to_print =
719 (const struct lttng_trigger *)
720 lttng_dynamic_pointer_array_get_pointer(
721 &sorted_triggers, i);
722
723 print_one_trigger(trigger_to_print);
724 }
725
726 ret = 0;
727 goto end;
728
729 error:
730 ret = 1;
731
732 end:
733 argpar_parse_ret_fini(&argpar_parse_ret);
734 lttng_triggers_destroy(triggers);
735 lttng_dynamic_pointer_array_reset(&sorted_triggers);
736
737 return ret;
738 }
This page took 0.0439659999999999 seconds and 5 git commands to generate.