1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
12 #include <side/trace.h>
14 static struct side_tracer_handle
*tracer_handle
;
17 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
19 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
21 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
23 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
);
25 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
27 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
29 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*dynamic_item
);
31 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
34 bool type_to_host_reverse_bo(const struct side_type_description
*type_desc
)
36 switch (type_desc
->type
) {
47 case SIDE_TYPE_POINTER32
:
48 case SIDE_TYPE_POINTER64
:
49 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
54 case SIDE_TYPE_FLOAT_BINARY16
:
55 case SIDE_TYPE_FLOAT_BINARY32
:
56 case SIDE_TYPE_FLOAT_BINARY64
:
57 case SIDE_TYPE_FLOAT_BINARY128
:
58 if (type_desc
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
64 fprintf(stderr
, "Unexpected type\n");
70 bool dynamic_type_to_host_reverse_bo(const struct side_arg_dynamic_vec
*item
)
72 switch (item
->dynamic_type
) {
73 case SIDE_DYNAMIC_TYPE_U8
:
74 case SIDE_DYNAMIC_TYPE_S8
:
75 case SIDE_DYNAMIC_TYPE_BYTE
:
77 case SIDE_DYNAMIC_TYPE_U16
:
78 case SIDE_DYNAMIC_TYPE_U32
:
79 case SIDE_DYNAMIC_TYPE_U64
:
80 case SIDE_DYNAMIC_TYPE_S16
:
81 case SIDE_DYNAMIC_TYPE_S32
:
82 case SIDE_DYNAMIC_TYPE_S64
:
83 case SIDE_DYNAMIC_TYPE_POINTER32
:
84 case SIDE_DYNAMIC_TYPE_POINTER64
:
85 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_BYTE_ORDER_HOST
)
90 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
91 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
92 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
93 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
94 if (item
->u
.side_basic
.byte_order
!= SIDE_TYPE_FLOAT_WORD_ORDER_HOST
)
100 fprintf(stderr
, "Unexpected type\n");
106 void tracer_print_attr_type(const char *separator
, const struct side_attr
*attr
)
108 printf("{ key%s \"%s\", value%s ", separator
, attr
->key
, separator
);
109 switch (attr
->value
.type
) {
110 case SIDE_ATTR_TYPE_BOOL
:
111 printf("%s", attr
->value
.u
.side_bool
? "true" : "false");
113 case SIDE_ATTR_TYPE_U8
:
114 printf("%" PRIu8
, attr
->value
.u
.side_u8
);
116 case SIDE_ATTR_TYPE_U16
:
117 printf("%" PRIu16
, attr
->value
.u
.side_u16
);
119 case SIDE_ATTR_TYPE_U32
:
120 printf("%" PRIu32
, attr
->value
.u
.side_u32
);
122 case SIDE_ATTR_TYPE_U64
:
123 printf("%" PRIu64
, attr
->value
.u
.side_u64
);
125 case SIDE_ATTR_TYPE_S8
:
126 printf("%" PRId8
, attr
->value
.u
.side_s8
);
128 case SIDE_ATTR_TYPE_S16
:
129 printf("%" PRId16
, attr
->value
.u
.side_s16
);
131 case SIDE_ATTR_TYPE_S32
:
132 printf("%" PRId32
, attr
->value
.u
.side_s32
);
134 case SIDE_ATTR_TYPE_S64
:
135 printf("%" PRId64
, attr
->value
.u
.side_s64
);
137 case SIDE_ATTR_TYPE_POINTER32
:
138 printf("0x%" PRIx32
, attr
->value
.u
.side_u32
);
140 case SIDE_ATTR_TYPE_POINTER64
:
141 printf("0x%" PRIx64
, attr
->value
.u
.side_u64
);
143 case SIDE_ATTR_TYPE_FLOAT_BINARY16
:
145 printf("%g", (double) attr
->value
.u
.side_float_binary16
);
148 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
151 case SIDE_ATTR_TYPE_FLOAT_BINARY32
:
153 printf("%g", (double) attr
->value
.u
.side_float_binary32
);
156 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
159 case SIDE_ATTR_TYPE_FLOAT_BINARY64
:
161 printf("%g", (double) attr
->value
.u
.side_float_binary64
);
164 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
167 case SIDE_ATTR_TYPE_FLOAT_BINARY128
:
169 printf("%Lg", (long double) attr
->value
.u
.side_float_binary128
);
172 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
175 case SIDE_ATTR_TYPE_STRING
:
176 printf("\"%s\"", (const char *)(uintptr_t) attr
->value
.u
.string
);
179 fprintf(stderr
, "ERROR: <UNKNOWN ATTRIBUTE TYPE>");
186 void print_attributes(const char *prefix_str
, const char *separator
,
187 const struct side_attr
*attr
, uint32_t nr_attr
)
193 printf("%s%s [ ", prefix_str
, separator
);
194 for (i
= 0; i
< nr_attr
; i
++) {
195 printf("%s", i
? ", " : "");
196 tracer_print_attr_type(separator
, &attr
[i
]);
202 void print_enum(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
204 const struct side_enum_mappings
*mappings
= type_desc
->u
.side_enum
.mappings
;
205 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum
.elem_type
;
206 int i
, print_count
= 0;
209 if (elem_type
->type
!= item
->type
) {
210 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
213 switch (item
->type
) {
215 value
= (int64_t) item
->u
.side_u8
;
221 v
= item
->u
.side_u16
;
222 if (type_to_host_reverse_bo(elem_type
))
223 v
= side_bswap_16(v
);
231 v
= item
->u
.side_u32
;
232 if (type_to_host_reverse_bo(elem_type
))
233 v
= side_bswap_32(v
);
241 v
= item
->u
.side_u64
;
242 if (type_to_host_reverse_bo(elem_type
))
243 v
= side_bswap_64(v
);
248 value
= (int64_t) item
->u
.side_s8
;
254 v
= item
->u
.side_s16
;
255 if (type_to_host_reverse_bo(elem_type
))
256 v
= side_bswap_16(v
);
264 v
= item
->u
.side_s32
;
265 if (type_to_host_reverse_bo(elem_type
))
266 v
= side_bswap_32(v
);
274 v
= item
->u
.side_s64
;
275 if (type_to_host_reverse_bo(elem_type
))
276 v
= side_bswap_64(v
);
281 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
284 print_attributes("attr", ":", mappings
->attr
, mappings
->nr_attr
);
285 printf("%s", mappings
->nr_attr
? ", " : "");
286 tracer_print_type(type_desc
->u
.side_enum
.elem_type
, item
);
287 printf(", labels: [ ");
288 for (i
= 0; i
< mappings
->nr_mappings
; i
++) {
289 const struct side_enum_mapping
*mapping
= &mappings
->mappings
[i
];
291 if (mapping
->range_end
< mapping
->range_begin
) {
292 fprintf(stderr
, "ERROR: Unexpected enum range: %" PRIu64
"-%" PRIu64
"\n",
293 mapping
->range_begin
, mapping
->range_end
);
296 if (value
>= mapping
->range_begin
&& value
<= mapping
->range_end
) {
297 printf("%s", print_count
++ ? ", " : "");
298 printf("\"%s\"", mapping
->label
);
302 printf("<NO LABEL>");
307 uint32_t enum_elem_type_to_stride(const struct side_type_description
*elem_type
)
311 switch (elem_type
->type
) {
312 case SIDE_TYPE_U8
: /* Fall-through */
326 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
333 void print_enum_bitmap(const struct side_type_description
*type_desc
,
334 const struct side_arg_vec
*item
)
336 const struct side_type_description
*elem_type
= type_desc
->u
.side_enum_bitmap
.elem_type
;
337 const struct side_enum_bitmap_mappings
*side_enum_mappings
= type_desc
->u
.side_enum_bitmap
.mappings
;
338 int i
, print_count
= 0;
339 uint32_t stride_bit
, nr_items
;
340 bool reverse_byte_order
= false;
341 const struct side_arg_vec
*array_item
;
343 switch (elem_type
->type
) {
344 case SIDE_TYPE_U8
: /* Fall-through */
345 case SIDE_TYPE_BYTE
: /* Fall-through */
346 case SIDE_TYPE_U16
: /* Fall-through */
347 case SIDE_TYPE_U32
: /* Fall-through */
349 stride_bit
= enum_elem_type_to_stride(elem_type
);
350 reverse_byte_order
= type_to_host_reverse_bo(elem_type
);
354 case SIDE_TYPE_ARRAY
:
355 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_array
.elem_type
);
356 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_array
.elem_type
);
357 array_item
= item
->u
.side_array
->sav
;
358 nr_items
= type_desc
->u
.side_array
.length
;
361 stride_bit
= enum_elem_type_to_stride(elem_type
->u
.side_vla
.elem_type
);
362 reverse_byte_order
= type_to_host_reverse_bo(elem_type
->u
.side_vla
.elem_type
);
363 array_item
= item
->u
.side_vla
->sav
;
364 nr_items
= item
->u
.side_vla
->len
;
367 fprintf(stderr
, "ERROR: Unexpected enum element type\n");
371 print_attributes("attr", ":", side_enum_mappings
->attr
, side_enum_mappings
->nr_attr
);
372 printf("%s", side_enum_mappings
->nr_attr
? ", " : "");
373 printf("labels: [ ");
374 for (i
= 0; i
< side_enum_mappings
->nr_mappings
; i
++) {
375 const struct side_enum_bitmap_mapping
*mapping
= &side_enum_mappings
->mappings
[i
];
379 if (mapping
->range_end
< mapping
->range_begin
) {
380 fprintf(stderr
, "ERROR: Unexpected enum bitmap range: %" PRIu64
"-%" PRIu64
"\n",
381 mapping
->range_begin
, mapping
->range_end
);
384 for (bit
= mapping
->range_begin
; bit
<= mapping
->range_end
; bit
++) {
385 if (bit
> (nr_items
* stride_bit
) - 1)
387 switch (stride_bit
) {
390 uint8_t v
= array_item
[bit
/ 8].u
.side_u8
;
391 if (v
& (1ULL << (bit
% 8))) {
399 uint16_t v
= array_item
[bit
/ 16].u
.side_u16
;
400 if (reverse_byte_order
)
401 v
= side_bswap_16(v
);
402 if (v
& (1ULL << (bit
% 16))) {
410 uint32_t v
= array_item
[bit
/ 32].u
.side_u32
;
411 if (reverse_byte_order
)
412 v
= side_bswap_32(v
);
413 if (v
& (1ULL << (bit
% 32))) {
421 uint64_t v
= array_item
[bit
/ 64].u
.side_u64
;
422 if (reverse_byte_order
)
423 v
= side_bswap_64(v
);
424 if (v
& (1ULL << (bit
% 64))) {
436 printf("%s", print_count
++ ? ", " : "");
437 printf("\"%s\"", mapping
->label
);
441 printf("<NO LABEL>");
446 void tracer_print_basic_type_header(const struct side_type_description
*type_desc
)
448 print_attributes("attr", ":", type_desc
->u
.side_basic
.attr
, type_desc
->u
.side_basic
.nr_attr
);
449 printf("%s", type_desc
->u
.side_basic
.nr_attr
? ", " : "");
454 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
458 switch (type_desc
->type
) {
459 case SIDE_TYPE_ARRAY
:
460 switch (item
->type
) {
461 case SIDE_TYPE_ARRAY_U8
:
462 case SIDE_TYPE_ARRAY_U16
:
463 case SIDE_TYPE_ARRAY_U32
:
464 case SIDE_TYPE_ARRAY_U64
:
465 case SIDE_TYPE_ARRAY_S8
:
466 case SIDE_TYPE_ARRAY_S16
:
467 case SIDE_TYPE_ARRAY_S32
:
468 case SIDE_TYPE_ARRAY_S64
:
469 case SIDE_TYPE_ARRAY_POINTER32
:
470 case SIDE_TYPE_ARRAY_POINTER64
:
471 case SIDE_TYPE_ARRAY_BYTE
:
472 case SIDE_TYPE_ARRAY
:
475 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
482 switch (item
->type
) {
483 case SIDE_TYPE_VLA_U8
:
484 case SIDE_TYPE_VLA_U16
:
485 case SIDE_TYPE_VLA_U32
:
486 case SIDE_TYPE_VLA_U64
:
487 case SIDE_TYPE_VLA_S8
:
488 case SIDE_TYPE_VLA_S16
:
489 case SIDE_TYPE_VLA_S32
:
490 case SIDE_TYPE_VLA_S64
:
491 case SIDE_TYPE_VLA_BYTE
:
492 case SIDE_TYPE_VLA_POINTER32
:
493 case SIDE_TYPE_VLA_POINTER64
:
497 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
504 switch (item
->type
) {
515 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
521 case SIDE_TYPE_ENUM_BITMAP
:
522 switch (item
->type
) {
528 case SIDE_TYPE_ARRAY
:
532 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
539 if (type_desc
->type
!= item
->type
) {
540 fprintf(stderr
, "ERROR: type mismatch between description and arguments\n");
546 if (type_desc
->type
== SIDE_TYPE_ENUM
|| type_desc
->type
== SIDE_TYPE_ENUM_BITMAP
)
547 type
= type_desc
->type
;
554 tracer_print_basic_type_header(type_desc
);
555 printf("%s", item
->u
.side_bool
? "true" : "false");
558 tracer_print_basic_type_header(type_desc
);
559 printf("%" PRIu8
, item
->u
.side_u8
);
565 v
= item
->u
.side_u16
;
566 if (type_to_host_reverse_bo(type_desc
))
567 v
= side_bswap_16(v
);
568 tracer_print_basic_type_header(type_desc
);
569 printf("%" PRIu16
, v
);
576 v
= item
->u
.side_u32
;
577 if (type_to_host_reverse_bo(type_desc
))
578 v
= side_bswap_32(v
);
579 tracer_print_basic_type_header(type_desc
);
580 printf("%" PRIu32
, v
);
587 v
= item
->u
.side_u64
;
588 if (type_to_host_reverse_bo(type_desc
))
589 v
= side_bswap_64(v
);
590 tracer_print_basic_type_header(type_desc
);
591 printf("%" PRIu64
, v
);
595 tracer_print_basic_type_header(type_desc
);
596 printf("%" PRId8
, item
->u
.side_s8
);
602 v
= item
->u
.side_s16
;
603 if (type_to_host_reverse_bo(type_desc
))
604 v
= side_bswap_16(v
);
605 tracer_print_basic_type_header(type_desc
);
606 printf("%" PRId16
, v
);
613 v
= item
->u
.side_s32
;
614 if (type_to_host_reverse_bo(type_desc
))
615 v
= side_bswap_32(v
);
616 tracer_print_basic_type_header(type_desc
);
617 printf("%" PRId32
, v
);
624 v
= item
->u
.side_s64
;
625 if (type_to_host_reverse_bo(type_desc
))
626 v
= side_bswap_64(v
);
627 tracer_print_basic_type_header(type_desc
);
628 printf("%" PRId64
, v
);
631 case SIDE_TYPE_POINTER32
:
635 v
= item
->u
.side_u32
;
636 if (type_to_host_reverse_bo(type_desc
))
637 v
= side_bswap_32(v
);
638 tracer_print_basic_type_header(type_desc
);
639 printf("0x%" PRIx32
, v
);
642 case SIDE_TYPE_POINTER64
:
646 v
= item
->u
.side_u64
;
647 if (type_to_host_reverse_bo(type_desc
))
648 v
= side_bswap_64(v
);
649 tracer_print_basic_type_header(type_desc
);
650 printf("0x%" PRIx64
, v
);
654 tracer_print_basic_type_header(type_desc
);
655 printf("0x%" PRIx8
, item
->u
.side_byte
);
659 print_enum(type_desc
, item
);
662 case SIDE_TYPE_ENUM_BITMAP
:
663 print_enum_bitmap(type_desc
, item
);
666 case SIDE_TYPE_FLOAT_BINARY16
:
673 .f
= item
->u
.side_float_binary16
,
676 if (type_to_host_reverse_bo(type_desc
))
677 float16
.u
= side_bswap_16(float16
.u
);
678 tracer_print_basic_type_header(type_desc
);
679 printf("%g", (double) float16
.f
);
682 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
686 case SIDE_TYPE_FLOAT_BINARY32
:
693 .f
= item
->u
.side_float_binary32
,
696 if (type_to_host_reverse_bo(type_desc
))
697 float32
.u
= side_bswap_32(float32
.u
);
698 tracer_print_basic_type_header(type_desc
);
699 printf("%g", (double) float32
.f
);
702 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
706 case SIDE_TYPE_FLOAT_BINARY64
:
713 .f
= item
->u
.side_float_binary64
,
716 if (type_to_host_reverse_bo(type_desc
))
717 float64
.u
= side_bswap_64(float64
.u
);
718 tracer_print_basic_type_header(type_desc
);
719 printf("%g", (double) float64
.f
);
722 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
726 case SIDE_TYPE_FLOAT_BINARY128
:
733 .f
= item
->u
.side_float_binary128
,
736 if (type_to_host_reverse_bo(type_desc
))
737 side_bswap_128p(float128
.arr
);
738 tracer_print_basic_type_header(type_desc
);
739 printf("%Lg", (long double) float128
.f
);
742 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
746 case SIDE_TYPE_STRING
:
747 tracer_print_basic_type_header(type_desc
);
748 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.string
);
750 case SIDE_TYPE_STRUCT
:
751 tracer_print_struct(type_desc
, item
->u
.side_struct
);
753 case SIDE_TYPE_ARRAY
:
754 tracer_print_array(type_desc
, item
->u
.side_array
);
757 tracer_print_vla(type_desc
, item
->u
.side_vla
);
759 case SIDE_TYPE_VLA_VISITOR
:
760 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
762 case SIDE_TYPE_ARRAY_U8
:
763 case SIDE_TYPE_ARRAY_U16
:
764 case SIDE_TYPE_ARRAY_U32
:
765 case SIDE_TYPE_ARRAY_U64
:
766 case SIDE_TYPE_ARRAY_S8
:
767 case SIDE_TYPE_ARRAY_S16
:
768 case SIDE_TYPE_ARRAY_S32
:
769 case SIDE_TYPE_ARRAY_S64
:
770 case SIDE_TYPE_ARRAY_BYTE
:
771 case SIDE_TYPE_ARRAY_POINTER32
:
772 case SIDE_TYPE_ARRAY_POINTER64
:
773 tracer_print_array_fixint(type_desc
, item
);
775 case SIDE_TYPE_VLA_U8
:
776 case SIDE_TYPE_VLA_U16
:
777 case SIDE_TYPE_VLA_U32
:
778 case SIDE_TYPE_VLA_U64
:
779 case SIDE_TYPE_VLA_S8
:
780 case SIDE_TYPE_VLA_S16
:
781 case SIDE_TYPE_VLA_S32
:
782 case SIDE_TYPE_VLA_S64
:
783 case SIDE_TYPE_VLA_BYTE
:
784 case SIDE_TYPE_VLA_POINTER32
:
785 case SIDE_TYPE_VLA_POINTER64
:
786 tracer_print_vla_fixint(type_desc
, item
);
788 case SIDE_TYPE_DYNAMIC
:
789 tracer_print_basic_type_header(type_desc
);
790 tracer_print_dynamic(&item
->u
.dynamic
);
793 fprintf(stderr
, "<UNKNOWN TYPE>");
800 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
802 printf("%s: ", item_desc
->field_name
);
803 tracer_print_type(&item_desc
->side_type
, item
);
807 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
809 const struct side_arg_vec
*sav
= sav_desc
->sav
;
810 uint32_t side_sav_len
= sav_desc
->len
;
813 if (type_desc
->u
.side_struct
->nr_fields
!= side_sav_len
) {
814 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments of structure\n");
817 print_attributes("attr", ":", type_desc
->u
.side_struct
->attr
, type_desc
->u
.side_struct
->nr_attr
);
818 printf("%s", type_desc
->u
.side_struct
->nr_attr
? ", " : "");
819 printf("fields: { ");
820 for (i
= 0; i
< side_sav_len
; i
++) {
821 printf("%s", i
? ", " : "");
822 tracer_print_field(&type_desc
->u
.side_struct
->fields
[i
], &sav
[i
]);
828 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
830 const struct side_arg_vec
*sav
= sav_desc
->sav
;
831 uint32_t side_sav_len
= sav_desc
->len
;
834 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
835 fprintf(stderr
, "ERROR: length mismatch between description and arguments of array\n");
838 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
839 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
840 printf("elements: ");
842 for (i
= 0; i
< side_sav_len
; i
++) {
843 printf("%s", i
? ", " : "");
844 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
850 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
852 const struct side_arg_vec
*sav
= sav_desc
->sav
;
853 uint32_t side_sav_len
= sav_desc
->len
;
856 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
857 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
858 printf("elements: ");
860 for (i
= 0; i
< side_sav_len
; i
++) {
861 printf("%s", i
? ", " : "");
862 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
867 struct tracer_visitor_priv
{
868 const struct side_type_description
*elem_type
;
873 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
874 const struct side_arg_vec
*elem
)
876 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
878 printf("%s", tracer_priv
->i
++ ? ", " : "");
879 tracer_print_type(tracer_priv
->elem_type
, elem
);
880 return SIDE_VISITOR_STATUS_OK
;
884 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
886 enum side_visitor_status status
;
887 struct tracer_visitor_priv tracer_priv
= {
888 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
891 const struct side_tracer_visitor_ctx tracer_ctx
= {
892 .write_elem
= tracer_write_elem_cb
,
893 .priv
= &tracer_priv
,
896 print_attributes("attr", ":", type_desc
->u
.side_vla_visitor
.attr
, type_desc
->u
.side_vla_visitor
.nr_attr
);
897 printf("%s", type_desc
->u
.side_vla_visitor
.nr_attr
? ", " : "");
898 printf("elements: ");
900 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
902 case SIDE_VISITOR_STATUS_OK
:
904 case SIDE_VISITOR_STATUS_ERROR
:
905 fprintf(stderr
, "ERROR: Visitor error\n");
911 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
913 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
914 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
915 void *p
= item
->u
.side_array_fixint
;
916 enum side_type side_type
;
919 print_attributes("attr", ":", type_desc
->u
.side_array
.attr
, type_desc
->u
.side_array
.nr_attr
);
920 printf("%s", type_desc
->u
.side_array
.nr_attr
? ", " : "");
921 printf("elements: ");
922 switch (item
->type
) {
923 case SIDE_TYPE_ARRAY_U8
:
924 if (elem_type
->type
!= SIDE_TYPE_U8
)
927 case SIDE_TYPE_ARRAY_U16
:
928 if (elem_type
->type
!= SIDE_TYPE_U16
)
931 case SIDE_TYPE_ARRAY_U32
:
932 if (elem_type
->type
!= SIDE_TYPE_U32
)
935 case SIDE_TYPE_ARRAY_U64
:
936 if (elem_type
->type
!= SIDE_TYPE_U64
)
939 case SIDE_TYPE_ARRAY_S8
:
940 if (elem_type
->type
!= SIDE_TYPE_S8
)
943 case SIDE_TYPE_ARRAY_S16
:
944 if (elem_type
->type
!= SIDE_TYPE_S16
)
947 case SIDE_TYPE_ARRAY_S32
:
948 if (elem_type
->type
!= SIDE_TYPE_S32
)
951 case SIDE_TYPE_ARRAY_S64
:
952 if (elem_type
->type
!= SIDE_TYPE_S64
)
955 case SIDE_TYPE_ARRAY_BYTE
:
956 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
959 case SIDE_TYPE_ARRAY_POINTER32
:
960 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
962 case SIDE_TYPE_ARRAY_POINTER64
:
963 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
969 side_type
= elem_type
->type
;
972 for (i
= 0; i
< side_sav_len
; i
++) {
973 struct side_arg_vec sav_elem
= {
979 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
982 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
985 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
988 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
991 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
994 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
997 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1000 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1002 case SIDE_TYPE_BYTE
:
1003 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1005 case SIDE_TYPE_POINTER32
:
1006 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1008 case SIDE_TYPE_POINTER64
:
1009 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1013 fprintf(stderr
, "ERROR: Unexpected type\n");
1017 printf("%s", i
? ", " : "");
1018 tracer_print_type(elem_type
, &sav_elem
);
1024 fprintf(stderr
, "ERROR: type mismatch\n");
1028 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
1030 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
1031 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
1032 void *p
= item
->u
.side_vla_fixint
.p
;
1033 enum side_type side_type
;
1036 print_attributes("attr", ":", type_desc
->u
.side_vla
.attr
, type_desc
->u
.side_vla
.nr_attr
);
1037 printf("%s", type_desc
->u
.side_vla
.nr_attr
? ", " : "");
1038 printf("elements: ");
1039 switch (item
->type
) {
1040 case SIDE_TYPE_VLA_U8
:
1041 if (elem_type
->type
!= SIDE_TYPE_U8
)
1044 case SIDE_TYPE_VLA_U16
:
1045 if (elem_type
->type
!= SIDE_TYPE_U16
)
1048 case SIDE_TYPE_VLA_U32
:
1049 if (elem_type
->type
!= SIDE_TYPE_U32
)
1052 case SIDE_TYPE_VLA_U64
:
1053 if (elem_type
->type
!= SIDE_TYPE_U64
)
1056 case SIDE_TYPE_VLA_S8
:
1057 if (elem_type
->type
!= SIDE_TYPE_S8
)
1060 case SIDE_TYPE_VLA_S16
:
1061 if (elem_type
->type
!= SIDE_TYPE_S16
)
1064 case SIDE_TYPE_VLA_S32
:
1065 if (elem_type
->type
!= SIDE_TYPE_S32
)
1068 case SIDE_TYPE_VLA_S64
:
1069 if (elem_type
->type
!= SIDE_TYPE_S64
)
1072 case SIDE_TYPE_VLA_BYTE
:
1073 if (elem_type
->type
!= SIDE_TYPE_BYTE
)
1076 case SIDE_TYPE_VLA_POINTER32
:
1077 if (elem_type
->type
!= SIDE_TYPE_POINTER32
)
1079 case SIDE_TYPE_VLA_POINTER64
:
1080 if (elem_type
->type
!= SIDE_TYPE_POINTER64
)
1086 side_type
= elem_type
->type
;
1089 for (i
= 0; i
< side_sav_len
; i
++) {
1090 struct side_arg_vec sav_elem
= {
1094 switch (side_type
) {
1096 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
1099 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
1102 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
1105 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
1108 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1111 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
1114 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1117 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
1119 case SIDE_TYPE_BYTE
:
1120 sav_elem
.u
.side_byte
= ((const uint8_t *) p
)[i
];
1122 case SIDE_TYPE_POINTER32
:
1123 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
1125 case SIDE_TYPE_POINTER64
:
1126 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
1130 fprintf(stderr
, "ERROR: Unexpected type\n");
1134 printf("%s", i
? ", " : "");
1135 tracer_print_type(elem_type
, &sav_elem
);
1141 fprintf(stderr
, "ERROR: type mismatch\n");
1146 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
1148 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
1149 uint32_t len
= dynamic_struct
->len
;
1152 print_attributes("attr", "::", dynamic_struct
->attr
, dynamic_struct
->nr_attr
);
1153 printf("%s", dynamic_struct
->nr_attr
? ", " : "");
1154 printf("fields:: ");
1156 for (i
= 0; i
< len
; i
++) {
1157 printf("%s", i
? ", " : "");
1158 printf("%s:: ", fields
[i
].field_name
);
1159 tracer_print_dynamic(&fields
[i
].elem
);
1164 struct tracer_dynamic_struct_visitor_priv
{
1169 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
1170 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
1171 const struct side_arg_dynamic_event_field
*dynamic_field
)
1173 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1175 printf("%s", tracer_priv
->i
++ ? ", " : "");
1176 printf("%s:: ", dynamic_field
->field_name
);
1177 tracer_print_dynamic(&dynamic_field
->elem
);
1178 return SIDE_VISITOR_STATUS_OK
;
1182 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
1184 enum side_visitor_status status
;
1185 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
1188 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
1189 .write_field
= tracer_dynamic_struct_write_elem_cb
,
1190 .priv
= &tracer_priv
,
1192 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
1194 print_attributes("attr", "::", item
->u
.side_dynamic_struct_visitor
.attr
, item
->u
.side_dynamic_struct_visitor
.nr_attr
);
1195 printf("%s", item
->u
.side_dynamic_struct_visitor
.nr_attr
? ", " : "");
1196 printf("fields:: ");
1198 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
1200 case SIDE_VISITOR_STATUS_OK
:
1202 case SIDE_VISITOR_STATUS_ERROR
:
1203 fprintf(stderr
, "ERROR: Visitor error\n");
1210 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
1212 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
1213 uint32_t side_sav_len
= vla
->len
;
1216 print_attributes("attr", "::", vla
->attr
, vla
->nr_attr
);
1217 printf("%s", vla
->nr_attr
? ", " : "");
1218 printf("elements:: ");
1220 for (i
= 0; i
< side_sav_len
; i
++) {
1221 printf("%s", i
? ", " : "");
1222 tracer_print_dynamic(&sav
[i
]);
1227 struct tracer_dynamic_vla_visitor_priv
{
1232 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
1233 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
1234 const struct side_arg_dynamic_vec
*elem
)
1236 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
1238 printf("%s", tracer_priv
->i
++ ? ", " : "");
1239 tracer_print_dynamic(elem
);
1240 return SIDE_VISITOR_STATUS_OK
;
1244 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
1246 enum side_visitor_status status
;
1247 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
1250 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
1251 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
1252 .priv
= &tracer_priv
,
1254 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
1256 print_attributes("attr", "::", item
->u
.side_dynamic_vla_visitor
.attr
, item
->u
.side_dynamic_vla_visitor
.nr_attr
);
1257 printf("%s", item
->u
.side_dynamic_vla_visitor
.nr_attr
? ", " : "");
1258 printf("elements:: ");
1260 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
1262 case SIDE_VISITOR_STATUS_OK
:
1264 case SIDE_VISITOR_STATUS_ERROR
:
1265 fprintf(stderr
, "ERROR: Visitor error\n");
1272 void tracer_print_dynamic_basic_type_header(const struct side_arg_dynamic_vec
*item
)
1274 print_attributes("attr", "::", item
->u
.side_basic
.attr
, item
->u
.side_basic
.nr_attr
);
1275 printf("%s", item
->u
.side_basic
.nr_attr
? ", " : "");
1280 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
1283 switch (item
->dynamic_type
) {
1284 case SIDE_DYNAMIC_TYPE_NULL
:
1285 tracer_print_dynamic_basic_type_header(item
);
1286 printf("<NULL TYPE>");
1288 case SIDE_DYNAMIC_TYPE_BOOL
:
1289 tracer_print_dynamic_basic_type_header(item
);
1290 printf("%s", item
->u
.side_basic
.u
.side_bool
? "true" : "false");
1292 case SIDE_DYNAMIC_TYPE_U8
:
1293 tracer_print_dynamic_basic_type_header(item
);
1294 printf("%" PRIu8
, item
->u
.side_basic
.u
.side_u8
);
1296 case SIDE_DYNAMIC_TYPE_U16
:
1300 v
= item
->u
.side_basic
.u
.side_u16
;
1301 if (dynamic_type_to_host_reverse_bo(item
))
1302 v
= side_bswap_16(v
);
1303 tracer_print_dynamic_basic_type_header(item
);
1304 printf("%" PRIu16
, v
);
1307 case SIDE_DYNAMIC_TYPE_U32
:
1311 v
= item
->u
.side_basic
.u
.side_u32
;
1312 if (dynamic_type_to_host_reverse_bo(item
))
1313 v
= side_bswap_32(v
);
1314 tracer_print_dynamic_basic_type_header(item
);
1315 printf("%" PRIu32
, v
);
1318 case SIDE_DYNAMIC_TYPE_U64
:
1322 v
= item
->u
.side_basic
.u
.side_u64
;
1323 if (dynamic_type_to_host_reverse_bo(item
))
1324 v
= side_bswap_64(v
);
1325 tracer_print_dynamic_basic_type_header(item
);
1326 printf("%" PRIu64
, v
);
1329 case SIDE_DYNAMIC_TYPE_S8
:
1330 tracer_print_dynamic_basic_type_header(item
);
1331 printf("%" PRId8
, item
->u
.side_basic
.u
.side_s8
);
1333 case SIDE_DYNAMIC_TYPE_S16
:
1337 v
= item
->u
.side_basic
.u
.side_u16
;
1338 if (dynamic_type_to_host_reverse_bo(item
))
1339 v
= side_bswap_16(v
);
1340 tracer_print_dynamic_basic_type_header(item
);
1341 printf("%" PRId16
, v
);
1344 case SIDE_DYNAMIC_TYPE_S32
:
1348 v
= item
->u
.side_basic
.u
.side_u32
;
1349 if (dynamic_type_to_host_reverse_bo(item
))
1350 v
= side_bswap_32(v
);
1351 tracer_print_dynamic_basic_type_header(item
);
1352 printf("%" PRId32
, v
);
1355 case SIDE_DYNAMIC_TYPE_S64
:
1359 v
= item
->u
.side_basic
.u
.side_u64
;
1360 if (dynamic_type_to_host_reverse_bo(item
))
1361 v
= side_bswap_64(v
);
1362 tracer_print_dynamic_basic_type_header(item
);
1363 printf("%" PRId64
, v
);
1366 case SIDE_DYNAMIC_TYPE_BYTE
:
1367 tracer_print_dynamic_basic_type_header(item
);
1368 printf("0x%" PRIx8
, item
->u
.side_basic
.u
.side_byte
);
1370 case SIDE_DYNAMIC_TYPE_POINTER32
:
1374 v
= item
->u
.side_basic
.u
.side_u32
;
1375 if (dynamic_type_to_host_reverse_bo(item
))
1376 v
= side_bswap_32(v
);
1377 tracer_print_dynamic_basic_type_header(item
);
1378 printf("0x%" PRIx32
, v
);
1382 case SIDE_DYNAMIC_TYPE_POINTER64
:
1386 v
= item
->u
.side_basic
.u
.side_u64
;
1387 if (dynamic_type_to_host_reverse_bo(item
))
1388 v
= side_bswap_64(v
);
1389 tracer_print_dynamic_basic_type_header(item
);
1390 printf("0x%" PRIx64
, v
);
1394 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY16
:
1401 .f
= item
->u
.side_basic
.u
.side_float_binary16
,
1404 if (dynamic_type_to_host_reverse_bo(item
))
1405 float16
.u
= side_bswap_16(float16
.u
);
1406 tracer_print_dynamic_basic_type_header(item
);
1407 printf("%g", (double) float16
.f
);
1410 fprintf(stderr
, "ERROR: Unsupported binary16 float type\n");
1414 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY32
:
1421 .f
= item
->u
.side_basic
.u
.side_float_binary32
,
1424 if (dynamic_type_to_host_reverse_bo(item
))
1425 float32
.u
= side_bswap_32(float32
.u
);
1426 tracer_print_dynamic_basic_type_header(item
);
1427 printf("%g", (double) float32
.f
);
1430 fprintf(stderr
, "ERROR: Unsupported binary32 float type\n");
1434 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY64
:
1441 .f
= item
->u
.side_basic
.u
.side_float_binary64
,
1444 if (dynamic_type_to_host_reverse_bo(item
))
1445 float64
.u
= side_bswap_64(float64
.u
);
1446 tracer_print_dynamic_basic_type_header(item
);
1447 printf("%g", (double) float64
.f
);
1450 fprintf(stderr
, "ERROR: Unsupported binary64 float type\n");
1454 case SIDE_DYNAMIC_TYPE_FLOAT_BINARY128
:
1461 .f
= item
->u
.side_basic
.u
.side_float_binary128
,
1464 if (dynamic_type_to_host_reverse_bo(item
))
1465 side_bswap_128p(float128
.arr
);
1466 tracer_print_dynamic_basic_type_header(item
);
1467 printf("%Lg", (long double) float128
.f
);
1470 fprintf(stderr
, "ERROR: Unsupported binary128 float type\n");
1474 case SIDE_DYNAMIC_TYPE_STRING
:
1475 tracer_print_dynamic_basic_type_header(item
);
1476 printf("\"%s\"", (const char *)(uintptr_t) item
->u
.side_basic
.u
.string
);
1478 case SIDE_DYNAMIC_TYPE_STRUCT
:
1479 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
1481 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
1482 tracer_print_dynamic_struct_visitor(item
);
1484 case SIDE_DYNAMIC_TYPE_VLA
:
1485 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
1487 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
1488 tracer_print_dynamic_vla_visitor(item
);
1491 fprintf(stderr
, "<UNKNOWN TYPE>");
1498 void tracer_print_static_fields(const struct side_event_description
*desc
,
1499 const struct side_arg_vec_description
*sav_desc
,
1502 const struct side_arg_vec
*sav
= sav_desc
->sav
;
1503 uint32_t side_sav_len
= sav_desc
->len
;
1506 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
1507 if (desc
->nr_fields
!= side_sav_len
) {
1508 fprintf(stderr
, "ERROR: number of fields mismatch between description and arguments\n");
1511 print_attributes(", attr", ":", desc
->attr
, desc
->nr_attr
);
1512 printf("%s", side_sav_len
? ", fields: [ " : "");
1513 for (i
= 0; i
< side_sav_len
; i
++) {
1514 printf("%s", i
? ", " : "");
1515 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
1523 void tracer_call(const struct side_event_description
*desc
,
1524 const struct side_arg_vec_description
*sav_desc
,
1525 void *priv
__attribute__((unused
)))
1529 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
1533 void tracer_call_variadic(const struct side_event_description
*desc
,
1534 const struct side_arg_vec_description
*sav_desc
,
1535 const struct side_arg_dynamic_event_struct
*var_struct
,
1536 void *priv
__attribute__((unused
)))
1538 uint32_t var_struct_len
= var_struct
->len
;
1539 int nr_fields
= 0, i
;
1541 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
1543 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
1544 fprintf(stderr
, "ERROR: unexpected non-variadic event description\n");
1547 print_attributes(", attr ", "::", var_struct
->attr
, var_struct
->nr_attr
);
1548 printf("%s", var_struct_len
? ", fields:: [ " : "");
1549 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
1550 printf("%s", i
? ", " : "");
1551 printf("%s:: ", var_struct
->fields
[i
].field_name
);
1552 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);
1559 void tracer_event_notification(enum side_tracer_notification notif
,
1560 struct side_event_description
**events
, uint32_t nr_events
, void *priv
)
1565 printf("----------------------------------------------------------\n");
1566 printf("Tracer notified of events %s\n",
1567 notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
? "inserted" : "removed");
1568 for (i
= 0; i
< nr_events
; i
++) {
1569 struct side_event_description
*event
= events
[i
];
1571 /* Skip NULL pointers */
1574 printf("provider: %s, event: %s\n",
1575 event
->provider_name
, event
->event_name
);
1576 if (notif
== SIDE_TRACER_NOTIFICATION_INSERT_EVENTS
) {
1577 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1578 ret
= side_tracer_callback_variadic_register(event
, tracer_call_variadic
, NULL
);
1582 ret
= side_tracer_callback_register(event
, tracer_call
, NULL
);
1587 if (event
->flags
& SIDE_EVENT_FLAG_VARIADIC
) {
1588 ret
= side_tracer_callback_variadic_unregister(event
, tracer_call_variadic
, NULL
);
1592 ret
= side_tracer_callback_unregister(event
, tracer_call
, NULL
);
1598 printf("----------------------------------------------------------\n");
1601 static __attribute__((constructor
))
1602 void tracer_init(void);
1604 void tracer_init(void)
1606 tracer_handle
= side_tracer_event_notification_register(tracer_event_notification
, NULL
);
1611 static __attribute__((destructor
))
1612 void tracer_exit(void);
1614 void tracer_exit(void)
1616 side_tracer_event_notification_unregister(tracer_handle
);