4 * Babeltrace Copy Trace Structure
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
8 * Author: Julien Desfossez <jdesfossez@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include <babeltrace/ctf-ir/event.h>
31 #include <babeltrace/ctf-ir/packet.h>
32 #include <babeltrace/ctf-ir/event-class.h>
33 #include <babeltrace/ctf-ir/stream.h>
34 #include <babeltrace/ctf-ir/stream-class.h>
35 #include <babeltrace/ctf-ir/clock-class.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-writer/stream-class.h>
38 #include <babeltrace/ctf-writer/stream.h>
40 #include <ctfcopytrace.h>
41 #include "debug-info.h"
44 struct bt_ctf_field
*get_payload_field(FILE *err
,
45 struct bt_ctf_event
*event
, const char *field_name
)
47 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
48 struct bt_ctf_field_type
*sec_type
= NULL
;
50 sec
= bt_ctf_event_get_payload(event
, NULL
);
52 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
57 sec_type
= bt_ctf_field_get_type(sec
);
59 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
64 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
65 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
70 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
79 struct bt_ctf_field
*get_stream_event_context_field(FILE *err
,
80 struct bt_ctf_event
*event
, const char *field_name
)
82 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
83 struct bt_ctf_field_type
*sec_type
= NULL
;
85 sec
= bt_ctf_event_get_stream_event_context(event
);
90 sec_type
= bt_ctf_field_get_type(sec
);
92 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
97 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
98 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
103 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
112 int get_stream_event_context_unsigned_int_field_value(FILE *err
,
113 struct bt_ctf_event
*event
, const char *field_name
,
117 struct bt_ctf_field
*field
= NULL
;
118 struct bt_ctf_field_type
*field_type
= NULL
;
120 field
= get_stream_event_context_field(err
, event
, field_name
);
125 field_type
= bt_ctf_field_get_type(field
);
127 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
132 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
133 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
138 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
139 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
144 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
156 int get_stream_event_context_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
157 const char *field_name
, int64_t *value
)
159 struct bt_ctf_field
*field
= NULL
;
160 struct bt_ctf_field_type
*field_type
= NULL
;
163 field
= get_stream_event_context_field(err
, event
, field_name
);
168 field_type
= bt_ctf_field_get_type(field
);
170 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
175 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
176 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
181 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
182 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
187 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
199 int get_payload_unsigned_int_field_value(FILE *err
,
200 struct bt_ctf_event
*event
, const char *field_name
,
203 struct bt_ctf_field
*field
= NULL
;
204 struct bt_ctf_field_type
*field_type
= NULL
;
207 field
= get_payload_field(err
, event
, field_name
);
209 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
214 field_type
= bt_ctf_field_get_type(field
);
216 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
221 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
222 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
227 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
228 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
233 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
245 int get_payload_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
246 const char *field_name
, int64_t *value
)
248 struct bt_ctf_field
*field
= NULL
;
249 struct bt_ctf_field_type
*field_type
= NULL
;
252 field
= get_payload_field(err
, event
, field_name
);
254 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
259 field_type
= bt_ctf_field_get_type(field
);
261 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
266 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
267 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
272 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
273 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
278 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
290 int get_payload_string_field_value(FILE *err
,
291 struct bt_ctf_event
*event
, const char *field_name
,
294 struct bt_ctf_field
*field
= NULL
;
295 struct bt_ctf_field_type
*field_type
= NULL
;
299 * The field might not exist, no error here.
301 field
= get_payload_field(err
, event
, field_name
);
306 field_type
= bt_ctf_field_get_type(field
);
308 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
313 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_STRING
) {
314 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
319 *value
= bt_ctf_field_string_get_value(field
);
321 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
338 int get_payload_build_id_field_value(FILE *err
,
339 struct bt_ctf_event
*event
, const char *field_name
,
340 uint8_t **build_id
, uint64_t *build_id_len
)
342 struct bt_ctf_field
*field
= NULL
, *seq_len
= NULL
;
343 struct bt_ctf_field_type
*field_type
= NULL
;
344 struct bt_ctf_field
*seq_field
= NULL
;
350 field
= get_payload_field(err
, event
, field_name
);
352 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
357 field_type
= bt_ctf_field_get_type(field
);
359 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
364 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
365 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
371 seq_len
= bt_ctf_field_sequence_get_length(field
);
373 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
378 ret
= bt_ctf_field_unsigned_integer_get_value(seq_len
, build_id_len
);
380 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
386 *build_id
= g_new0(uint8_t, *build_id_len
);
388 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
393 for (i
= 0; i
< *build_id_len
; i
++) {
396 seq_field
= bt_ctf_field_sequence_get_field(field
, i
);
398 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
403 ret
= bt_ctf_field_unsigned_integer_get_value(seq_field
, &tmp
);
405 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
410 (*build_id
)[i
] = (uint8_t) tmp
;
425 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
426 struct bt_ctf_trace
*writer_trace
)
428 return (struct debug_info
*) g_hash_table_lookup(
429 debug_it
->trace_debug_map
,
430 (gpointer
) writer_trace
);
434 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
435 struct bt_ctf_trace
*writer_trace
)
437 struct debug_info
*debug_info
= NULL
;
438 struct bt_value
*field
= NULL
;
439 const char *str_value
;
440 enum bt_value_status ret
;
442 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
444 /* No domain field, no debug info */
448 ret
= bt_value_string_get(field
, &str_value
);
449 if (ret
!= BT_VALUE_STATUS_OK
) {
450 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
454 /* Domain not ust, no debug info */
455 if (strcmp(str_value
, "ust") != 0) {
460 /* No tracer_name, no debug info */
461 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
463 /* No tracer_name, no debug info */
467 ret
= bt_value_string_get(field
, &str_value
);
468 if (ret
!= BT_VALUE_STATUS_OK
) {
469 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
473 /* Tracer_name not lttng-ust, no debug info */
474 if (strcmp(str_value
, "lttng-ust") != 0) {
479 debug_info
= debug_info_create(debug_it
->debug_info_component
);
481 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
486 g_hash_table_insert(debug_it
->trace_debug_map
, (gpointer
) writer_trace
,
495 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
496 struct bt_ctf_trace
*writer_trace
)
498 struct debug_info
*debug_info
;
500 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
);
505 debug_info
= insert_new_debug_info(debug_it
, writer_trace
);
512 struct bt_ctf_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
513 struct bt_ctf_trace
*trace
)
515 return (struct bt_ctf_trace
*) g_hash_table_lookup(
521 struct bt_ctf_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
522 struct bt_ctf_trace
*trace
) {
523 struct bt_ctf_trace
*writer_trace
= NULL
;
526 writer_trace
= bt_ctf_trace_create();
528 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
532 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, writer_trace
);
534 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
535 if (ret
!= BT_COMPONENT_STATUS_OK
) {
536 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
544 BT_PUT(writer_trace
);
550 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
551 struct bt_ctf_packet
*packet
)
553 return (struct bt_ctf_packet
*) g_hash_table_lookup(
554 debug_it
->packet_map
,
559 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
560 struct bt_ctf_packet
*packet
,
561 struct bt_ctf_stream
*writer_stream
)
563 struct bt_ctf_packet
*writer_packet
;
565 writer_packet
= bt_ctf_packet_create(writer_stream
);
566 if (!writer_packet
) {
567 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
571 g_hash_table_insert(debug_it
->packet_map
, (gpointer
) packet
, writer_packet
);
574 return writer_packet
;
578 int add_debug_info_fields(FILE *err
,
579 struct bt_ctf_field_type
*writer_event_context_type
,
580 struct debug_info_component
*component
)
582 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
583 *bin_field_type
= NULL
, *func_field_type
= NULL
,
584 *src_field_type
= NULL
;
587 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
588 writer_event_context_type
, "_ip");
589 /* No ip field, so no debug info. */
595 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
596 writer_event_context_type
,
597 component
->arg_debug_info_field_name
);
598 /* Already existing debug_info field, no need to add it. */
599 if (debug_field_type
) {
603 debug_field_type
= bt_ctf_field_type_structure_create();
604 if (!debug_field_type
) {
605 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
610 bin_field_type
= bt_ctf_field_type_string_create();
611 if (!bin_field_type
) {
612 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
617 func_field_type
= bt_ctf_field_type_string_create();
618 if (!func_field_type
) {
619 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
624 src_field_type
= bt_ctf_field_type_string_create();
625 if (!src_field_type
) {
626 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
631 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
632 bin_field_type
, "bin");
634 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
639 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
640 func_field_type
, "func");
642 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
647 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
648 src_field_type
, "src");
650 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
655 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
656 debug_field_type
, component
->arg_debug_info_field_name
);
658 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
667 BT_PUT(debug_field_type
);
670 bt_put(src_field_type
);
671 bt_put(func_field_type
);
672 bt_put(bin_field_type
);
673 bt_put(debug_field_type
);
678 int create_debug_info_event_context_type(FILE *err
,
679 struct bt_ctf_field_type
*event_context_type
,
680 struct bt_ctf_field_type
*writer_event_context_type
,
681 struct debug_info_component
*component
)
683 int ret
, nr_fields
, i
;
685 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
686 for (i
= 0; i
< nr_fields
; i
++) {
687 struct bt_ctf_field_type
*field_type
= NULL
;
688 const char *field_name
;
690 if (bt_ctf_field_type_structure_get_field(event_context_type
,
691 &field_name
, &field_type
, i
) < 0) {
692 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
697 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
698 field_type
, field_name
);
701 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
707 ret
= add_debug_info_fields(err
, writer_event_context_type
,
718 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
719 struct bt_ctf_stream_class
*stream_class
,
720 struct bt_ctf_trace
*writer_trace
,
721 struct debug_info_component
*component
)
723 struct bt_ctf_field_type
*type
= NULL
;
724 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
725 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
727 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
729 if (strlen(name
) == 0) {
733 writer_stream_class
= bt_ctf_stream_class_create(name
);
734 if (!writer_stream_class
) {
735 fprintf(err
, "[error] %s in %s:%d\n",
736 __func__
, __FILE__
, __LINE__
);
740 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
742 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
747 ret_int
= bt_ctf_stream_class_set_packet_context_type(
748 writer_stream_class
, type
);
750 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
756 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
758 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
763 ret_int
= bt_ctf_stream_class_set_event_header_type(
764 writer_stream_class
, type
);
766 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
772 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
774 writer_event_context_type
= bt_ctf_field_type_structure_create();
775 if (!writer_event_context_type
) {
776 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
780 ret_int
= create_debug_info_event_context_type(err
, type
,
781 writer_event_context_type
, component
);
783 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
789 ret_int
= bt_ctf_stream_class_set_event_context_type(
790 writer_stream_class
, writer_event_context_type
);
792 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
796 BT_PUT(writer_event_context_type
);
802 BT_PUT(writer_stream_class
);
804 bt_put(writer_event_context_type
);
806 return writer_stream_class
;
810 * Add the original clock classes to the new trace, we do not need to copy
811 * them, and if we did, we would have to manually inspect the stream class
812 * to update the integers mapping to a clock.
815 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
816 struct bt_ctf_stream_class
*writer_stream_class
,
817 struct bt_ctf_trace
*trace
)
819 int ret
, clock_class_count
, i
;
821 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
823 for (i
= 0; i
< clock_class_count
; i
++) {
824 struct bt_ctf_clock_class
*clock_class
=
825 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
828 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
833 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
836 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
853 struct bt_ctf_stream_class
*insert_new_stream_class(
854 struct debug_info_iterator
*debug_it
,
855 struct bt_ctf_stream_class
*stream_class
)
857 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
858 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
859 enum bt_component_status ret
;
862 trace
= bt_ctf_stream_class_get_trace(stream_class
);
864 fprintf(debug_it
->err
,
865 "[error] %s in %s:%d\n", __func__
, __FILE__
,
870 writer_trace
= lookup_trace(debug_it
, trace
);
872 writer_trace
= insert_new_trace(debug_it
, trace
);
874 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
876 ret
= BT_COMPONENT_STATUS_ERROR
;
880 bt_get(writer_trace
);
882 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
883 writer_trace
, debug_it
->debug_info_component
);
884 if (!writer_stream_class
) {
885 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
886 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
887 __func__
, __FILE__
, __LINE__
);
891 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
893 fprintf(debug_it
->err
,
894 "[error] %s in %s:%d\n", __func__
, __FILE__
,
899 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
900 writer_stream_class
, trace
);
901 if (ret
!= BT_COMPONENT_STATUS_OK
) {
902 fprintf(debug_it
->err
,
903 "[error] %s in %s:%d\n", __func__
, __FILE__
,
907 BT_PUT(writer_trace
);
910 g_hash_table_insert(debug_it
->stream_class_map
,
911 (gpointer
) stream_class
, writer_stream_class
);
916 BT_PUT(writer_stream_class
);
919 bt_put(writer_trace
);
920 return writer_stream_class
;
924 struct bt_ctf_stream
*insert_new_stream(
925 struct debug_info_iterator
*debug_it
,
926 struct bt_ctf_stream_class
*stream_class
,
927 struct bt_ctf_stream
*stream
)
929 struct bt_ctf_stream
*writer_stream
= NULL
;
930 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
932 writer_stream_class
= g_hash_table_lookup(
933 debug_it
->stream_class_map
,
934 (gpointer
) stream_class
);
936 if (!writer_stream_class
) {
937 writer_stream_class
= insert_new_stream_class(debug_it
,
939 if (!writer_stream_class
) {
940 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
941 __func__
, __FILE__
, __LINE__
);
945 bt_get(writer_stream_class
);
947 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
948 bt_ctf_stream_get_name(stream
));
949 if (!writer_stream
) {
950 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
951 __func__
, __FILE__
, __LINE__
);
955 g_hash_table_insert(debug_it
->stream_map
, (gpointer
) stream
,
961 BT_PUT(writer_stream
);
963 bt_put(writer_stream_class
);
964 return writer_stream
;
968 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
969 struct bt_ctf_stream
*stream
)
971 return (struct bt_ctf_stream
*) g_hash_table_lookup(
972 debug_it
->stream_map
,
977 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
978 struct bt_ctf_stream_class
*writer_stream_class
,
979 struct bt_ctf_event_class
*event_class
)
981 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
982 bt_ctf_event_class_get_id(event_class
));
986 struct bt_ctf_stream
*get_writer_stream(
987 struct debug_info_iterator
*debug_it
,
988 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
990 struct bt_ctf_stream_class
*stream_class
= NULL
;
991 struct bt_ctf_stream
*writer_stream
= NULL
;
993 stream_class
= bt_ctf_stream_get_class(stream
);
995 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
996 __func__
, __FILE__
, __LINE__
);
1000 writer_stream
= lookup_stream(debug_it
, stream
);
1001 if (!writer_stream
) {
1002 writer_stream
= insert_new_stream(debug_it
, stream_class
, stream
);
1004 bt_get(writer_stream
);
1009 BT_PUT(writer_stream
);
1011 bt_put(stream_class
);
1012 return writer_stream
;
1016 struct bt_ctf_packet
*debug_info_new_packet(
1017 struct debug_info_iterator
*debug_it
,
1018 struct bt_ctf_packet
*packet
)
1020 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1021 struct bt_ctf_field
*writer_packet_context
= NULL
;
1022 struct bt_ctf_packet
*writer_packet
= NULL
;
1025 stream
= bt_ctf_packet_get_stream(packet
);
1027 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1028 __func__
, __FILE__
, __LINE__
);
1032 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1033 if (!writer_stream
) {
1034 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1035 __func__
, __FILE__
, __LINE__
);
1040 * If a packet was already opened, close it and remove it from
1043 writer_packet
= lookup_packet(debug_it
, packet
);
1044 if (writer_packet
) {
1045 g_hash_table_remove(debug_it
->packet_map
, packet
);
1046 BT_PUT(writer_packet
);
1049 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
);
1050 if (!writer_packet
) {
1051 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1052 __func__
, __FILE__
, __LINE__
);
1056 writer_packet_context
= ctf_copy_packet_context(debug_it
->err
, packet
,
1058 if (!writer_packet_context
) {
1059 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1060 __func__
, __FILE__
, __LINE__
);
1064 int_ret
= bt_ctf_packet_set_context(writer_packet
, writer_packet_context
);
1066 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1067 __func__
, __FILE__
, __LINE__
);
1075 bt_put(writer_packet_context
);
1076 bt_put(writer_stream
);
1078 return writer_packet
;
1082 struct bt_ctf_packet
*debug_info_close_packet(
1083 struct debug_info_iterator
*debug_it
,
1084 struct bt_ctf_packet
*packet
)
1086 struct bt_ctf_packet
*writer_packet
= NULL
;
1088 writer_packet
= lookup_packet(debug_it
, packet
);
1089 if (!writer_packet
) {
1090 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1091 __func__
, __FILE__
, __LINE__
);
1094 g_hash_table_remove(debug_it
->packet_map
, packet
);
1097 return writer_packet
;
1101 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1102 struct bt_ctf_stream
*stream
)
1104 struct bt_ctf_stream
*writer_stream
;
1106 writer_stream
= lookup_stream(debug_it
, stream
);
1107 if (!writer_stream
) {
1108 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1109 __func__
, __FILE__
, __LINE__
);
1112 bt_get(writer_stream
);
1113 g_hash_table_remove(debug_it
->stream_map
, stream
);
1116 return writer_stream
;
1120 struct debug_info_source
*lookup_debug_info(FILE *err
,
1121 struct bt_ctf_event
*event
,
1122 struct debug_info
*debug_info
)
1126 struct debug_info_source
*dbg_info_src
= NULL
;
1129 ret
= get_stream_event_context_int_field_value(err
, event
,
1135 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1141 /* Get debug info for this context. */
1142 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1145 return dbg_info_src
;
1149 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1150 struct debug_info_source
*dbg_info_src
,
1151 struct debug_info_component
*component
)
1153 int i
, nr_fields
, ret
= 0;
1154 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1155 struct bt_ctf_field
*field
= NULL
;
1156 struct bt_ctf_field_type
*field_type
= NULL
;
1158 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1159 if (!debug_field_type
) {
1160 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1161 __FILE__
, __LINE__
);
1165 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1166 for (i
= 0; i
< nr_fields
; i
++) {
1167 const char *field_name
;
1169 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1170 &field_name
, &field_type
, i
) < 0) {
1171 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1172 __FILE__
, __LINE__
);
1177 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1178 if (!strcmp(field_name
, "bin")) {
1179 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1180 GString
*tmp
= g_string_new(NULL
);
1182 if (component
->arg_full_path
) {
1183 g_string_printf(tmp
, "%s%s",
1184 dbg_info_src
->bin_path
,
1185 dbg_info_src
->bin_loc
);
1187 g_string_printf(tmp
, "%s%s",
1188 dbg_info_src
->short_bin_path
,
1189 dbg_info_src
->bin_loc
);
1191 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1192 g_string_free(tmp
, true);
1194 ret
= bt_ctf_field_string_set_value(field
, "");
1196 } else if (!strcmp(field_name
, "func")) {
1197 if (dbg_info_src
&& dbg_info_src
->func
) {
1198 ret
= bt_ctf_field_string_set_value(field
,
1199 dbg_info_src
->func
);
1201 ret
= bt_ctf_field_string_set_value(field
, "");
1203 } else if (!strcmp(field_name
, "src")) {
1204 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1205 GString
*tmp
= g_string_new(NULL
);
1207 if (component
->arg_full_path
) {
1208 g_string_printf(tmp
, "%s:%" PRId64
,
1209 dbg_info_src
->src_path
,
1210 dbg_info_src
->line_no
);
1212 g_string_printf(tmp
, "%s:%" PRId64
,
1213 dbg_info_src
->short_src_path
,
1214 dbg_info_src
->line_no
);
1216 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1217 g_string_free(tmp
, true);
1219 ret
= bt_ctf_field_string_set_value(field
, "");
1224 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1225 __FILE__
, __LINE__
);
1237 bt_put(debug_field_type
);
1242 int copy_set_debug_info_stream_event_context(FILE *err
,
1243 struct bt_ctf_field
*event_context
,
1244 struct bt_ctf_event
*event
,
1245 struct bt_ctf_event
*writer_event
,
1246 struct debug_info
*debug_info
,
1247 struct debug_info_component
*component
)
1249 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1250 *event_context_type
= NULL
;
1251 struct bt_ctf_field
*writer_event_context
= NULL
;
1252 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1253 struct bt_ctf_field_type
*field_type
= NULL
;
1254 struct debug_info_source
*dbg_info_src
;
1255 int ret
, nr_fields
, i
;
1257 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1258 if (!writer_event_context
) {
1259 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1263 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1264 if (!writer_event_context_type
) {
1265 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1266 __FILE__
, __LINE__
);
1270 event_context_type
= bt_ctf_field_get_type(event_context
);
1271 if (!event_context_type
) {
1272 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1273 __FILE__
, __LINE__
);
1278 * If it is not a structure, we did not modify it to add the debug info
1279 * fields, so just assign it as is.
1281 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1282 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1286 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1288 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1289 for (i
= 0; i
< nr_fields
; i
++) {
1290 const char *field_name
;
1292 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1293 &field_name
, &field_type
, i
) < 0) {
1294 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1295 __FILE__
, __LINE__
);
1300 * Prevent illegal access in the event_context.
1302 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1303 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1306 * The debug_info field, only exists in the writer event or
1307 * if it was set by a earlier pass of the debug_info plugin.
1309 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1311 debug_field
= bt_ctf_field_structure_get_field_by_index(
1312 writer_event_context
, i
);
1314 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1315 __FILE__
, __LINE__
);
1318 ret
= set_debug_info_field(err
, debug_field
,
1319 dbg_info_src
, component
);
1321 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1322 __FILE__
, __LINE__
);
1325 BT_PUT(debug_field
);
1327 copy_field
= bt_ctf_field_copy(field
);
1329 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1330 __FILE__
, __LINE__
);
1334 ret
= bt_ctf_field_structure_set_field(writer_event_context
,
1335 field_name
, copy_field
);
1337 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1338 __FILE__
, __LINE__
);
1353 bt_put(event_context_type
);
1354 bt_put(writer_event_context_type
);
1355 bt_put(writer_event_context
);
1358 bt_put(debug_field
);
1364 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1365 struct bt_ctf_stream_class
*stream_class
)
1367 struct bt_ctf_trace
*trace
= NULL
;
1368 struct bt_ctf_clock_class
*clock_class
= NULL
;
1370 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1372 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1377 /* FIXME multi-clock? */
1378 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1387 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1389 struct bt_ctf_event_class
*event_class
= NULL
;
1390 struct bt_ctf_stream_class
*stream_class
= NULL
;
1391 struct bt_ctf_clock_class
*clock_class
= NULL
;
1393 event_class
= bt_ctf_event_get_class(event
);
1395 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1400 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1401 if (!stream_class
) {
1402 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1407 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1411 BT_PUT(clock_class
);
1413 bt_put(stream_class
);
1414 bt_put(event_class
);
1419 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1420 struct bt_ctf_event
*writer_event
)
1422 struct bt_ctf_clock_class
*clock_class
= NULL
;
1423 struct bt_ctf_clock_value
*clock_value
= NULL
;
1426 clock_class
= event_get_clock_class(err
, event
);
1428 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1433 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1435 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1441 * We share the same clocks, so we can assign the clock value to the
1444 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1446 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1457 bt_put(clock_class
);
1458 bt_put(clock_value
);
1463 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1464 struct bt_ctf_event_class
*writer_event_class
,
1465 struct debug_info
*debug_info
,
1466 struct debug_info_component
*component
)
1468 struct bt_ctf_event
*writer_event
= NULL
;
1469 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1472 writer_event
= bt_ctf_event_create(writer_event_class
);
1473 if (!writer_event
) {
1474 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1479 ret
= set_event_clock_value(err
, event
, writer_event
);
1481 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1482 __FILE__
, __LINE__
);
1486 /* Optional field, so it can fail silently. */
1487 field
= bt_ctf_event_get_header(event
);
1489 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1490 writer_event
, field
);
1492 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1493 __FILE__
, __LINE__
);
1499 /* Optional field, so it can fail silently. */
1500 field
= bt_ctf_event_get_stream_event_context(event
);
1502 ret
= copy_set_debug_info_stream_event_context(err
,
1503 field
, event
, writer_event
, debug_info
,
1506 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1507 __FILE__
, __LINE__
);
1513 /* Optional field, so it can fail silently. */
1514 field
= bt_ctf_event_get_event_context(event
);
1516 copy_field
= bt_ctf_field_copy(field
);
1518 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1519 __FILE__
, __LINE__
);
1522 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1524 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1525 __FILE__
, __LINE__
);
1532 field
= bt_ctf_event_get_event_payload(event
);
1534 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1535 __FILE__
, __LINE__
);
1538 copy_field
= bt_ctf_field_copy(field
);
1540 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
1542 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1543 __FILE__
, __LINE__
);
1553 BT_PUT(writer_event
);
1557 return writer_event
;
1561 struct bt_ctf_event
*debug_info_output_event(
1562 struct debug_info_iterator
*debug_it
,
1563 struct bt_ctf_event
*event
)
1565 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
1566 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
1567 struct bt_ctf_event
*writer_event
= NULL
;
1568 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
1569 struct bt_ctf_trace
*writer_trace
= NULL
;
1570 struct debug_info
*debug_info
;
1571 const char *event_name
;
1574 event_class
= bt_ctf_event_get_class(event
);
1576 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1577 __FILE__
, __LINE__
);
1581 event_name
= bt_ctf_event_class_get_name(event_class
);
1583 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1584 __FILE__
, __LINE__
);
1588 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1589 if (!stream_class
) {
1590 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1591 __FILE__
, __LINE__
);
1595 writer_stream_class
= g_hash_table_lookup(
1596 debug_it
->stream_class_map
,
1597 (gpointer
) stream_class
);
1598 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1599 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1600 __FILE__
, __LINE__
);
1604 writer_event_class
= get_event_class(debug_it
,
1605 writer_stream_class
, event_class
);
1606 if (!writer_event_class
) {
1607 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
1609 if (!writer_event_class
) {
1610 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1611 __func__
, __FILE__
, __LINE__
);
1614 int_ret
= bt_ctf_stream_class_add_event_class(
1615 writer_stream_class
, writer_event_class
);
1617 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1618 __func__
, __FILE__
, __LINE__
);
1623 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
1624 if (!writer_trace
) {
1625 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1626 __FILE__
, __LINE__
);
1630 debug_info
= get_trace_debug_info(debug_it
, writer_trace
);
1632 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
1635 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
1636 writer_event_class
, debug_info
,
1637 debug_it
->debug_info_component
);
1638 if (!writer_event
) {
1639 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1640 __FILE__
, __LINE__
);
1641 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
1642 bt_ctf_event_class_get_name(writer_event_class
));
1646 packet
= bt_ctf_event_get_packet(event
);
1648 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1649 __FILE__
, __LINE__
);
1653 writer_packet
= lookup_packet(debug_it
, packet
);
1654 if (!writer_packet
) {
1655 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1656 __FILE__
, __LINE__
);
1659 bt_get(writer_packet
);
1661 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
1663 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1664 __FILE__
, __LINE__
);
1665 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
1666 bt_ctf_event_class_get_name(writer_event_class
));
1670 /* Keep the reference on the writer event */
1674 BT_PUT(writer_event
);
1677 bt_put(writer_trace
);
1678 bt_put(writer_packet
);
1680 bt_put(writer_event_class
);
1681 bt_put(writer_stream_class
);
1682 bt_put(stream_class
);
1683 bt_put(event_class
);
1684 return writer_event
;