1 // SPDX-License-Identifier: MIT
3 * Copyright 2022 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11 #include <side/trace.h>
14 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
16 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
18 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
);
20 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
);
22 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
24 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
);
26 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*dynamic_item
);
29 void print_attributes(const char *prefix_str
, const struct side_attr
*attr
, uint32_t nr_attr
)
35 printf("%s[ ", prefix_str
);
36 for (i
= 0; i
< nr_attr
; i
++) {
37 printf("%s", i
? ", " : "");
38 printf("{ key: \"%s\", value: \"%s\" }",
39 attr
[i
].key
, attr
[i
].value
);
45 void tracer_print_type(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
48 case SIDE_TYPE_ARRAY_U8
:
49 case SIDE_TYPE_ARRAY_U16
:
50 case SIDE_TYPE_ARRAY_U32
:
51 case SIDE_TYPE_ARRAY_U64
:
52 case SIDE_TYPE_ARRAY_S8
:
53 case SIDE_TYPE_ARRAY_S16
:
54 case SIDE_TYPE_ARRAY_S32
:
55 case SIDE_TYPE_ARRAY_S64
:
56 if (type_desc
->type
!= SIDE_TYPE_ARRAY
) {
57 printf("ERROR: type mismatch between description and arguments\n");
61 case SIDE_TYPE_VLA_U8
:
62 case SIDE_TYPE_VLA_U16
:
63 case SIDE_TYPE_VLA_U32
:
64 case SIDE_TYPE_VLA_U64
:
65 case SIDE_TYPE_VLA_S8
:
66 case SIDE_TYPE_VLA_S16
:
67 case SIDE_TYPE_VLA_S32
:
68 case SIDE_TYPE_VLA_S64
:
69 if (type_desc
->type
!= SIDE_TYPE_VLA
) {
70 printf("ERROR: type mismatch between description and arguments\n");
76 if (type_desc
->type
!= item
->type
) {
77 printf("ERROR: type mismatch between description and arguments\n");
83 print_attributes("attr: ", type_desc
->attr
, type_desc
->nr_attr
);
84 printf("%s", type_desc
->nr_attr
? ", " : "");
88 printf("%s", item
->u
.side_bool
? "true" : "false");
91 printf("%" PRIu8
, item
->u
.side_u8
);
94 printf("%" PRIu16
, item
->u
.side_u16
);
97 printf("%" PRIu32
, item
->u
.side_u32
);
100 printf("%" PRIu64
, item
->u
.side_u64
);
103 printf("%" PRId8
, item
->u
.side_s8
);
106 printf("%" PRId16
, item
->u
.side_s16
);
109 printf("%" PRId32
, item
->u
.side_s32
);
112 printf("%" PRId64
, item
->u
.side_s64
);
114 case SIDE_TYPE_STRING
:
115 printf("\"%s\"", item
->u
.string
);
117 case SIDE_TYPE_STRUCT
:
118 tracer_print_struct(type_desc
, item
->u
.side_struct
);
120 case SIDE_TYPE_ARRAY
:
121 tracer_print_array(type_desc
, item
->u
.side_array
);
124 tracer_print_vla(type_desc
, item
->u
.side_vla
);
126 case SIDE_TYPE_VLA_VISITOR
:
127 tracer_print_vla_visitor(type_desc
, item
->u
.side_vla_app_visitor_ctx
);
129 case SIDE_TYPE_ARRAY_U8
:
130 case SIDE_TYPE_ARRAY_U16
:
131 case SIDE_TYPE_ARRAY_U32
:
132 case SIDE_TYPE_ARRAY_U64
:
133 case SIDE_TYPE_ARRAY_S8
:
134 case SIDE_TYPE_ARRAY_S16
:
135 case SIDE_TYPE_ARRAY_S32
:
136 case SIDE_TYPE_ARRAY_S64
:
137 tracer_print_array_fixint(type_desc
, item
);
139 case SIDE_TYPE_VLA_U8
:
140 case SIDE_TYPE_VLA_U16
:
141 case SIDE_TYPE_VLA_U32
:
142 case SIDE_TYPE_VLA_U64
:
143 case SIDE_TYPE_VLA_S8
:
144 case SIDE_TYPE_VLA_S16
:
145 case SIDE_TYPE_VLA_S32
:
146 case SIDE_TYPE_VLA_S64
:
147 tracer_print_vla_fixint(type_desc
, item
);
149 case SIDE_TYPE_DYNAMIC
:
150 tracer_print_dynamic(&item
->u
.dynamic
);
153 printf("<UNKNOWN TYPE>");
160 void tracer_print_field(const struct side_event_field
*item_desc
, const struct side_arg_vec
*item
)
162 printf("%s: ", item_desc
->field_name
);
163 tracer_print_type(&item_desc
->side_type
, item
);
167 void tracer_print_struct(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
169 const struct side_arg_vec
*sav
= sav_desc
->sav
;
170 uint32_t side_sav_len
= sav_desc
->len
;
173 if (type_desc
->u
.side_struct
.nr_fields
!= side_sav_len
) {
174 printf("ERROR: number of fields mismatch between description and arguments of structure\n");
178 for (i
= 0; i
< side_sav_len
; i
++) {
179 printf("%s", i
? ", " : "");
180 tracer_print_field(&type_desc
->u
.side_struct
.fields
[i
], &sav
[i
]);
186 void tracer_print_array(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
188 const struct side_arg_vec
*sav
= sav_desc
->sav
;
189 uint32_t side_sav_len
= sav_desc
->len
;
192 if (type_desc
->u
.side_array
.length
!= side_sav_len
) {
193 printf("ERROR: length mismatch between description and arguments of array\n");
197 for (i
= 0; i
< side_sav_len
; i
++) {
198 printf("%s", i
? ", " : "");
199 tracer_print_type(type_desc
->u
.side_array
.elem_type
, &sav
[i
]);
205 void tracer_print_vla(const struct side_type_description
*type_desc
, const struct side_arg_vec_description
*sav_desc
)
207 const struct side_arg_vec
*sav
= sav_desc
->sav
;
208 uint32_t side_sav_len
= sav_desc
->len
;
212 for (i
= 0; i
< side_sav_len
; i
++) {
213 printf("%s", i
? ", " : "");
214 tracer_print_type(type_desc
->u
.side_vla
.elem_type
, &sav
[i
]);
219 struct tracer_visitor_priv
{
220 const struct side_type_description
*elem_type
;
225 enum side_visitor_status
tracer_write_elem_cb(const struct side_tracer_visitor_ctx
*tracer_ctx
,
226 const struct side_arg_vec
*elem
)
228 struct tracer_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
230 printf("%s", tracer_priv
->i
++ ? ", " : "");
231 tracer_print_type(tracer_priv
->elem_type
, elem
);
232 return SIDE_VISITOR_STATUS_OK
;
236 void tracer_print_vla_visitor(const struct side_type_description
*type_desc
, void *app_ctx
)
238 enum side_visitor_status status
;
239 struct tracer_visitor_priv tracer_priv
= {
240 .elem_type
= type_desc
->u
.side_vla_visitor
.elem_type
,
243 const struct side_tracer_visitor_ctx tracer_ctx
= {
244 .write_elem
= tracer_write_elem_cb
,
245 .priv
= &tracer_priv
,
249 status
= type_desc
->u
.side_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
251 case SIDE_VISITOR_STATUS_OK
:
253 case SIDE_VISITOR_STATUS_ERROR
:
254 printf("ERROR: Visitor error\n");
260 void tracer_print_array_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
262 const struct side_type_description
*elem_type
= type_desc
->u
.side_array
.elem_type
;
263 uint32_t side_sav_len
= type_desc
->u
.side_array
.length
;
264 void *p
= item
->u
.side_array_fixint
;
265 enum side_type side_type
;
268 switch (item
->type
) {
269 case SIDE_TYPE_ARRAY_U8
:
270 if (elem_type
->type
!= SIDE_TYPE_U8
)
273 case SIDE_TYPE_ARRAY_U16
:
274 if (elem_type
->type
!= SIDE_TYPE_U16
)
277 case SIDE_TYPE_ARRAY_U32
:
278 if (elem_type
->type
!= SIDE_TYPE_U32
)
281 case SIDE_TYPE_ARRAY_U64
:
282 if (elem_type
->type
!= SIDE_TYPE_U64
)
285 case SIDE_TYPE_ARRAY_S8
:
286 if (elem_type
->type
!= SIDE_TYPE_S8
)
289 case SIDE_TYPE_ARRAY_S16
:
290 if (elem_type
->type
!= SIDE_TYPE_S16
)
293 case SIDE_TYPE_ARRAY_S32
:
294 if (elem_type
->type
!= SIDE_TYPE_S32
)
297 case SIDE_TYPE_ARRAY_S64
:
298 if (elem_type
->type
!= SIDE_TYPE_S64
)
304 side_type
= elem_type
->type
;
307 for (i
= 0; i
< side_sav_len
; i
++) {
308 struct side_arg_vec sav_elem
= {
314 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
317 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
320 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
323 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
326 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
329 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
332 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
335 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
339 printf("ERROR: Unexpected type\n");
343 printf("%s", i
? ", " : "");
344 tracer_print_type(elem_type
, &sav_elem
);
350 printf("ERROR: type mismatch\n");
354 void tracer_print_vla_fixint(const struct side_type_description
*type_desc
, const struct side_arg_vec
*item
)
356 const struct side_type_description
*elem_type
= type_desc
->u
.side_vla
.elem_type
;
357 uint32_t side_sav_len
= item
->u
.side_vla_fixint
.length
;
358 void *p
= item
->u
.side_vla_fixint
.p
;
359 enum side_type side_type
;
362 switch (item
->type
) {
363 case SIDE_TYPE_VLA_U8
:
364 if (elem_type
->type
!= SIDE_TYPE_U8
)
367 case SIDE_TYPE_VLA_U16
:
368 if (elem_type
->type
!= SIDE_TYPE_U16
)
371 case SIDE_TYPE_VLA_U32
:
372 if (elem_type
->type
!= SIDE_TYPE_U32
)
375 case SIDE_TYPE_VLA_U64
:
376 if (elem_type
->type
!= SIDE_TYPE_U64
)
379 case SIDE_TYPE_VLA_S8
:
380 if (elem_type
->type
!= SIDE_TYPE_S8
)
383 case SIDE_TYPE_VLA_S16
:
384 if (elem_type
->type
!= SIDE_TYPE_S16
)
387 case SIDE_TYPE_VLA_S32
:
388 if (elem_type
->type
!= SIDE_TYPE_S32
)
391 case SIDE_TYPE_VLA_S64
:
392 if (elem_type
->type
!= SIDE_TYPE_S64
)
398 side_type
= elem_type
->type
;
401 for (i
= 0; i
< side_sav_len
; i
++) {
402 struct side_arg_vec sav_elem
= {
408 sav_elem
.u
.side_u8
= ((const uint8_t *) p
)[i
];
411 sav_elem
.u
.side_s8
= ((const int8_t *) p
)[i
];
414 sav_elem
.u
.side_u16
= ((const uint16_t *) p
)[i
];
417 sav_elem
.u
.side_s16
= ((const int16_t *) p
)[i
];
420 sav_elem
.u
.side_u32
= ((const uint32_t *) p
)[i
];
423 sav_elem
.u
.side_s32
= ((const int32_t *) p
)[i
];
426 sav_elem
.u
.side_u64
= ((const uint64_t *) p
)[i
];
429 sav_elem
.u
.side_s64
= ((const int64_t *) p
)[i
];
433 printf("ERROR: Unexpected type\n");
437 printf("%s", i
? ", " : "");
438 tracer_print_type(elem_type
, &sav_elem
);
444 printf("ERROR: type mismatch\n");
449 void tracer_print_dynamic_struct(const struct side_arg_dynamic_event_struct
*dynamic_struct
)
451 const struct side_arg_dynamic_event_field
*fields
= dynamic_struct
->fields
;
452 uint32_t len
= dynamic_struct
->len
;
456 for (i
= 0; i
< len
; i
++) {
457 printf("%s", i
? ", " : "");
458 printf("%s:: ", fields
[i
].field_name
);
459 tracer_print_dynamic(&fields
[i
].elem
);
464 struct tracer_dynamic_struct_visitor_priv
{
469 enum side_visitor_status
tracer_dynamic_struct_write_elem_cb(
470 const struct side_tracer_dynamic_struct_visitor_ctx
*tracer_ctx
,
471 const struct side_arg_dynamic_event_field
*dynamic_field
)
473 struct tracer_dynamic_struct_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
475 printf("%s", tracer_priv
->i
++ ? ", " : "");
476 printf("%s:: ", dynamic_field
->field_name
);
477 tracer_print_dynamic(&dynamic_field
->elem
);
478 return SIDE_VISITOR_STATUS_OK
;
482 void tracer_print_dynamic_struct_visitor(const struct side_arg_dynamic_vec
*item
)
484 enum side_visitor_status status
;
485 struct tracer_dynamic_struct_visitor_priv tracer_priv
= {
488 const struct side_tracer_dynamic_struct_visitor_ctx tracer_ctx
= {
489 .write_field
= tracer_dynamic_struct_write_elem_cb
,
490 .priv
= &tracer_priv
,
492 void *app_ctx
= item
->u
.side_dynamic_struct_visitor
.app_ctx
;
495 status
= item
->u
.side_dynamic_struct_visitor
.visitor(&tracer_ctx
, app_ctx
);
497 case SIDE_VISITOR_STATUS_OK
:
499 case SIDE_VISITOR_STATUS_ERROR
:
500 printf("ERROR: Visitor error\n");
507 void tracer_print_dynamic_vla(const struct side_arg_dynamic_vec_vla
*vla
)
509 const struct side_arg_dynamic_vec
*sav
= vla
->sav
;
510 uint32_t side_sav_len
= vla
->len
;
514 for (i
= 0; i
< side_sav_len
; i
++) {
515 printf("%s", i
? ", " : "");
516 tracer_print_dynamic(&sav
[i
]);
521 struct tracer_dynamic_vla_visitor_priv
{
526 enum side_visitor_status
tracer_dynamic_vla_write_elem_cb(
527 const struct side_tracer_dynamic_vla_visitor_ctx
*tracer_ctx
,
528 const struct side_arg_dynamic_vec
*elem
)
530 struct tracer_dynamic_vla_visitor_priv
*tracer_priv
= tracer_ctx
->priv
;
532 printf("%s", tracer_priv
->i
++ ? ", " : "");
533 tracer_print_dynamic(elem
);
534 return SIDE_VISITOR_STATUS_OK
;
538 void tracer_print_dynamic_vla_visitor(const struct side_arg_dynamic_vec
*item
)
540 enum side_visitor_status status
;
541 struct tracer_dynamic_vla_visitor_priv tracer_priv
= {
544 const struct side_tracer_dynamic_vla_visitor_ctx tracer_ctx
= {
545 .write_elem
= tracer_dynamic_vla_write_elem_cb
,
546 .priv
= &tracer_priv
,
548 void *app_ctx
= item
->u
.side_dynamic_vla_visitor
.app_ctx
;
551 status
= item
->u
.side_dynamic_vla_visitor
.visitor(&tracer_ctx
, app_ctx
);
553 case SIDE_VISITOR_STATUS_OK
:
555 case SIDE_VISITOR_STATUS_ERROR
:
556 printf("ERROR: Visitor error\n");
563 void tracer_print_dynamic(const struct side_arg_dynamic_vec
*item
)
566 print_attributes("attr: ", item
->attr
, item
->nr_attr
);
567 printf("%s", item
->nr_attr
? ", " : "");
569 switch (item
->dynamic_type
) {
570 case SIDE_DYNAMIC_TYPE_NULL
:
571 printf("<NULL TYPE>");
573 case SIDE_DYNAMIC_TYPE_BOOL
:
574 printf("%s", item
->u
.side_bool
? "true" : "false");
576 case SIDE_DYNAMIC_TYPE_U8
:
577 printf("%" PRIu8
, item
->u
.side_u8
);
579 case SIDE_DYNAMIC_TYPE_U16
:
580 printf("%" PRIu16
, item
->u
.side_u16
);
582 case SIDE_DYNAMIC_TYPE_U32
:
583 printf("%" PRIu32
, item
->u
.side_u32
);
585 case SIDE_DYNAMIC_TYPE_U64
:
586 printf("%" PRIu64
, item
->u
.side_u64
);
588 case SIDE_DYNAMIC_TYPE_S8
:
589 printf("%" PRId8
, item
->u
.side_s8
);
591 case SIDE_DYNAMIC_TYPE_S16
:
592 printf("%" PRId16
, item
->u
.side_s16
);
594 case SIDE_DYNAMIC_TYPE_S32
:
595 printf("%" PRId32
, item
->u
.side_s32
);
597 case SIDE_DYNAMIC_TYPE_S64
:
598 printf("%" PRId64
, item
->u
.side_s64
);
600 case SIDE_DYNAMIC_TYPE_STRING
:
601 printf("\"%s\"", item
->u
.string
);
603 case SIDE_DYNAMIC_TYPE_STRUCT
:
604 tracer_print_dynamic_struct(item
->u
.side_dynamic_struct
);
606 case SIDE_DYNAMIC_TYPE_STRUCT_VISITOR
:
607 tracer_print_dynamic_struct_visitor(item
);
609 case SIDE_DYNAMIC_TYPE_VLA
:
610 tracer_print_dynamic_vla(item
->u
.side_dynamic_vla
);
612 case SIDE_DYNAMIC_TYPE_VLA_VISITOR
:
613 tracer_print_dynamic_vla_visitor(item
);
616 printf("<UNKNOWN TYPE>");
623 void tracer_print_static_fields(const struct side_event_description
*desc
,
624 const struct side_arg_vec_description
*sav_desc
,
627 const struct side_arg_vec
*sav
= sav_desc
->sav
;
628 uint32_t side_sav_len
= sav_desc
->len
;
631 printf("provider: %s, event: %s", desc
->provider_name
, desc
->event_name
);
632 if (desc
->nr_fields
!= side_sav_len
) {
633 printf("ERROR: number of fields mismatch between description and arguments\n");
636 print_attributes(", attributes: ", desc
->attr
, desc
->nr_attr
);
637 printf("%s", side_sav_len
? ", fields: [ " : "");
638 for (i
= 0; i
< side_sav_len
; i
++) {
639 printf("%s", i
? ", " : "");
640 tracer_print_field(&desc
->fields
[i
], &sav
[i
]);
646 void tracer_call(const struct side_event_description
*desc
, const struct side_arg_vec_description
*sav_desc
)
650 if (side_unlikely(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
)) {
651 printf("ERROR: unexpected variadic event description\n");
654 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
660 void tracer_call_variadic(const struct side_event_description
*desc
,
661 const struct side_arg_vec_description
*sav_desc
,
662 const struct side_arg_dynamic_event_struct
*var_struct
)
664 uint32_t var_struct_len
= var_struct
->len
;
665 int nr_fields
= 0, i
;
667 tracer_print_static_fields(desc
, sav_desc
, &nr_fields
);
669 if (side_unlikely(!(desc
->flags
& SIDE_EVENT_FLAG_VARIADIC
))) {
670 printf("ERROR: unexpected non-variadic event description\n");
673 printf("%s", var_struct_len
&& !nr_fields
? ", fields: [ " : "");
674 for (i
= 0; i
< var_struct_len
; i
++, nr_fields
++) {
675 printf("%s", nr_fields
? ", " : "");
676 printf("%s:: ", var_struct
->fields
[i
].field_name
);
677 tracer_print_dynamic(&var_struct
->fields
[i
].elem
);