Make API CTF-agnostic
[babeltrace.git] / lib / lib-logging.c
1 /*
2 * Copyright 2018 Philippe Proulx <pproulx@efficios.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 * SOFTWARE.
21 */
22
23 #define BT_LOG_TAG "LIB-LOGGING"
24
25 #include <stdarg.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <inttypes.h>
30 #include <stdint.h>
31 #include <wchar.h>
32 #include <glib.h>
33 #include <babeltrace/common-internal.h>
34 #include <babeltrace/lib-logging-internal.h>
35 #include <babeltrace/values-internal.h>
36 #include <babeltrace/object-pool-internal.h>
37 #include <babeltrace/ctf-ir/field-types-internal.h>
38 #include <babeltrace/ctf-ir/fields-internal.h>
39 #include <babeltrace/ctf-ir/event-class-internal.h>
40 #include <babeltrace/ctf-ir/event-internal.h>
41 #include <babeltrace/ctf-ir/packet-internal.h>
42 #include <babeltrace/ctf-ir/stream-class-internal.h>
43 #include <babeltrace/ctf-ir/stream-internal.h>
44 #include <babeltrace/ctf-ir/trace-internal.h>
45 #include <babeltrace/ctf-ir/clock-class-internal.h>
46 #include <babeltrace/ctf-ir/clock-value-internal.h>
47 #include <babeltrace/ctf-ir/field-path-internal.h>
48 #include <babeltrace/ctf-ir/utils-internal.h>
49 #include <babeltrace/graph/component-class-internal.h>
50 #include <babeltrace/graph/component-class-sink-colander-internal.h>
51 #include <babeltrace/graph/component-filter-internal.h>
52 #include <babeltrace/graph/component-internal.h>
53 #include <babeltrace/graph/component-sink-internal.h>
54 #include <babeltrace/graph/component-source-internal.h>
55 #include <babeltrace/graph/connection-internal.h>
56 #include <babeltrace/graph/graph-internal.h>
57 #include <babeltrace/graph/notification-event-internal.h>
58 #include <babeltrace/graph/notification-inactivity-internal.h>
59 #include <babeltrace/graph/notification-internal.h>
60 #include <babeltrace/graph/notification-iterator-internal.h>
61 #include <babeltrace/graph/notification-packet-internal.h>
62 #include <babeltrace/graph/notification-stream-internal.h>
63 #include <babeltrace/graph/port-internal.h>
64 #include <babeltrace/plugin/plugin-internal.h>
65 #include <babeltrace/plugin/plugin-so-internal.h>
66
67 #define LIB_LOGGING_BUF_SIZE (4096 * 4)
68
69 static char __thread lib_logging_buf[LIB_LOGGING_BUF_SIZE];
70
71 #define BUF_APPEND(_fmt, ...) \
72 do { \
73 int _count; \
74 size_t _size = LIB_LOGGING_BUF_SIZE - \
75 (size_t) (*buf_ch - lib_logging_buf); \
76 _count = snprintf(*buf_ch, _size, (_fmt), __VA_ARGS__); \
77 BT_ASSERT(_count >= 0); \
78 *buf_ch += MIN(_count, _size); \
79 if (*buf_ch >= lib_logging_buf + LIB_LOGGING_BUF_SIZE - 1) { \
80 return; \
81 } \
82 } while (0)
83
84 #define BUF_APPEND_UUID(_uuid) \
85 do { \
86 BUF_APPEND(", %suuid=", prefix); \
87 format_uuid(buf_ch, (_uuid)); \
88 } while (0)
89
90 #define PRFIELD(_expr) prefix, (_expr)
91
92 #define SET_TMP_PREFIX(_prefix2) \
93 do { \
94 strcpy(tmp_prefix, prefix); \
95 strcat(tmp_prefix, (_prefix2)); \
96 } while (0)
97
98 static inline void format_component(char **buf_ch, bool extended,
99 const char *prefix, struct bt_component *component);
100
101 static inline void format_port(char **buf_ch, bool extended,
102 const char *prefix, struct bt_port *port);
103
104 static inline void format_connection(char **buf_ch, bool extended,
105 const char *prefix, struct bt_connection *connection);
106
107 static inline void format_clock_value(char **buf_ch, bool extended,
108 const char *prefix, struct bt_clock_value *clock_value);
109
110 static inline void format_field_path(char **buf_ch, bool extended,
111 const char *prefix, struct bt_field_path *field_path);
112
113 static inline void format_object(char **buf_ch, bool extended,
114 const char *prefix, struct bt_object *obj)
115 {
116 BUF_APPEND(", %sref-count=%llu", prefix, obj->ref_count);
117 }
118
119 static inline void format_uuid(char **buf_ch, bt_uuid uuid)
120 {
121 BUF_APPEND("\"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\"",
122 (unsigned int) uuid[0],
123 (unsigned int) uuid[1],
124 (unsigned int) uuid[2],
125 (unsigned int) uuid[3],
126 (unsigned int) uuid[4],
127 (unsigned int) uuid[5],
128 (unsigned int) uuid[6],
129 (unsigned int) uuid[7],
130 (unsigned int) uuid[8],
131 (unsigned int) uuid[9],
132 (unsigned int) uuid[10],
133 (unsigned int) uuid[11],
134 (unsigned int) uuid[12],
135 (unsigned int) uuid[13],
136 (unsigned int) uuid[14],
137 (unsigned int) uuid[15]);
138 }
139
140 static inline void format_object_pool(char **buf_ch, bool extended,
141 const char *prefix, struct bt_object_pool *pool)
142 {
143 BUF_APPEND(", %ssize=%zu", PRFIELD(pool->size));
144
145 if (pool->objects) {
146 BUF_APPEND(", %scap=%u", PRFIELD(pool->objects->len));
147 }
148 }
149
150 static inline void format_integer_field_type(char **buf_ch,
151 bool extended, const char *prefix,
152 struct bt_field_type *field_type)
153 {
154 struct bt_field_type_integer *int_ft = (void *) field_type;
155
156 BUF_APPEND(", %srange-size=%" PRIu64 ", %sbase=%s",
157 PRFIELD(int_ft->range),
158 PRFIELD(bt_common_field_type_integer_preferred_display_base_string(int_ft->base)));
159 }
160
161 static inline void format_array_field_type(char **buf_ch,
162 bool extended, const char *prefix,
163 struct bt_field_type *field_type)
164 {
165 struct bt_field_type_array *array_ft = (void *) field_type;
166
167 BUF_APPEND(", %selement-ft-addr=%p, %selement-ft-id=%s",
168 PRFIELD(array_ft->element_ft),
169 PRFIELD(bt_common_field_type_id_string(array_ft->element_ft->id)));
170 }
171
172 static inline void format_field_type(char **buf_ch, bool extended,
173 const char *prefix, struct bt_field_type *field_type)
174 {
175 char tmp_prefix[64];
176
177 BUF_APPEND(", %sid=%s",
178 PRFIELD(bt_common_field_type_id_string(field_type->id)));
179
180 if (extended) {
181 BUF_APPEND(", %sis-frozen=%d", PRFIELD(field_type->frozen));
182 BUF_APPEND(", %sis-part-of-trace=%d",
183 PRFIELD(field_type->part_of_trace));
184 } else {
185 return;
186 }
187
188 switch (field_type->id) {
189 case BT_FIELD_TYPE_ID_UNSIGNED_INTEGER:
190 case BT_FIELD_TYPE_ID_SIGNED_INTEGER:
191 {
192 format_integer_field_type(buf_ch, extended, prefix, field_type);
193 break;
194 }
195 case BT_FIELD_TYPE_ID_REAL:
196 {
197 struct bt_field_type_real *real_ft = (void *) field_type;
198
199 BUF_APPEND(", %sis-single-precision=%d",
200 PRFIELD(real_ft->is_single_precision));
201 break;
202 }
203 case BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION:
204 case BT_FIELD_TYPE_ID_SIGNED_ENUMERATION:
205 {
206 struct bt_field_type_enumeration *enum_ft =
207 (void *) field_type;
208
209 format_integer_field_type(buf_ch, extended, prefix, field_type);
210 BUF_APPEND(", %smapping-count=%u",
211 PRFIELD(enum_ft->mappings->len));
212 break;
213 }
214 case BT_FIELD_TYPE_ID_STRUCTURE:
215 {
216 struct bt_field_type_structure *struct_ft =
217 (void *) field_type;
218
219 if (struct_ft->common.named_fts) {
220 BUF_APPEND(", %smember-count=%u",
221 PRFIELD(struct_ft->common.named_fts->len));
222 }
223
224 break;
225 }
226 case BT_FIELD_TYPE_ID_STATIC_ARRAY:
227 {
228 struct bt_field_type_static_array *array_ft =
229 (void *) field_type;
230
231 format_array_field_type(buf_ch, extended, prefix, field_type);
232 BUF_APPEND(", %slength=%" PRIu64, PRFIELD(array_ft->length));
233 break;
234 }
235 case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
236 {
237 struct bt_field_type_dynamic_array *array_ft =
238 (void *) field_type;
239
240 format_array_field_type(buf_ch, extended, prefix, field_type);
241
242 if (array_ft->length_ft) {
243 SET_TMP_PREFIX("length-ft-");
244 format_field_type(buf_ch, extended, tmp_prefix,
245 array_ft->length_ft);
246 }
247
248 if (array_ft->length_field_path) {
249 SET_TMP_PREFIX("length-field-path-");
250 format_field_path(buf_ch, extended, tmp_prefix,
251 array_ft->length_field_path);
252 }
253
254 break;
255 }
256 case BT_FIELD_TYPE_ID_VARIANT:
257 {
258 struct bt_field_type_variant *var_ft = (void *) field_type;
259
260 if (var_ft->common.named_fts) {
261 BUF_APPEND(", %soption-count=%u",
262 PRFIELD(var_ft->common.named_fts->len));
263 }
264
265 if (var_ft->selector_ft) {
266 SET_TMP_PREFIX("selector-ft-");
267 format_field_type(buf_ch, extended, tmp_prefix,
268 var_ft->selector_ft);
269 }
270
271 if (var_ft->selector_field_path) {
272 SET_TMP_PREFIX("selector-field-path-");
273 format_field_path(buf_ch, extended, tmp_prefix,
274 var_ft->selector_field_path);
275 }
276
277 break;
278 }
279 default:
280 break;
281 }
282 }
283
284 static inline void format_field_integer_extended(char **buf_ch,
285 const char *prefix, struct bt_field *field)
286 {
287 struct bt_field_integer *integer = (void *) field;
288 struct bt_field_type_integer *field_type = (void *) field->type;
289 const char *fmt = NULL;
290
291 BT_ASSERT(field_type);
292
293 if (field_type->base == BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL) {
294 fmt = ", %svalue=%" PRIo64;
295 } else if (field_type->base == BT_FIELD_TYPE_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL) {
296 fmt = ", %svalue=%" PRIx64;
297 }
298
299 if (field_type->common.id == BT_FIELD_TYPE_ID_SIGNED_INTEGER ||
300 field_type->common.id == BT_FIELD_TYPE_ID_SIGNED_ENUMERATION) {
301 if (!fmt) {
302 fmt = ", %svalue=%" PRId64;
303 }
304
305 BUF_APPEND(fmt, PRFIELD(integer->value.i));
306 } else {
307 if (!fmt) {
308 fmt = ", %svalue=%" PRIu64;
309 }
310
311 BUF_APPEND(fmt, PRFIELD(integer->value.u));
312 }
313 }
314
315 static inline void format_field(char **buf_ch, bool extended,
316 const char *prefix, struct bt_field *field)
317 {
318 BUF_APPEND(", %sis-set=%d", PRFIELD(field->is_set));
319
320 if (extended) {
321 BUF_APPEND(", %sis-frozen=%d", PRFIELD(field->frozen));
322 }
323
324 BUF_APPEND(", %stype-addr=%p", PRFIELD(field->type));
325
326 if (!field->type) {
327 return;
328 }
329
330 BUF_APPEND(", %stype-id=%s",
331 PRFIELD(bt_common_field_type_id_string(field->type->id)));
332
333 if (!extended || !field->is_set) {
334 return;
335 }
336
337 switch (field->type->id) {
338 case BT_FIELD_TYPE_ID_UNSIGNED_INTEGER:
339 case BT_FIELD_TYPE_ID_SIGNED_INTEGER:
340 case BT_FIELD_TYPE_ID_UNSIGNED_ENUMERATION:
341 case BT_FIELD_TYPE_ID_SIGNED_ENUMERATION:
342 {
343 format_field_integer_extended(buf_ch, prefix, field);
344 break;
345 }
346 case BT_FIELD_TYPE_ID_REAL:
347 {
348 struct bt_field_real *real_field = (void *) field;
349
350 BUF_APPEND(", %svalue=%f", PRFIELD(real_field->value));
351 break;
352 }
353 case BT_FIELD_TYPE_ID_STRING:
354 {
355 struct bt_field_string *str = (void *) field;
356
357 if (str->buf) {
358 BT_ASSERT(str->buf->data);
359 BUF_APPEND(", %spartial-value=\"%.32s\"",
360 PRFIELD(str->buf->data));
361 }
362
363 break;
364 }
365 case BT_FIELD_TYPE_ID_STATIC_ARRAY:
366 case BT_FIELD_TYPE_ID_DYNAMIC_ARRAY:
367 {
368 struct bt_field_array *array_field = (void *) field;
369
370 BUF_APPEND(", %slength=%" PRIu64, PRFIELD(array_field->length));
371
372 if (array_field->fields) {
373 BUF_APPEND(", %sallocated-length=%u",
374 PRFIELD(array_field->fields->len));
375 }
376
377 break;
378 }
379 case BT_FIELD_TYPE_ID_VARIANT:
380 {
381 struct bt_field_variant *var_field = (void *) field;
382
383 BUF_APPEND(", %sselected-field-index=%" PRIu64,
384 PRFIELD(var_field->selected_index));
385 break;
386 }
387 default:
388 break;
389 }
390 }
391
392 static inline void format_field_path(char **buf_ch, bool extended,
393 const char *prefix, struct bt_field_path *field_path)
394 {
395 uint64_t i;
396
397 if (field_path->indexes) {
398 BT_ASSERT(field_path->indexes);
399 BUF_APPEND(", %sindex-count=%u",
400 PRFIELD(field_path->indexes->len));
401 }
402
403 if (!extended || !field_path->indexes) {
404 return;
405 }
406
407 BUF_APPEND(", %spath=[%s",
408 PRFIELD(bt_common_scope_string(field_path->root)));
409
410 for (i = 0; i < field_path->indexes->len; i++) {
411 uint64_t index = bt_field_path_get_index_by_index_inline(
412 field_path, i);
413
414 BUF_APPEND(", %" PRIu64, index);
415 }
416
417 BUF_APPEND("%s", "]");
418 }
419
420 static inline void format_trace(char **buf_ch, bool extended,
421 const char *prefix, struct bt_trace *trace)
422 {
423 char tmp_prefix[64];
424
425 if (trace->name.value) {
426 BUF_APPEND(", %sname=\"%s\"", PRFIELD(trace->name.value));
427 }
428
429 if (!extended) {
430 return;
431 }
432
433 BUF_APPEND(", %sis-frozen=%d", PRFIELD(trace->frozen));
434
435 if (trace->uuid.value) {
436 BUF_APPEND_UUID(trace->uuid.value);
437 }
438
439 if (trace->stream_classes) {
440 BUF_APPEND(", %sstream-class-count=%u",
441 PRFIELD(trace->stream_classes->len));
442 }
443
444 if (trace->streams) {
445 BUF_APPEND(", %sstream-count=%u",
446 PRFIELD(trace->streams->len));
447 }
448
449 BUF_APPEND(", %spacket-header-ft-addr=%p, %sis-static=%d, "
450 "%sassigns-auto-sc-id=%d",
451 PRFIELD(trace->packet_header_ft),
452 PRFIELD(trace->is_static),
453 PRFIELD(trace->assigns_automatic_stream_class_id));
454 SET_TMP_PREFIX("phf-pool-");
455 format_object_pool(buf_ch, extended, prefix,
456 &trace->packet_header_field_pool);
457 }
458
459 static inline void format_stream_class(char **buf_ch, bool extended,
460 const char *prefix, struct bt_stream_class *stream_class)
461 {
462 struct bt_trace *trace;
463 char tmp_prefix[64];
464
465 BUF_APPEND(", %sid=%" PRIu64, PRFIELD(stream_class->id));
466
467 if (stream_class->name.value) {
468 BUF_APPEND(", %sname=\"%s\"",
469 PRFIELD(stream_class->name.value));
470 }
471
472 if (!extended) {
473 return;
474 }
475
476 BUF_APPEND(", %sis-frozen=%d", PRFIELD(stream_class->frozen));
477
478 if (stream_class->event_classes) {
479 BUF_APPEND(", %sevent-class-count=%u",
480 PRFIELD(stream_class->event_classes->len));
481 }
482
483 BUF_APPEND(", %spacket-context-ft-addr=%p, "
484 "%sevent-header-ft-addr=%p, %sevent-common-context-ft-addr=%p",
485 PRFIELD(stream_class->packet_context_ft),
486 PRFIELD(stream_class->event_header_ft),
487 PRFIELD(stream_class->event_common_context_ft));
488 trace = bt_stream_class_borrow_trace_inline(stream_class);
489 if (!trace) {
490 return;
491 }
492
493 BUF_APPEND(", %sassigns-auto-ec-id=%d, %sassigns-auto-stream-id=%d, "
494 "%spackets-have-discarded-ev-counter-snapshot=%d, "
495 "%spackets-have-packet-counter-snapshot=%d, "
496 "%spackets-have-default-begin-cv=%d, "
497 "%spackets-have-default-end-cv=%d",
498 PRFIELD(stream_class->assigns_automatic_event_class_id),
499 PRFIELD(stream_class->assigns_automatic_stream_id),
500 PRFIELD(stream_class->packets_have_discarded_event_counter_snapshot),
501 PRFIELD(stream_class->packets_have_packet_counter_snapshot),
502 PRFIELD(stream_class->packets_have_default_beginning_cv),
503 PRFIELD(stream_class->packets_have_default_end_cv));
504 BUF_APPEND(", %strace-addr=%p", PRFIELD(trace));
505 SET_TMP_PREFIX("trace-");
506 format_trace(buf_ch, false, tmp_prefix, trace);
507 SET_TMP_PREFIX("ehf-pool-");
508 format_object_pool(buf_ch, extended, prefix,
509 &stream_class->event_header_field_pool);
510 SET_TMP_PREFIX("pcf-pool-");
511 format_object_pool(buf_ch, extended, prefix,
512 &stream_class->packet_context_field_pool);
513 }
514
515 static inline void format_event_class(char **buf_ch, bool extended,
516 const char *prefix, struct bt_event_class *event_class)
517 {
518 struct bt_stream_class *stream_class;
519 struct bt_trace *trace;
520 char tmp_prefix[64];
521
522 BUF_APPEND(", %sid=%" PRIu64, PRFIELD(event_class->id));
523
524 if (event_class->name.value) {
525 BUF_APPEND(", %sname=\"%s\"",
526 PRFIELD(event_class->name.value));
527 }
528
529 if (!extended) {
530 return;
531 }
532
533 BUF_APPEND(", %sis-frozen=%d", PRFIELD(event_class->frozen));
534
535 if (event_class->log_level.base.avail) {
536 BUF_APPEND(", %slog-level=%s",
537 PRFIELD(bt_common_event_class_log_level_string(
538 (int) event_class->log_level.value)));
539 }
540
541 if (event_class->emf_uri.value) {
542 BUF_APPEND(", %semf-uri=\"%s\"",
543 PRFIELD(event_class->emf_uri.value));
544 }
545
546 BUF_APPEND(", %sspecific-context-ft-addr=%p, %spayload-ft-addr=%p",
547 PRFIELD(event_class->specific_context_ft),
548 PRFIELD(event_class->payload_ft));
549
550 stream_class = bt_event_class_borrow_stream_class(event_class);
551 if (!stream_class) {
552 return;
553 }
554
555 BUF_APPEND(", %sstream-class-addr=%p", PRFIELD(stream_class));
556 SET_TMP_PREFIX("stream-class-");
557 format_stream_class(buf_ch, false, tmp_prefix, stream_class);
558 trace = bt_stream_class_borrow_trace_inline(stream_class);
559 if (!trace) {
560 return;
561 }
562
563 BUF_APPEND(", %strace-addr=%p", PRFIELD(trace));
564 SET_TMP_PREFIX("trace-");
565 format_trace(buf_ch, false, tmp_prefix, trace);
566 SET_TMP_PREFIX("event-pool-");
567 format_object_pool(buf_ch, extended, prefix, &event_class->event_pool);
568 }
569
570 static inline void format_stream(char **buf_ch, bool extended,
571 const char *prefix, struct bt_stream *stream)
572 {
573 struct bt_stream_class *stream_class;
574 struct bt_trace *trace;
575 char tmp_prefix[64];
576
577 BUF_APPEND(", %sid=%" PRIu64, PRFIELD(stream->id));
578
579 if (stream->name.value) {
580 BUF_APPEND(", %sname=\"%s\"", PRFIELD(stream->name.value));
581 }
582
583 if (!extended) {
584 return;
585 }
586
587 stream_class = bt_stream_borrow_class(stream);
588 if (!stream_class) {
589 return;
590 }
591
592 BUF_APPEND(", %sstream-class-addr=%p", PRFIELD(stream_class));
593 SET_TMP_PREFIX("stream-class-");
594 format_stream_class(buf_ch, false, tmp_prefix, stream_class);
595 trace = bt_stream_class_borrow_trace_inline(stream_class);
596 if (!trace) {
597 return;
598 }
599
600 trace = (void *) bt_object_borrow_parent(&stream->base);
601 if (!trace) {
602 return;
603 }
604
605 BUF_APPEND(", %strace-addr=%p", PRFIELD(trace));
606 SET_TMP_PREFIX("trace-");
607 format_trace(buf_ch, false, tmp_prefix, trace);
608 SET_TMP_PREFIX("packet-pool-");
609 format_object_pool(buf_ch, extended, prefix, &stream->packet_pool);
610 }
611
612 static inline void format_packet(char **buf_ch, bool extended,
613 const char *prefix, struct bt_packet *packet)
614 {
615 struct bt_stream *stream;
616 struct bt_trace *trace;
617 char tmp_prefix[64];
618
619 if (!extended) {
620 return;
621 }
622
623 BUF_APPEND(", %sis-frozen=%d, %sheader-field-addr=%p, "
624 "%scontext-field-addr=%p",
625 PRFIELD(packet->frozen),
626 PRFIELD(packet->header_field ? packet->header_field->field : NULL),
627 PRFIELD(packet->context_field ? packet->context_field->field : NULL));
628 stream = bt_packet_borrow_stream(packet);
629 if (!stream) {
630 return;
631 }
632
633 if (packet->default_beginning_cv) {
634 SET_TMP_PREFIX("default-begin-cv-");
635 format_clock_value(buf_ch, true, tmp_prefix,
636 packet->default_beginning_cv);
637 }
638
639 if (packet->default_end_cv) {
640 SET_TMP_PREFIX("default-end-cv-");
641 format_clock_value(buf_ch, true, tmp_prefix,
642 packet->default_end_cv);
643 }
644
645 if (packet->discarded_event_counter_snapshot.base.avail) {
646 BUF_APPEND(", %sdiscarded-ev-counter-snapshot=%" PRIu64,
647 PRFIELD(packet->discarded_event_counter_snapshot.value));
648 }
649
650 if (packet->packet_counter_snapshot.base.avail) {
651 BUF_APPEND(", %spacket-counter-snapshot=%" PRIu64,
652 PRFIELD(packet->packet_counter_snapshot.value));
653 }
654
655 BUF_APPEND(", %sstream-addr=%p", PRFIELD(stream));
656 SET_TMP_PREFIX("stream-");
657 format_stream(buf_ch, false, tmp_prefix, stream);
658 trace = (struct bt_trace *) bt_object_borrow_parent(&stream->base);
659 if (!trace) {
660 return;
661 }
662
663 BUF_APPEND(", %strace-addr=%p", PRFIELD(trace));
664 SET_TMP_PREFIX("trace-");
665 format_trace(buf_ch, false, tmp_prefix, trace);
666 }
667
668 static inline void format_event(char **buf_ch, bool extended,
669 const char *prefix, struct bt_event *event)
670 {
671 struct bt_packet *packet;
672 struct bt_stream *stream;
673 struct bt_trace *trace;
674 struct bt_stream_class *stream_class;
675 char tmp_prefix[64];
676
677 if (!extended) {
678 return;
679 }
680
681 BUF_APPEND(", %sis-frozen=%d, %sheader-field-addr=%p, "
682 "%scommon-context-field-addr=%p, "
683 "%specific-scontext-field-addr=%p, "
684 "%spayload-field-addr=%p, ",
685 PRFIELD(event->frozen),
686 PRFIELD(event->header_field ?
687 event->header_field->field : NULL),
688 PRFIELD(event->common_context_field),
689 PRFIELD(event->specific_context_field),
690 PRFIELD(event->payload_field));
691 BUF_APPEND(", %sevent-class-addr=%p", PRFIELD(event->class));
692
693 if (!event->class) {
694 return;
695 }
696
697 SET_TMP_PREFIX("event-class-");
698 format_event_class(buf_ch, false, tmp_prefix, event->class);
699 stream_class = bt_event_class_borrow_stream_class(event->class);
700 if (stream_class) {
701 BUF_APPEND(", %sstream-class-addr=%p", PRFIELD(stream_class));
702 SET_TMP_PREFIX("stream-class-");
703 format_stream_class(buf_ch, false, tmp_prefix,
704 stream_class);
705
706 trace = bt_stream_class_borrow_trace_inline(stream_class);
707 if (trace) {
708 BUF_APPEND(", %strace-addr=%p", PRFIELD(trace));
709 SET_TMP_PREFIX("trace-");
710 format_trace(buf_ch, false, tmp_prefix, trace);
711 }
712 }
713
714 if (event->default_cv) {
715 SET_TMP_PREFIX("default-cv-");
716 format_clock_value(buf_ch, true, tmp_prefix,
717 event->default_cv);
718 }
719
720 packet = bt_event_borrow_packet(event);
721 if (!packet) {
722 return;
723 }
724
725 BUF_APPEND(", %spacket-addr=%p", PRFIELD(packet));
726 SET_TMP_PREFIX("packet-");
727 format_packet(buf_ch, false, tmp_prefix, packet);
728 stream = bt_packet_borrow_stream(packet);
729 if (!stream) {
730 return;
731 }
732
733 BUF_APPEND(", %sstream-addr=%p", PRFIELD(stream));
734 SET_TMP_PREFIX("stream-");
735 format_stream(buf_ch, false, tmp_prefix, stream);
736 }
737
738 static inline void format_clock_class(char **buf_ch, bool extended,
739 const char *prefix, struct bt_clock_class *clock_class)
740 {
741 char tmp_prefix[64];
742
743 if (clock_class->name.value) {
744 BUF_APPEND(", %sname=\"%s\"", PRFIELD(clock_class->name.value));
745 }
746
747 BUF_APPEND(", %sfreq=%" PRIu64, PRFIELD(clock_class->frequency));
748
749 if (!extended) {
750 return;
751 }
752
753 if (clock_class->description.value) {
754 BUF_APPEND(", %spartial-descr=\"%.32s\"",
755 PRFIELD(clock_class->description.value));
756 }
757
758 if (clock_class->uuid.value) {
759 BUF_APPEND_UUID(clock_class->uuid.value);
760 }
761
762 BUF_APPEND(", %sis-frozen=%d, %sprecision=%" PRIu64 ", "
763 "%soffset-s=%" PRId64 ", "
764 "%soffset-cycles=%" PRIu64 ", %sis-absolute=%d, "
765 "%sbase-offset-ns=%" PRId64,
766 PRFIELD(clock_class->frozen), PRFIELD(clock_class->precision),
767 PRFIELD(clock_class->offset_seconds),
768 PRFIELD(clock_class->offset_cycles),
769 PRFIELD(clock_class->is_absolute),
770 PRFIELD(clock_class->base_offset.value_ns));
771
772 SET_TMP_PREFIX("cv-pool-");
773 format_object_pool(buf_ch, extended, prefix, &clock_class->cv_pool);
774 }
775
776 static inline void format_clock_value(char **buf_ch, bool extended,
777 const char *prefix, struct bt_clock_value *clock_value)
778 {
779 char tmp_prefix[64];
780 BUF_APPEND(", %svalue=%" PRIu64 ", %sns-from-origin=%" PRId64,
781 PRFIELD(clock_value->value_cycles),
782 PRFIELD(clock_value->ns_from_origin));
783
784 if (!extended) {
785 return;
786 }
787
788 BUF_APPEND(", %sis-set=%d", PRFIELD(clock_value->is_set));
789 BUF_APPEND(", %sclock-class-addr=%p",
790 PRFIELD(clock_value->clock_class));
791 SET_TMP_PREFIX("clock-class-");
792 format_clock_class(buf_ch, false, tmp_prefix, clock_value->clock_class);
793 }
794
795 static inline void format_value(char **buf_ch, bool extended,
796 const char *prefix, struct bt_value *value)
797 {
798 BUF_APPEND(", %stype=%s",
799 PRFIELD(bt_value_type_string(bt_value_get_type(value))));
800
801 if (!extended) {
802 return;
803 }
804
805 switch (bt_value_get_type(value)) {
806 case BT_VALUE_TYPE_BOOL:
807 {
808 bt_bool val;
809
810 (void) bt_value_bool_get(value, &val);
811 BUF_APPEND(", %svalue=%d", PRFIELD(val));
812 break;
813 }
814 case BT_VALUE_TYPE_INTEGER:
815 {
816 int64_t val;
817
818 (void) bt_value_integer_get(value, &val);
819 BUF_APPEND(", %svalue=%" PRId64, PRFIELD(val));
820 break;
821 }
822 case BT_VALUE_TYPE_FLOAT:
823 {
824 double val;
825
826 (void) bt_value_float_get(value, &val);
827 BUF_APPEND(", %svalue=%f", PRFIELD(val));
828 break;
829 }
830 case BT_VALUE_TYPE_STRING:
831 {
832 const char *val;
833
834 (void) bt_value_string_get(value, &val);
835 BUF_APPEND(", %spartial-value=\"%.32s\"", PRFIELD(val));
836 break;
837 }
838 case BT_VALUE_TYPE_ARRAY:
839 {
840 int64_t count = bt_value_array_size(value);
841
842 BT_ASSERT(count >= 0);
843 BUF_APPEND(", %selement-count=%" PRId64, PRFIELD(count));
844 break;
845 }
846 case BT_VALUE_TYPE_MAP:
847 {
848 int64_t count = bt_value_map_size(value);
849
850 BT_ASSERT(count >= 0);
851 BUF_APPEND(", %selement-count=%" PRId64, PRFIELD(count));
852 break;
853 }
854 default:
855 break;
856 }
857 }
858
859 static inline void format_notification(char **buf_ch, bool extended,
860 const char *prefix, struct bt_notification *notif)
861 {
862 char tmp_prefix[64];
863
864 BUF_APPEND(", %stype=%s",
865 PRFIELD(bt_notification_type_string(notif->type)));
866
867 if (!extended) {
868 return;
869 }
870
871 BUF_APPEND(", %sis-frozen=%d, %sgraph-addr=%p",
872 PRFIELD(notif->frozen), PRFIELD(notif->graph));
873
874 switch (notif->type) {
875 case BT_NOTIFICATION_TYPE_EVENT:
876 {
877 struct bt_notification_event *notif_event = (void *) notif;
878
879 SET_TMP_PREFIX("event-");
880 format_event(buf_ch, true, tmp_prefix, notif_event->event);
881 break;
882 }
883 case BT_NOTIFICATION_TYPE_STREAM_BEGIN:
884 {
885 struct bt_notification_stream_begin *notif_stream =
886 (void *) notif;
887
888 SET_TMP_PREFIX("stream-");
889 format_stream(buf_ch, true, tmp_prefix, notif_stream->stream);
890 break;
891 }
892 case BT_NOTIFICATION_TYPE_STREAM_END:
893 {
894 struct bt_notification_stream_end *notif_stream =
895 (void *) notif;
896
897 SET_TMP_PREFIX("stream-");
898 format_stream(buf_ch, true, tmp_prefix, notif_stream->stream);
899 break;
900 }
901 case BT_NOTIFICATION_TYPE_PACKET_BEGIN:
902 {
903 struct bt_notification_packet_begin *notif_packet =
904 (void *) notif;
905
906 SET_TMP_PREFIX("packet-");
907 format_packet(buf_ch, true, tmp_prefix, notif_packet->packet);
908 break;
909 }
910 case BT_NOTIFICATION_TYPE_PACKET_END:
911 {
912 struct bt_notification_packet_end *notif_packet =
913 (void *) notif;
914
915 SET_TMP_PREFIX("packet-");
916 format_packet(buf_ch, true, tmp_prefix, notif_packet->packet);
917 break;
918 }
919 default:
920 break;
921 }
922 }
923
924 static inline void format_plugin_so_shared_lib_handle(char **buf_ch,
925 const char *prefix,
926 struct bt_plugin_so_shared_lib_handle *handle)
927 {
928 BUF_APPEND(", %saddr=%p", PRFIELD(handle));
929
930 if (handle->path) {
931 BUF_APPEND(", %spath=\"%s\"", PRFIELD(handle->path->str));
932 }
933 }
934
935 static inline void format_component_class(char **buf_ch, bool extended,
936 const char *prefix, struct bt_component_class *comp_class)
937 {
938 char tmp_prefix[64];
939
940 BUF_APPEND(", %stype=%s, %sname=\"%s\"",
941 PRFIELD(bt_component_class_type_string(comp_class->type)),
942 PRFIELD(comp_class->name ? comp_class->name->str : NULL));
943
944 if (comp_class->description) {
945 BUF_APPEND(", %spartial-descr=\"%.32s\"",
946 PRFIELD(comp_class->description->str));
947 }
948
949 if (!extended) {
950 return;
951 }
952
953 BUF_APPEND(", %sis-frozen=%d", PRFIELD(comp_class->frozen));
954
955 if (comp_class->so_handle) {
956 SET_TMP_PREFIX("so-handle-");
957 format_plugin_so_shared_lib_handle(buf_ch, tmp_prefix,
958 comp_class->so_handle);
959 }
960 }
961
962 static inline void format_component(char **buf_ch, bool extended,
963 const char *prefix, struct bt_component *component)
964 {
965 char tmp_prefix[64];
966
967 BUF_APPEND(", %sname=\"%s\"", PRFIELD(component->name->str));
968 SET_TMP_PREFIX("class-");
969 format_component_class(buf_ch, extended, tmp_prefix, component->class);
970
971 if (!extended) {
972 return;
973 }
974
975 if (component->input_ports) {
976 BUF_APPEND(", %sinput-port-count=%u",
977 PRFIELD(component->input_ports->len));
978 }
979
980 if (component->output_ports) {
981 BUF_APPEND(", %soutput-port-count=%u",
982 PRFIELD(component->output_ports->len));
983 }
984 }
985
986 static inline void format_port(char **buf_ch, bool extended,
987 const char *prefix, struct bt_port *port)
988 {
989 char tmp_prefix[64];
990
991 BUF_APPEND(", %stype=%s, %sname=\"%s\"",
992 PRFIELD(bt_port_type_string(port->type)),
993 PRFIELD(port->name->str));
994
995 if (!extended) {
996 return;
997 }
998
999 if (port->connection) {
1000 SET_TMP_PREFIX("conn-");
1001 format_connection(buf_ch, false, tmp_prefix, port->connection);
1002 }
1003 }
1004
1005 static inline void format_connection(char **buf_ch, bool extended,
1006 const char *prefix, struct bt_connection *connection)
1007 {
1008 char tmp_prefix[64];
1009
1010 if (!extended) {
1011 return;
1012 }
1013
1014 if (connection->upstream_port) {
1015 SET_TMP_PREFIX("upstream-port-");
1016 format_port(buf_ch, false, tmp_prefix,
1017 connection->upstream_port);
1018 }
1019
1020 if (connection->downstream_port) {
1021 SET_TMP_PREFIX("downstream-port-");
1022 format_port(buf_ch, false, tmp_prefix,
1023 connection->downstream_port);
1024 }
1025 }
1026
1027 static inline void format_graph(char **buf_ch, bool extended,
1028 const char *prefix, struct bt_graph *graph)
1029 {
1030 char tmp_prefix[64];
1031
1032 BUF_APPEND(", %sis-canceled=%d", PRFIELD(graph->canceled));
1033
1034 if (!extended) {
1035 return;
1036 }
1037
1038 if (graph->components) {
1039 BUF_APPEND(", %scomp-count=%u",
1040 PRFIELD(graph->components->len));
1041 }
1042
1043 if (graph->connections) {
1044 BUF_APPEND(", %sconn-count=%u",
1045 PRFIELD(graph->connections->len));
1046 }
1047
1048 SET_TMP_PREFIX("en-pool-");
1049 format_object_pool(buf_ch, extended, prefix,
1050 &graph->event_notif_pool);
1051 SET_TMP_PREFIX("pbn-pool-");
1052 format_object_pool(buf_ch, extended, prefix,
1053 &graph->packet_begin_notif_pool);
1054 SET_TMP_PREFIX("pen-pool-");
1055 format_object_pool(buf_ch, extended, prefix,
1056 &graph->packet_end_notif_pool);
1057 }
1058
1059 static inline void format_notification_iterator(char **buf_ch,
1060 bool extended, const char *prefix,
1061 struct bt_notification_iterator *iterator)
1062 {
1063 const char *type;
1064 char tmp_prefix[64];
1065
1066 if (iterator->type == BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION) {
1067 type = "BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION";
1068 } else if (iterator->type == BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT) {
1069 type = "BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT";
1070 } else {
1071 type = "(unknown)";
1072 }
1073
1074 BUF_APPEND(", %stype=%s", PRFIELD(type));
1075
1076 switch (iterator->type) {
1077 case BT_NOTIFICATION_ITERATOR_TYPE_PRIVATE_CONNECTION:
1078 {
1079 struct bt_notification_iterator_private_connection *
1080 iter_priv_conn = (void *) iterator;
1081
1082 if (iter_priv_conn->upstream_component) {
1083 SET_TMP_PREFIX("upstream-comp-");
1084 format_component(buf_ch, false, tmp_prefix,
1085 iter_priv_conn->upstream_component);
1086 }
1087
1088 if (iter_priv_conn->upstream_port) {
1089 SET_TMP_PREFIX("upstream-port-");
1090 format_port(buf_ch, false, tmp_prefix,
1091 iter_priv_conn->upstream_port);
1092 }
1093
1094 if (iter_priv_conn->connection) {
1095 SET_TMP_PREFIX("upstream-conn-");
1096 format_connection(buf_ch, false, tmp_prefix,
1097 iter_priv_conn->connection);
1098 }
1099 break;
1100 }
1101 case BT_NOTIFICATION_ITERATOR_TYPE_OUTPUT_PORT:
1102 {
1103 struct bt_notification_iterator_output_port *iter_output_port =
1104 (void *) iterator;
1105
1106 SET_TMP_PREFIX("graph-");
1107 format_graph(buf_ch, false, tmp_prefix,
1108 iter_output_port->graph);
1109 SET_TMP_PREFIX("colander-comp-");
1110 format_component(buf_ch, false, tmp_prefix,
1111 iter_output_port->colander);
1112 break;
1113 }
1114 default:
1115 break;
1116 }
1117 }
1118
1119 static inline void format_plugin(char **buf_ch, bool extended,
1120 const char *prefix, struct bt_plugin *plugin)
1121 {
1122 char tmp_prefix[64];
1123
1124 BUF_APPEND(", %stype=%s", PRFIELD(bt_plugin_type_string(plugin->type)));
1125
1126 if (plugin->info.path_set) {
1127 BUF_APPEND(", %spath=\"%s\"",
1128 PRFIELD(plugin->info.path->str));
1129 }
1130
1131 if (plugin->info.name_set) {
1132 BUF_APPEND(", %sname=\"%s\"",
1133 PRFIELD(plugin->info.name->str));
1134 }
1135
1136 if (!extended) {
1137 return;
1138 }
1139
1140 if (plugin->info.author_set) {
1141 BUF_APPEND(", %sauthor=\"%s\"",
1142 PRFIELD(plugin->info.author->str));
1143 }
1144
1145 if (plugin->info.license_set) {
1146 BUF_APPEND(", %slicense=\"%s\"",
1147 PRFIELD(plugin->info.license->str));
1148 }
1149
1150 if (plugin->info.version_set) {
1151 BUF_APPEND(", %sversion=%u.%u.%u%s",
1152 PRFIELD(plugin->info.version.major),
1153 plugin->info.version.minor,
1154 plugin->info.version.patch,
1155 plugin->info.version.extra ?
1156 plugin->info.version.extra->str : "");
1157 }
1158
1159 BUF_APPEND(", %sis-frozen=%d, %scomp-class-count=%u",
1160 PRFIELD(plugin->frozen),
1161 PRFIELD(plugin->comp_classes->len));
1162
1163 if (plugin->spec_data) {
1164 struct bt_plugin_so_spec_data *spec_data =
1165 (void *) plugin->spec_data;
1166
1167 if (spec_data->shared_lib_handle) {
1168 SET_TMP_PREFIX("so-handle-");
1169 format_plugin_so_shared_lib_handle(buf_ch, tmp_prefix,
1170 spec_data->shared_lib_handle);
1171 }
1172 }
1173 }
1174
1175 static inline void handle_conversion_specifier_bt(void *priv_data,
1176 char **buf_ch, size_t avail_size,
1177 const char **out_fmt_ch, va_list *args)
1178 {
1179 const char *fmt_ch = *out_fmt_ch;
1180 bool extended = false;
1181 char prefix[64];
1182 char *prefix_ch = prefix;
1183 void *obj;
1184
1185 /* skip "%!" */
1186 fmt_ch += 2;
1187
1188 if (*fmt_ch == 'u') {
1189 /* UUID */
1190 obj = va_arg(*args, void *);
1191 format_uuid(buf_ch, obj);
1192 goto update_fmt;
1193 }
1194
1195 if (*fmt_ch == '[') {
1196 /* local prefix */
1197 fmt_ch++;
1198
1199 while (true) {
1200 if (*fmt_ch == ']') {
1201 *prefix_ch = '\0';
1202 fmt_ch++;
1203 break;
1204 }
1205
1206 *prefix_ch = *fmt_ch;
1207 prefix_ch++;
1208 fmt_ch++;
1209 }
1210 }
1211
1212 *prefix_ch = '\0';
1213
1214 if (*fmt_ch == '+') {
1215 extended = true;
1216 fmt_ch++;
1217 }
1218
1219 obj = va_arg(*args, void *);
1220 BUF_APPEND("%saddr=%p", prefix, obj);
1221
1222 if (!obj) {
1223 goto update_fmt;
1224 }
1225
1226 switch (*fmt_ch) {
1227 case 'F':
1228 format_field_type(buf_ch, extended, prefix, obj);
1229 break;
1230 case 'f':
1231 format_field(buf_ch, extended, prefix, obj);
1232 break;
1233 case 'P':
1234 format_field_path(buf_ch, extended, prefix, obj);
1235 break;
1236 case 'E':
1237 format_event_class(buf_ch, extended, prefix, obj);
1238 break;
1239 case 'e':
1240 format_event(buf_ch, extended, prefix, obj);
1241 break;
1242 case 'S':
1243 format_stream_class(buf_ch, extended, prefix, obj);
1244 break;
1245 case 's':
1246 format_stream(buf_ch, extended, prefix, obj);
1247 break;
1248 case 'a':
1249 format_packet(buf_ch, extended, prefix, obj);
1250 break;
1251 case 't':
1252 format_trace(buf_ch, extended, prefix, obj);
1253 break;
1254 case 'K':
1255 format_clock_class(buf_ch, extended, prefix, obj);
1256 break;
1257 case 'k':
1258 format_clock_value(buf_ch, extended, prefix, obj);
1259 break;
1260 case 'v':
1261 format_value(buf_ch, extended, prefix, obj);
1262 break;
1263 case 'n':
1264 format_notification(buf_ch, extended, prefix, obj);
1265 break;
1266 case 'i':
1267 format_notification_iterator(buf_ch, extended, prefix, obj);
1268 break;
1269 case 'C':
1270 format_component_class(buf_ch, extended, prefix, obj);
1271 break;
1272 case 'c':
1273 format_component(buf_ch, extended, prefix, obj);
1274 break;
1275 case 'p':
1276 format_port(buf_ch, extended, prefix, obj);
1277 break;
1278 case 'x':
1279 format_connection(buf_ch, extended, prefix, obj);
1280 break;
1281 case 'l':
1282 format_plugin(buf_ch, extended, prefix, obj);
1283 break;
1284 case 'g':
1285 format_graph(buf_ch, extended, prefix, obj);
1286 break;
1287 case 'o':
1288 format_object_pool(buf_ch, extended, prefix, obj);
1289 break;
1290 case 'O':
1291 format_object(buf_ch, extended, prefix, obj);
1292 break;
1293 default:
1294 abort();
1295 }
1296
1297 update_fmt:
1298 fmt_ch++;
1299 *out_fmt_ch = fmt_ch;
1300 }
1301
1302 BT_HIDDEN
1303 void bt_lib_log(const char *func, const char *file, unsigned line,
1304 int lvl, const char *tag, const char *fmt, ...)
1305 {
1306 va_list args;
1307
1308 BT_ASSERT(fmt);
1309 va_start(args, fmt);
1310 bt_common_custom_vsnprintf(lib_logging_buf, LIB_LOGGING_BUF_SIZE, '!',
1311 handle_conversion_specifier_bt, NULL, fmt, &args);
1312 va_end(args);
1313 _bt_log_write_d(func, file, line, lvl, tag, "%s", lib_logging_buf);
1314 }
This page took 0.061665 seconds and 4 git commands to generate.