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
);
87 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
92 sec_type
= bt_ctf_field_get_type(sec
);
94 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
99 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
100 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
105 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
114 int get_stream_event_context_unsigned_int_field_value(FILE *err
,
115 struct bt_ctf_event
*event
, const char *field_name
,
119 struct bt_ctf_field
*field
= NULL
;
120 struct bt_ctf_field_type
*field_type
= NULL
;
122 field
= get_stream_event_context_field(err
, event
, field_name
);
124 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
129 field_type
= bt_ctf_field_get_type(field
);
131 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
136 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
137 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
142 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
143 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
148 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
160 int get_stream_event_context_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
161 const char *field_name
, int64_t *value
)
163 struct bt_ctf_field
*field
= NULL
;
164 struct bt_ctf_field_type
*field_type
= NULL
;
167 field
= get_stream_event_context_field(err
, event
, field_name
);
172 field_type
= bt_ctf_field_get_type(field
);
174 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
179 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
180 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
185 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
186 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
191 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
203 int get_payload_unsigned_int_field_value(FILE *err
,
204 struct bt_ctf_event
*event
, const char *field_name
,
207 struct bt_ctf_field
*field
= NULL
;
208 struct bt_ctf_field_type
*field_type
= NULL
;
211 field
= get_payload_field(err
, event
, field_name
);
213 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
218 field_type
= bt_ctf_field_get_type(field
);
220 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
225 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
226 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
231 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
232 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
237 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
249 int get_payload_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
250 const char *field_name
, int64_t *value
)
252 struct bt_ctf_field
*field
= NULL
;
253 struct bt_ctf_field_type
*field_type
= NULL
;
256 field
= get_payload_field(err
, event
, field_name
);
258 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
263 field_type
= bt_ctf_field_get_type(field
);
265 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
270 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
271 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
276 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
277 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
282 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
294 int get_payload_string_field_value(FILE *err
,
295 struct bt_ctf_event
*event
, const char *field_name
,
298 struct bt_ctf_field
*field
= NULL
;
299 struct bt_ctf_field_type
*field_type
= NULL
;
302 field
= get_payload_field(err
, event
, field_name
);
304 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
309 field_type
= bt_ctf_field_get_type(field
);
311 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
316 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_STRING
) {
317 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
322 *value
= bt_ctf_field_string_get_value(field
);
324 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
341 int get_payload_build_id_field_value(FILE *err
,
342 struct bt_ctf_event
*event
, const char *field_name
,
343 uint8_t **build_id
, uint64_t *build_id_len
)
345 struct bt_ctf_field
*field
= NULL
, *seq_len
= NULL
;
346 struct bt_ctf_field_type
*field_type
= NULL
;
347 struct bt_ctf_field
*seq_field
= NULL
;
353 field
= get_payload_field(err
, event
, field_name
);
355 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
360 field_type
= bt_ctf_field_get_type(field
);
362 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
367 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
368 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
374 seq_len
= bt_ctf_field_sequence_get_length(field
);
376 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
381 ret
= bt_ctf_field_unsigned_integer_get_value(seq_len
, build_id_len
);
383 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
389 *build_id
= g_new0(uint8_t, *build_id_len
);
391 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
396 for (i
= 0; i
< *build_id_len
; i
++) {
399 seq_field
= bt_ctf_field_sequence_get_field(field
, i
);
401 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
406 ret
= bt_ctf_field_unsigned_integer_get_value(seq_field
, &tmp
);
408 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
413 (*build_id
)[i
] = (uint8_t) tmp
;
428 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
429 struct bt_ctf_trace
*writer_trace
)
431 return (struct debug_info
*) g_hash_table_lookup(
432 debug_it
->trace_debug_map
,
433 (gpointer
) writer_trace
);
437 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
438 struct bt_ctf_trace
*writer_trace
)
440 struct debug_info
*debug_info
= NULL
;
441 struct bt_value
*field
= NULL
;
442 const char *str_value
;
443 enum bt_value_status ret
;
445 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
447 /* No domain field, no debug info */
451 ret
= bt_value_string_get(field
, &str_value
);
452 if (ret
!= BT_VALUE_STATUS_OK
) {
453 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
457 /* Domain not ust, no debug info */
458 if (strcmp(str_value
, "ust") != 0) {
463 /* No tracer_name, no debug info */
464 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
466 /* No tracer_name, no debug info */
470 ret
= bt_value_string_get(field
, &str_value
);
471 if (ret
!= BT_VALUE_STATUS_OK
) {
472 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
476 /* Tracer_name not lttng-ust, no debug info */
477 if (strcmp(str_value
, "lttng-ust") != 0) {
482 debug_info
= debug_info_create(debug_it
->debug_info_component
);
484 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
489 g_hash_table_insert(debug_it
->trace_debug_map
, (gpointer
) writer_trace
,
498 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
499 struct bt_ctf_trace
*writer_trace
)
501 struct debug_info
*debug_info
;
503 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
);
508 debug_info
= insert_new_debug_info(debug_it
, writer_trace
);
515 struct bt_ctf_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
516 struct bt_ctf_trace
*trace
)
518 return (struct bt_ctf_trace
*) g_hash_table_lookup(
524 struct bt_ctf_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
525 struct bt_ctf_trace
*trace
) {
526 struct bt_ctf_trace
*writer_trace
= NULL
;
529 writer_trace
= bt_ctf_trace_create();
531 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
535 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, writer_trace
);
537 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
538 if (ret
!= BT_COMPONENT_STATUS_OK
) {
539 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
547 BT_PUT(writer_trace
);
553 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
554 struct bt_ctf_packet
*packet
)
556 return (struct bt_ctf_packet
*) g_hash_table_lookup(
557 debug_it
->packet_map
,
562 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
563 struct bt_ctf_packet
*packet
,
564 struct bt_ctf_stream
*writer_stream
)
566 struct bt_ctf_packet
*writer_packet
;
568 writer_packet
= bt_ctf_packet_create(writer_stream
);
569 if (!writer_packet
) {
570 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
574 g_hash_table_insert(debug_it
->packet_map
, (gpointer
) packet
, writer_packet
);
577 return writer_packet
;
581 int add_debug_info_fields(FILE *err
,
582 struct bt_ctf_field_type
*writer_event_context_type
,
583 struct debug_info_component
*component
)
585 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
586 *bin_field_type
= NULL
, *func_field_type
= NULL
,
587 *src_field_type
= NULL
;
590 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
591 writer_event_context_type
, "_ip");
592 /* No ip field, so no debug info. */
598 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
599 writer_event_context_type
,
600 component
->arg_debug_info_field_name
);
601 /* Already existing debug_info field, no need to add it. */
602 if (debug_field_type
) {
606 debug_field_type
= bt_ctf_field_type_structure_create();
607 if (!debug_field_type
) {
608 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
613 bin_field_type
= bt_ctf_field_type_string_create();
614 if (!bin_field_type
) {
615 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
620 func_field_type
= bt_ctf_field_type_string_create();
621 if (!func_field_type
) {
622 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
627 src_field_type
= bt_ctf_field_type_string_create();
628 if (!src_field_type
) {
629 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
634 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
635 bin_field_type
, "bin");
637 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
642 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
643 func_field_type
, "func");
645 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
650 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
651 src_field_type
, "src");
653 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
658 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
659 debug_field_type
, component
->arg_debug_info_field_name
);
661 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
670 BT_PUT(debug_field_type
);
673 bt_put(src_field_type
);
674 bt_put(func_field_type
);
675 bt_put(bin_field_type
);
676 bt_put(debug_field_type
);
681 int create_debug_info_event_context_type(FILE *err
,
682 struct bt_ctf_field_type
*event_context_type
,
683 struct bt_ctf_field_type
*writer_event_context_type
,
684 struct debug_info_component
*component
)
686 int ret
, nr_fields
, i
;
688 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
689 for (i
= 0; i
< nr_fields
; i
++) {
690 struct bt_ctf_field_type
*field_type
= NULL
;
691 const char *field_name
;
693 if (bt_ctf_field_type_structure_get_field(event_context_type
,
694 &field_name
, &field_type
, i
) < 0) {
695 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
700 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
701 field_type
, field_name
);
704 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
710 ret
= add_debug_info_fields(err
, writer_event_context_type
,
721 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
722 struct bt_ctf_stream_class
*stream_class
,
723 struct bt_ctf_trace
*writer_trace
,
724 struct debug_info_component
*component
)
726 struct bt_ctf_field_type
*type
= NULL
;
727 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
728 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
730 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
732 if (strlen(name
) == 0) {
736 writer_stream_class
= bt_ctf_stream_class_create(name
);
737 if (!writer_stream_class
) {
738 fprintf(err
, "[error] %s in %s:%d\n",
739 __func__
, __FILE__
, __LINE__
);
743 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
745 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
750 ret_int
= bt_ctf_stream_class_set_packet_context_type(
751 writer_stream_class
, type
);
753 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
759 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
761 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
766 ret_int
= bt_ctf_stream_class_set_event_header_type(
767 writer_stream_class
, type
);
769 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
775 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
777 writer_event_context_type
= bt_ctf_field_type_structure_create();
778 if (!writer_event_context_type
) {
779 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
783 ret_int
= create_debug_info_event_context_type(err
, type
,
784 writer_event_context_type
, component
);
786 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
792 ret_int
= bt_ctf_stream_class_set_event_context_type(
793 writer_stream_class
, writer_event_context_type
);
795 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
799 BT_PUT(writer_event_context_type
);
805 BT_PUT(writer_stream_class
);
807 bt_put(writer_event_context_type
);
809 return writer_stream_class
;
813 * Add the original clock classes to the new trace, we do not need to copy
814 * them, and if we did, we would have to manually inspect the stream class
815 * to update the integers mapping to a clock.
818 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
819 struct bt_ctf_stream_class
*writer_stream_class
,
820 struct bt_ctf_trace
*trace
)
822 int ret
, clock_class_count
, i
;
824 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
826 for (i
= 0; i
< clock_class_count
; i
++) {
827 struct bt_ctf_clock_class
*clock_class
=
828 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
831 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
836 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
839 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
856 struct bt_ctf_stream_class
*insert_new_stream_class(
857 struct debug_info_iterator
*debug_it
,
858 struct bt_ctf_stream_class
*stream_class
)
860 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
861 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
862 enum bt_component_status ret
;
865 trace
= bt_ctf_stream_class_get_trace(stream_class
);
867 fprintf(debug_it
->err
,
868 "[error] %s in %s:%d\n", __func__
, __FILE__
,
873 writer_trace
= lookup_trace(debug_it
, trace
);
875 writer_trace
= insert_new_trace(debug_it
, trace
);
877 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
879 ret
= BT_COMPONENT_STATUS_ERROR
;
883 bt_get(writer_trace
);
885 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
886 writer_trace
, debug_it
->debug_info_component
);
887 if (!writer_stream_class
) {
888 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
889 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
890 __func__
, __FILE__
, __LINE__
);
894 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
896 fprintf(debug_it
->err
,
897 "[error] %s in %s:%d\n", __func__
, __FILE__
,
902 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
903 writer_stream_class
, trace
);
904 if (ret
!= BT_COMPONENT_STATUS_OK
) {
905 fprintf(debug_it
->err
,
906 "[error] %s in %s:%d\n", __func__
, __FILE__
,
910 BT_PUT(writer_trace
);
913 g_hash_table_insert(debug_it
->stream_class_map
,
914 (gpointer
) stream_class
, writer_stream_class
);
919 BT_PUT(writer_stream_class
);
922 bt_put(writer_trace
);
923 return writer_stream_class
;
927 struct bt_ctf_stream
*insert_new_stream(
928 struct debug_info_iterator
*debug_it
,
929 struct bt_ctf_stream_class
*stream_class
,
930 struct bt_ctf_stream
*stream
)
932 struct bt_ctf_stream
*writer_stream
= NULL
;
933 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
935 writer_stream_class
= g_hash_table_lookup(
936 debug_it
->stream_class_map
,
937 (gpointer
) stream_class
);
939 if (!writer_stream_class
) {
940 writer_stream_class
= insert_new_stream_class(debug_it
,
942 if (!writer_stream_class
) {
943 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
944 __func__
, __FILE__
, __LINE__
);
948 bt_get(writer_stream_class
);
950 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
951 bt_ctf_stream_get_name(stream
));
952 if (!writer_stream
) {
953 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
954 __func__
, __FILE__
, __LINE__
);
958 g_hash_table_insert(debug_it
->stream_map
, (gpointer
) stream
,
964 BT_PUT(writer_stream
);
966 bt_put(writer_stream_class
);
967 return writer_stream
;
971 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
972 struct bt_ctf_stream
*stream
)
974 return (struct bt_ctf_stream
*) g_hash_table_lookup(
975 debug_it
->stream_map
,
980 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
981 struct bt_ctf_stream_class
*writer_stream_class
,
982 struct bt_ctf_event_class
*event_class
)
984 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
985 bt_ctf_event_class_get_id(event_class
));
989 struct bt_ctf_stream
*get_writer_stream(
990 struct debug_info_iterator
*debug_it
,
991 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
993 struct bt_ctf_stream_class
*stream_class
= NULL
;
994 struct bt_ctf_stream
*writer_stream
= NULL
;
996 stream_class
= bt_ctf_stream_get_class(stream
);
998 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
999 __func__
, __FILE__
, __LINE__
);
1003 writer_stream
= lookup_stream(debug_it
, stream
);
1004 if (!writer_stream
) {
1005 writer_stream
= insert_new_stream(debug_it
, stream_class
, stream
);
1007 bt_get(writer_stream
);
1012 BT_PUT(writer_stream
);
1014 bt_put(stream_class
);
1015 return writer_stream
;
1019 struct bt_ctf_packet
*debug_info_new_packet(
1020 struct debug_info_iterator
*debug_it
,
1021 struct bt_ctf_packet
*packet
)
1023 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1024 struct bt_ctf_field
*writer_packet_context
= NULL
;
1025 struct bt_ctf_packet
*writer_packet
= NULL
;
1028 stream
= bt_ctf_packet_get_stream(packet
);
1030 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1031 __func__
, __FILE__
, __LINE__
);
1035 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1036 if (!writer_stream
) {
1037 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1038 __func__
, __FILE__
, __LINE__
);
1043 * If a packet was already opened, close it and remove it from
1046 writer_packet
= lookup_packet(debug_it
, packet
);
1047 if (writer_packet
) {
1048 g_hash_table_remove(debug_it
->packet_map
, packet
);
1049 BT_PUT(writer_packet
);
1052 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
);
1053 if (!writer_packet
) {
1054 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1055 __func__
, __FILE__
, __LINE__
);
1058 bt_get(writer_packet
);
1060 writer_packet_context
= ctf_copy_packet_context(debug_it
->err
, packet
,
1062 if (!writer_packet_context
) {
1063 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1064 __func__
, __FILE__
, __LINE__
);
1068 int_ret
= bt_ctf_packet_set_context(writer_packet
, writer_packet_context
);
1070 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1071 __func__
, __FILE__
, __LINE__
);
1079 bt_put(writer_packet_context
);
1080 bt_put(writer_stream
);
1082 return writer_packet
;
1086 struct bt_ctf_packet
*debug_info_close_packet(
1087 struct debug_info_iterator
*debug_it
,
1088 struct bt_ctf_packet
*packet
)
1090 struct bt_ctf_packet
*writer_packet
= NULL
;
1092 writer_packet
= lookup_packet(debug_it
, packet
);
1093 if (!writer_packet
) {
1094 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1095 __func__
, __FILE__
, __LINE__
);
1098 g_hash_table_remove(debug_it
->packet_map
, packet
);
1101 return writer_packet
;
1105 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1106 struct bt_ctf_stream
*stream
)
1108 struct bt_ctf_stream
*writer_stream
;
1110 writer_stream
= lookup_stream(debug_it
, stream
);
1111 if (!writer_stream
) {
1112 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1113 __func__
, __FILE__
, __LINE__
);
1116 g_hash_table_remove(debug_it
->stream_map
, stream
);
1119 return writer_stream
;
1123 struct debug_info_source
*lookup_debug_info(FILE *err
,
1124 struct bt_ctf_event
*event
,
1125 struct debug_info
*debug_info
)
1129 struct debug_info_source
*dbg_info_src
= NULL
;
1132 ret
= get_stream_event_context_int_field_value(err
, event
,
1138 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1144 /* Get debug info for this context. */
1145 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1148 return dbg_info_src
;
1152 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1153 struct debug_info_source
*dbg_info_src
,
1154 struct debug_info_component
*component
)
1156 int i
, nr_fields
, ret
;
1157 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1158 struct bt_ctf_field
*field
= NULL
;
1159 struct bt_ctf_field_type
*field_type
= NULL
;
1161 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1162 if (!debug_field_type
) {
1163 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1164 __FILE__
, __LINE__
);
1168 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1169 for (i
= 0; i
< nr_fields
; i
++) {
1170 const char *field_name
;
1172 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1173 &field_name
, &field_type
, i
) < 0) {
1174 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1175 __FILE__
, __LINE__
);
1180 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1181 if (!strcmp(field_name
, "bin")) {
1182 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1183 GString
*tmp
= g_string_new(NULL
);
1185 if (component
->arg_full_path
) {
1186 g_string_printf(tmp
, "%s%s",
1187 dbg_info_src
->bin_path
,
1188 dbg_info_src
->bin_loc
);
1190 g_string_printf(tmp
, "%s%s",
1191 dbg_info_src
->short_bin_path
,
1192 dbg_info_src
->bin_loc
);
1194 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1195 g_string_free(tmp
, true);
1197 ret
= bt_ctf_field_string_set_value(field
, "");
1199 } else if (!strcmp(field_name
, "func")) {
1200 if (dbg_info_src
&& dbg_info_src
->func
) {
1201 ret
= bt_ctf_field_string_set_value(field
,
1202 dbg_info_src
->func
);
1204 ret
= bt_ctf_field_string_set_value(field
, "");
1206 } else if (!strcmp(field_name
, "src")) {
1207 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1208 GString
*tmp
= g_string_new(NULL
);
1210 if (component
->arg_full_path
) {
1211 g_string_printf(tmp
, "%s:%" PRId64
,
1212 dbg_info_src
->src_path
,
1213 dbg_info_src
->line_no
);
1215 g_string_printf(tmp
, "%s:%" PRId64
,
1216 dbg_info_src
->short_src_path
,
1217 dbg_info_src
->line_no
);
1219 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1220 g_string_free(tmp
, true);
1222 ret
= bt_ctf_field_string_set_value(field
, "");
1227 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1228 __FILE__
, __LINE__
);
1240 bt_put(debug_field_type
);
1245 int copy_set_debug_info_stream_event_context(FILE *err
,
1246 struct bt_ctf_field
*event_context
,
1247 struct bt_ctf_event
*event
,
1248 struct bt_ctf_event
*writer_event
,
1249 struct debug_info
*debug_info
,
1250 struct debug_info_component
*component
)
1252 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1253 struct bt_ctf_field
*writer_event_context
= NULL
;
1254 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1255 struct bt_ctf_field_type
*field_type
= NULL
;
1256 struct debug_info_source
*dbg_info_src
;
1257 int ret
, nr_fields
, i
;
1259 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1260 if (!writer_event_context
) {
1261 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1265 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1266 if (!writer_event_context_type
) {
1267 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1268 __FILE__
, __LINE__
);
1273 * If it is not a structure, we did not modify it to add the debug info
1274 * fields, so just assign it as is.
1276 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1277 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1281 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1283 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1284 for (i
= 0; i
< nr_fields
; i
++) {
1285 const char *field_name
;
1287 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1288 &field_name
, &field_type
, i
) < 0) {
1289 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1290 __FILE__
, __LINE__
);
1294 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1296 * The debug_info field, only exists in the writer event or
1297 * if it was set by a earlier pass of the debug_info plugin.
1299 * FIXME: are we replacing an exisiting debug_info struct here ??
1301 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1303 debug_field
= bt_ctf_field_structure_get_field_by_index(
1304 writer_event_context
, i
);
1306 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1307 __FILE__
, __LINE__
);
1310 ret
= set_debug_info_field(err
, debug_field
,
1311 dbg_info_src
, component
);
1313 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1314 __FILE__
, __LINE__
);
1317 BT_PUT(debug_field
);
1319 copy_field
= bt_ctf_field_copy(field
);
1321 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1322 __FILE__
, __LINE__
);
1326 ret
= bt_ctf_field_structure_set_field(writer_event_context
,
1327 field_name
, copy_field
);
1329 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1330 __FILE__
, __LINE__
);
1345 bt_put(writer_event_context_type
);
1346 bt_put(writer_event_context
);
1349 bt_put(debug_field
);
1355 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1356 struct bt_ctf_stream_class
*stream_class
)
1358 struct bt_ctf_trace
*trace
= NULL
;
1359 struct bt_ctf_clock_class
*clock_class
= NULL
;
1361 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1363 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1368 /* FIXME multi-clock? */
1369 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1378 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1380 struct bt_ctf_event_class
*event_class
= NULL
;
1381 struct bt_ctf_stream_class
*stream_class
= NULL
;
1382 struct bt_ctf_clock_class
*clock_class
= NULL
;
1384 event_class
= bt_ctf_event_get_class(event
);
1386 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1391 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1392 if (!stream_class
) {
1393 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1398 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1402 BT_PUT(clock_class
);
1404 bt_put(stream_class
);
1405 bt_put(event_class
);
1410 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1411 struct bt_ctf_event
*writer_event
)
1413 struct bt_ctf_clock_class
*clock_class
= NULL
;
1414 struct bt_ctf_clock_value
*clock_value
= NULL
;
1417 clock_class
= event_get_clock_class(err
, event
);
1419 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1424 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1426 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1432 * We share the same clocks, so we can assign the clock value to the
1435 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1437 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1448 bt_put(clock_class
);
1449 bt_put(clock_value
);
1454 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1455 struct bt_ctf_event_class
*writer_event_class
,
1456 struct debug_info
*debug_info
,
1457 struct debug_info_component
*component
)
1459 struct bt_ctf_event
*writer_event
= NULL
;
1460 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1463 writer_event
= bt_ctf_event_create(writer_event_class
);
1464 if (!writer_event
) {
1465 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1470 ret
= set_event_clock_value(err
, event
, writer_event
);
1472 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1473 __FILE__
, __LINE__
);
1477 field
= bt_ctf_event_get_header(event
);
1479 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1480 __FILE__
, __LINE__
);
1484 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1485 writer_event
, field
);
1487 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1488 __FILE__
, __LINE__
);
1493 /* Optional field, so it can fail silently. */
1494 field
= bt_ctf_event_get_stream_event_context(event
);
1496 ret
= copy_set_debug_info_stream_event_context(err
,
1497 field
, event
, writer_event
, debug_info
,
1500 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1501 __FILE__
, __LINE__
);
1507 /* Optional field, so it can fail silently. */
1508 field
= bt_ctf_event_get_event_context(event
);
1509 copy_field
= bt_ctf_field_copy(field
);
1511 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1513 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1514 __FILE__
, __LINE__
);
1521 field
= bt_ctf_event_get_event_payload(event
);
1523 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1524 __FILE__
, __LINE__
);
1527 copy_field
= bt_ctf_field_copy(field
);
1529 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
1531 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1532 __FILE__
, __LINE__
);
1542 BT_PUT(writer_event
);
1546 return writer_event
;
1550 struct bt_ctf_event
*debug_info_output_event(
1551 struct debug_info_iterator
*debug_it
,
1552 struct bt_ctf_event
*event
)
1554 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
1555 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
1556 struct bt_ctf_event
*writer_event
= NULL
;
1557 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
1558 struct bt_ctf_trace
*writer_trace
= NULL
;
1559 struct debug_info
*debug_info
;
1560 const char *event_name
;
1563 event_class
= bt_ctf_event_get_class(event
);
1565 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1566 __FILE__
, __LINE__
);
1570 event_name
= bt_ctf_event_class_get_name(event_class
);
1572 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1573 __FILE__
, __LINE__
);
1577 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1578 if (!stream_class
) {
1579 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1580 __FILE__
, __LINE__
);
1584 writer_stream_class
= g_hash_table_lookup(
1585 debug_it
->stream_class_map
,
1586 (gpointer
) stream_class
);
1587 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1588 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1589 __FILE__
, __LINE__
);
1593 writer_event_class
= get_event_class(debug_it
,
1594 writer_stream_class
, event_class
);
1595 if (!writer_event_class
) {
1596 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
1598 if (!writer_event_class
) {
1599 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1600 __func__
, __FILE__
, __LINE__
);
1603 int_ret
= bt_ctf_stream_class_add_event_class(
1604 writer_stream_class
, writer_event_class
);
1606 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1607 __func__
, __FILE__
, __LINE__
);
1612 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
1613 if (!writer_trace
) {
1614 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1615 __FILE__
, __LINE__
);
1619 debug_info
= get_trace_debug_info(debug_it
, writer_trace
);
1621 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
1624 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
1625 writer_event_class
, debug_info
,
1626 debug_it
->debug_info_component
);
1627 if (!writer_event
) {
1628 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1629 __FILE__
, __LINE__
);
1630 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
1631 bt_ctf_event_class_get_name(writer_event_class
));
1635 packet
= bt_ctf_event_get_packet(event
);
1637 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1638 __FILE__
, __LINE__
);
1642 writer_packet
= lookup_packet(debug_it
, packet
);
1643 if (!writer_packet
) {
1644 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1645 __FILE__
, __LINE__
);
1648 bt_get(writer_packet
);
1650 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
1652 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1653 __FILE__
, __LINE__
);
1654 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
1655 bt_ctf_event_class_get_name(writer_event_class
));
1659 /* Keep the reference on the writer event */
1663 BT_PUT(writer_event
);
1666 bt_put(writer_trace
);
1667 bt_put(writer_packet
);
1669 bt_put(writer_event_class
);
1670 bt_put(writer_stream_class
);
1671 bt_put(stream_class
);
1672 bt_put(event_class
);
1673 return writer_event
;