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__
);
1059 writer_packet_context
= ctf_copy_packet_context(debug_it
->err
, packet
,
1061 if (!writer_packet_context
) {
1062 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1063 __func__
, __FILE__
, __LINE__
);
1067 int_ret
= bt_ctf_packet_set_context(writer_packet
, writer_packet_context
);
1069 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1070 __func__
, __FILE__
, __LINE__
);
1078 bt_put(writer_packet_context
);
1079 bt_put(writer_stream
);
1081 return writer_packet
;
1085 struct bt_ctf_packet
*debug_info_close_packet(
1086 struct debug_info_iterator
*debug_it
,
1087 struct bt_ctf_packet
*packet
)
1089 struct bt_ctf_packet
*writer_packet
= NULL
;
1091 writer_packet
= lookup_packet(debug_it
, packet
);
1092 if (!writer_packet
) {
1093 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1094 __func__
, __FILE__
, __LINE__
);
1097 g_hash_table_remove(debug_it
->packet_map
, packet
);
1100 return writer_packet
;
1104 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1105 struct bt_ctf_stream
*stream
)
1107 struct bt_ctf_stream
*writer_stream
;
1109 writer_stream
= lookup_stream(debug_it
, stream
);
1110 if (!writer_stream
) {
1111 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1112 __func__
, __FILE__
, __LINE__
);
1115 g_hash_table_remove(debug_it
->stream_map
, stream
);
1118 return writer_stream
;
1122 struct debug_info_source
*lookup_debug_info(FILE *err
,
1123 struct bt_ctf_event
*event
,
1124 struct debug_info
*debug_info
)
1128 struct debug_info_source
*dbg_info_src
= NULL
;
1131 ret
= get_stream_event_context_int_field_value(err
, event
,
1137 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1143 /* Get debug info for this context. */
1144 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1147 return dbg_info_src
;
1151 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1152 struct debug_info_source
*dbg_info_src
,
1153 struct debug_info_component
*component
)
1155 int i
, nr_fields
, ret
;
1156 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1157 struct bt_ctf_field
*field
= NULL
;
1158 struct bt_ctf_field_type
*field_type
= NULL
;
1160 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1161 if (!debug_field_type
) {
1162 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1163 __FILE__
, __LINE__
);
1167 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1168 for (i
= 0; i
< nr_fields
; i
++) {
1169 const char *field_name
;
1171 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1172 &field_name
, &field_type
, i
) < 0) {
1173 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1174 __FILE__
, __LINE__
);
1179 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1180 if (!strcmp(field_name
, "bin")) {
1181 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1182 GString
*tmp
= g_string_new(NULL
);
1184 if (component
->arg_full_path
) {
1185 g_string_printf(tmp
, "%s%s",
1186 dbg_info_src
->bin_path
,
1187 dbg_info_src
->bin_loc
);
1189 g_string_printf(tmp
, "%s%s",
1190 dbg_info_src
->short_bin_path
,
1191 dbg_info_src
->bin_loc
);
1193 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1194 g_string_free(tmp
, true);
1196 ret
= bt_ctf_field_string_set_value(field
, "");
1198 } else if (!strcmp(field_name
, "func")) {
1199 if (dbg_info_src
&& dbg_info_src
->func
) {
1200 ret
= bt_ctf_field_string_set_value(field
,
1201 dbg_info_src
->func
);
1203 ret
= bt_ctf_field_string_set_value(field
, "");
1205 } else if (!strcmp(field_name
, "src")) {
1206 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1207 GString
*tmp
= g_string_new(NULL
);
1209 if (component
->arg_full_path
) {
1210 g_string_printf(tmp
, "%s:%" PRId64
,
1211 dbg_info_src
->src_path
,
1212 dbg_info_src
->line_no
);
1214 g_string_printf(tmp
, "%s:%" PRId64
,
1215 dbg_info_src
->short_src_path
,
1216 dbg_info_src
->line_no
);
1218 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1219 g_string_free(tmp
, true);
1221 ret
= bt_ctf_field_string_set_value(field
, "");
1226 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1227 __FILE__
, __LINE__
);
1239 bt_put(debug_field_type
);
1244 int copy_set_debug_info_stream_event_context(FILE *err
,
1245 struct bt_ctf_field
*event_context
,
1246 struct bt_ctf_event
*event
,
1247 struct bt_ctf_event
*writer_event
,
1248 struct debug_info
*debug_info
,
1249 struct debug_info_component
*component
)
1251 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1252 struct bt_ctf_field
*writer_event_context
= NULL
;
1253 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1254 struct bt_ctf_field_type
*field_type
= NULL
;
1255 struct debug_info_source
*dbg_info_src
;
1256 int ret
, nr_fields
, i
;
1258 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1259 if (!writer_event_context
) {
1260 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1264 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1265 if (!writer_event_context_type
) {
1266 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1267 __FILE__
, __LINE__
);
1272 * If it is not a structure, we did not modify it to add the debug info
1273 * fields, so just assign it as is.
1275 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1276 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1280 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1282 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1283 for (i
= 0; i
< nr_fields
; i
++) {
1284 const char *field_name
;
1286 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1287 &field_name
, &field_type
, i
) < 0) {
1288 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1289 __FILE__
, __LINE__
);
1293 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1295 * The debug_info field, only exists in the writer event or
1296 * if it was set by a earlier pass of the debug_info plugin.
1298 * FIXME: are we replacing an exisiting debug_info struct here ??
1300 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1302 debug_field
= bt_ctf_field_structure_get_field_by_index(
1303 writer_event_context
, i
);
1305 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1306 __FILE__
, __LINE__
);
1309 ret
= set_debug_info_field(err
, debug_field
,
1310 dbg_info_src
, component
);
1312 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1313 __FILE__
, __LINE__
);
1316 BT_PUT(debug_field
);
1318 copy_field
= bt_ctf_field_copy(field
);
1320 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1321 __FILE__
, __LINE__
);
1325 ret
= bt_ctf_field_structure_set_field(writer_event_context
,
1326 field_name
, copy_field
);
1328 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1329 __FILE__
, __LINE__
);
1344 bt_put(writer_event_context_type
);
1345 bt_put(writer_event_context
);
1348 bt_put(debug_field
);
1354 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1355 struct bt_ctf_stream_class
*stream_class
)
1357 struct bt_ctf_trace
*trace
= NULL
;
1358 struct bt_ctf_clock_class
*clock_class
= NULL
;
1360 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1362 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1367 /* FIXME multi-clock? */
1368 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1377 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1379 struct bt_ctf_event_class
*event_class
= NULL
;
1380 struct bt_ctf_stream_class
*stream_class
= NULL
;
1381 struct bt_ctf_clock_class
*clock_class
= NULL
;
1383 event_class
= bt_ctf_event_get_class(event
);
1385 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1390 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1391 if (!stream_class
) {
1392 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1397 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1401 BT_PUT(clock_class
);
1403 bt_put(stream_class
);
1404 bt_put(event_class
);
1409 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1410 struct bt_ctf_event
*writer_event
)
1412 struct bt_ctf_clock_class
*clock_class
= NULL
;
1413 struct bt_ctf_clock_value
*clock_value
= NULL
;
1416 clock_class
= event_get_clock_class(err
, event
);
1418 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1423 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1425 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1431 * We share the same clocks, so we can assign the clock value to the
1434 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1436 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1447 bt_put(clock_class
);
1448 bt_put(clock_value
);
1453 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1454 struct bt_ctf_event_class
*writer_event_class
,
1455 struct debug_info
*debug_info
,
1456 struct debug_info_component
*component
)
1458 struct bt_ctf_event
*writer_event
= NULL
;
1459 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1462 writer_event
= bt_ctf_event_create(writer_event_class
);
1463 if (!writer_event
) {
1464 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1469 ret
= set_event_clock_value(err
, event
, writer_event
);
1471 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1472 __FILE__
, __LINE__
);
1476 /* Optional field, so it can fail silently. */
1477 field
= bt_ctf_event_get_header(event
);
1479 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1480 writer_event
, field
);
1482 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1483 __FILE__
, __LINE__
);
1489 /* Optional field, so it can fail silently. */
1490 field
= bt_ctf_event_get_stream_event_context(event
);
1492 ret
= copy_set_debug_info_stream_event_context(err
,
1493 field
, event
, writer_event
, debug_info
,
1496 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1497 __FILE__
, __LINE__
);
1503 /* Optional field, so it can fail silently. */
1504 field
= bt_ctf_event_get_event_context(event
);
1506 copy_field
= bt_ctf_field_copy(field
);
1508 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1509 __FILE__
, __LINE__
);
1512 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1514 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1515 __FILE__
, __LINE__
);
1522 field
= bt_ctf_event_get_event_payload(event
);
1524 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1525 __FILE__
, __LINE__
);
1528 copy_field
= bt_ctf_field_copy(field
);
1530 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
1532 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1533 __FILE__
, __LINE__
);
1543 BT_PUT(writer_event
);
1547 return writer_event
;
1551 struct bt_ctf_event
*debug_info_output_event(
1552 struct debug_info_iterator
*debug_it
,
1553 struct bt_ctf_event
*event
)
1555 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
1556 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
1557 struct bt_ctf_event
*writer_event
= NULL
;
1558 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
1559 struct bt_ctf_trace
*writer_trace
= NULL
;
1560 struct debug_info
*debug_info
;
1561 const char *event_name
;
1564 event_class
= bt_ctf_event_get_class(event
);
1566 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1567 __FILE__
, __LINE__
);
1571 event_name
= bt_ctf_event_class_get_name(event_class
);
1573 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1574 __FILE__
, __LINE__
);
1578 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1579 if (!stream_class
) {
1580 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1581 __FILE__
, __LINE__
);
1585 writer_stream_class
= g_hash_table_lookup(
1586 debug_it
->stream_class_map
,
1587 (gpointer
) stream_class
);
1588 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1589 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1590 __FILE__
, __LINE__
);
1594 writer_event_class
= get_event_class(debug_it
,
1595 writer_stream_class
, event_class
);
1596 if (!writer_event_class
) {
1597 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
1599 if (!writer_event_class
) {
1600 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1601 __func__
, __FILE__
, __LINE__
);
1604 int_ret
= bt_ctf_stream_class_add_event_class(
1605 writer_stream_class
, writer_event_class
);
1607 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1608 __func__
, __FILE__
, __LINE__
);
1613 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
1614 if (!writer_trace
) {
1615 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1616 __FILE__
, __LINE__
);
1620 debug_info
= get_trace_debug_info(debug_it
, writer_trace
);
1622 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
1625 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
1626 writer_event_class
, debug_info
,
1627 debug_it
->debug_info_component
);
1628 if (!writer_event
) {
1629 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1630 __FILE__
, __LINE__
);
1631 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
1632 bt_ctf_event_class_get_name(writer_event_class
));
1636 packet
= bt_ctf_event_get_packet(event
);
1638 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1639 __FILE__
, __LINE__
);
1643 writer_packet
= lookup_packet(debug_it
, packet
);
1644 if (!writer_packet
) {
1645 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1646 __FILE__
, __LINE__
);
1649 bt_get(writer_packet
);
1651 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
1653 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1654 __FILE__
, __LINE__
);
1655 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
1656 bt_ctf_event_class_get_name(writer_event_class
));
1660 /* Keep the reference on the writer event */
1664 BT_PUT(writer_event
);
1667 bt_put(writer_trace
);
1668 bt_put(writer_packet
);
1670 bt_put(writer_event_class
);
1671 bt_put(writer_stream_class
);
1672 bt_put(stream_class
);
1673 bt_put(event_class
);
1674 return writer_event
;