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
;
298 field
= get_payload_field(err
, event
, field_name
);
300 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
305 field_type
= bt_ctf_field_get_type(field
);
307 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
312 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_STRING
) {
313 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
318 *value
= bt_ctf_field_string_get_value(field
);
320 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
337 int get_payload_build_id_field_value(FILE *err
,
338 struct bt_ctf_event
*event
, const char *field_name
,
339 uint8_t **build_id
, uint64_t *build_id_len
)
341 struct bt_ctf_field
*field
= NULL
, *seq_len
= NULL
;
342 struct bt_ctf_field_type
*field_type
= NULL
;
343 struct bt_ctf_field
*seq_field
= NULL
;
349 field
= get_payload_field(err
, event
, field_name
);
351 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
356 field_type
= bt_ctf_field_get_type(field
);
358 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
363 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
364 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
370 seq_len
= bt_ctf_field_sequence_get_length(field
);
372 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
377 ret
= bt_ctf_field_unsigned_integer_get_value(seq_len
, build_id_len
);
379 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
385 *build_id
= g_new0(uint8_t, *build_id_len
);
387 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
392 for (i
= 0; i
< *build_id_len
; i
++) {
395 seq_field
= bt_ctf_field_sequence_get_field(field
, i
);
397 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
402 ret
= bt_ctf_field_unsigned_integer_get_value(seq_field
, &tmp
);
404 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
409 (*build_id
)[i
] = (uint8_t) tmp
;
424 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
425 struct bt_ctf_trace
*writer_trace
)
427 return (struct debug_info
*) g_hash_table_lookup(
428 debug_it
->trace_debug_map
,
429 (gpointer
) writer_trace
);
433 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
434 struct bt_ctf_trace
*writer_trace
)
436 struct debug_info
*debug_info
= NULL
;
437 struct bt_value
*field
= NULL
;
438 const char *str_value
;
439 enum bt_value_status ret
;
441 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
443 /* No domain field, no debug info */
447 ret
= bt_value_string_get(field
, &str_value
);
448 if (ret
!= BT_VALUE_STATUS_OK
) {
449 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
453 /* Domain not ust, no debug info */
454 if (strcmp(str_value
, "ust") != 0) {
459 /* No tracer_name, no debug info */
460 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
462 /* No tracer_name, no debug info */
466 ret
= bt_value_string_get(field
, &str_value
);
467 if (ret
!= BT_VALUE_STATUS_OK
) {
468 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
472 /* Tracer_name not lttng-ust, no debug info */
473 if (strcmp(str_value
, "lttng-ust") != 0) {
478 debug_info
= debug_info_create(debug_it
->debug_info_component
);
480 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
485 g_hash_table_insert(debug_it
->trace_debug_map
, (gpointer
) writer_trace
,
494 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
495 struct bt_ctf_trace
*writer_trace
)
497 struct debug_info
*debug_info
;
499 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
);
504 debug_info
= insert_new_debug_info(debug_it
, writer_trace
);
511 struct bt_ctf_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
512 struct bt_ctf_trace
*trace
)
514 return (struct bt_ctf_trace
*) g_hash_table_lookup(
520 struct bt_ctf_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
521 struct bt_ctf_trace
*trace
) {
522 struct bt_ctf_trace
*writer_trace
= NULL
;
525 writer_trace
= bt_ctf_trace_create();
527 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
531 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, writer_trace
);
533 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
534 if (ret
!= BT_COMPONENT_STATUS_OK
) {
535 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
543 BT_PUT(writer_trace
);
549 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
550 struct bt_ctf_packet
*packet
)
552 return (struct bt_ctf_packet
*) g_hash_table_lookup(
553 debug_it
->packet_map
,
558 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
559 struct bt_ctf_packet
*packet
,
560 struct bt_ctf_stream
*writer_stream
)
562 struct bt_ctf_packet
*writer_packet
;
564 writer_packet
= bt_ctf_packet_create(writer_stream
);
565 if (!writer_packet
) {
566 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
570 g_hash_table_insert(debug_it
->packet_map
, (gpointer
) packet
, writer_packet
);
573 return writer_packet
;
577 int add_debug_info_fields(FILE *err
,
578 struct bt_ctf_field_type
*writer_event_context_type
,
579 struct debug_info_component
*component
)
581 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
582 *bin_field_type
= NULL
, *func_field_type
= NULL
,
583 *src_field_type
= NULL
;
586 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
587 writer_event_context_type
, "_ip");
588 /* No ip field, so no debug info. */
594 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
595 writer_event_context_type
,
596 component
->arg_debug_info_field_name
);
597 /* Already existing debug_info field, no need to add it. */
598 if (debug_field_type
) {
602 debug_field_type
= bt_ctf_field_type_structure_create();
603 if (!debug_field_type
) {
604 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
609 bin_field_type
= bt_ctf_field_type_string_create();
610 if (!bin_field_type
) {
611 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
616 func_field_type
= bt_ctf_field_type_string_create();
617 if (!func_field_type
) {
618 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
623 src_field_type
= bt_ctf_field_type_string_create();
624 if (!src_field_type
) {
625 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
630 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
631 bin_field_type
, "bin");
633 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
638 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
639 func_field_type
, "func");
641 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
646 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
647 src_field_type
, "src");
649 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
654 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
655 debug_field_type
, component
->arg_debug_info_field_name
);
657 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
666 BT_PUT(debug_field_type
);
669 bt_put(src_field_type
);
670 bt_put(func_field_type
);
671 bt_put(bin_field_type
);
672 bt_put(debug_field_type
);
677 int create_debug_info_event_context_type(FILE *err
,
678 struct bt_ctf_field_type
*event_context_type
,
679 struct bt_ctf_field_type
*writer_event_context_type
,
680 struct debug_info_component
*component
)
682 int ret
, nr_fields
, i
;
684 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
685 for (i
= 0; i
< nr_fields
; i
++) {
686 struct bt_ctf_field_type
*field_type
= NULL
;
687 const char *field_name
;
689 if (bt_ctf_field_type_structure_get_field(event_context_type
,
690 &field_name
, &field_type
, i
) < 0) {
691 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
696 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
697 field_type
, field_name
);
700 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
706 ret
= add_debug_info_fields(err
, writer_event_context_type
,
717 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
718 struct bt_ctf_stream_class
*stream_class
,
719 struct bt_ctf_trace
*writer_trace
,
720 struct debug_info_component
*component
)
722 struct bt_ctf_field_type
*type
= NULL
;
723 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
724 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
726 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
728 if (strlen(name
) == 0) {
732 writer_stream_class
= bt_ctf_stream_class_create(name
);
733 if (!writer_stream_class
) {
734 fprintf(err
, "[error] %s in %s:%d\n",
735 __func__
, __FILE__
, __LINE__
);
739 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
741 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
746 ret_int
= bt_ctf_stream_class_set_packet_context_type(
747 writer_stream_class
, type
);
749 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
755 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
757 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
762 ret_int
= bt_ctf_stream_class_set_event_header_type(
763 writer_stream_class
, type
);
765 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
771 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
773 writer_event_context_type
= bt_ctf_field_type_structure_create();
774 if (!writer_event_context_type
) {
775 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
779 ret_int
= create_debug_info_event_context_type(err
, type
,
780 writer_event_context_type
, component
);
782 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
788 ret_int
= bt_ctf_stream_class_set_event_context_type(
789 writer_stream_class
, writer_event_context_type
);
791 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
795 BT_PUT(writer_event_context_type
);
801 BT_PUT(writer_stream_class
);
803 bt_put(writer_event_context_type
);
805 return writer_stream_class
;
809 * Add the original clock classes to the new trace, we do not need to copy
810 * them, and if we did, we would have to manually inspect the stream class
811 * to update the integers mapping to a clock.
814 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
815 struct bt_ctf_stream_class
*writer_stream_class
,
816 struct bt_ctf_trace
*trace
)
818 int ret
, clock_class_count
, i
;
820 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
822 for (i
= 0; i
< clock_class_count
; i
++) {
823 struct bt_ctf_clock_class
*clock_class
=
824 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
827 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
832 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
835 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
852 struct bt_ctf_stream_class
*insert_new_stream_class(
853 struct debug_info_iterator
*debug_it
,
854 struct bt_ctf_stream_class
*stream_class
)
856 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
857 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
858 enum bt_component_status ret
;
861 trace
= bt_ctf_stream_class_get_trace(stream_class
);
863 fprintf(debug_it
->err
,
864 "[error] %s in %s:%d\n", __func__
, __FILE__
,
869 writer_trace
= lookup_trace(debug_it
, trace
);
871 writer_trace
= insert_new_trace(debug_it
, trace
);
873 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
875 ret
= BT_COMPONENT_STATUS_ERROR
;
879 bt_get(writer_trace
);
881 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
882 writer_trace
, debug_it
->debug_info_component
);
883 if (!writer_stream_class
) {
884 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
885 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
886 __func__
, __FILE__
, __LINE__
);
890 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
892 fprintf(debug_it
->err
,
893 "[error] %s in %s:%d\n", __func__
, __FILE__
,
898 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
899 writer_stream_class
, trace
);
900 if (ret
!= BT_COMPONENT_STATUS_OK
) {
901 fprintf(debug_it
->err
,
902 "[error] %s in %s:%d\n", __func__
, __FILE__
,
906 BT_PUT(writer_trace
);
909 g_hash_table_insert(debug_it
->stream_class_map
,
910 (gpointer
) stream_class
, writer_stream_class
);
915 BT_PUT(writer_stream_class
);
918 bt_put(writer_trace
);
919 return writer_stream_class
;
923 struct bt_ctf_stream
*insert_new_stream(
924 struct debug_info_iterator
*debug_it
,
925 struct bt_ctf_stream_class
*stream_class
,
926 struct bt_ctf_stream
*stream
)
928 struct bt_ctf_stream
*writer_stream
= NULL
;
929 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
931 writer_stream_class
= g_hash_table_lookup(
932 debug_it
->stream_class_map
,
933 (gpointer
) stream_class
);
935 if (!writer_stream_class
) {
936 writer_stream_class
= insert_new_stream_class(debug_it
,
938 if (!writer_stream_class
) {
939 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
940 __func__
, __FILE__
, __LINE__
);
944 bt_get(writer_stream_class
);
946 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
947 bt_ctf_stream_get_name(stream
));
948 if (!writer_stream
) {
949 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
950 __func__
, __FILE__
, __LINE__
);
954 g_hash_table_insert(debug_it
->stream_map
, (gpointer
) stream
,
960 BT_PUT(writer_stream
);
962 bt_put(writer_stream_class
);
963 return writer_stream
;
967 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
968 struct bt_ctf_stream
*stream
)
970 return (struct bt_ctf_stream
*) g_hash_table_lookup(
971 debug_it
->stream_map
,
976 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
977 struct bt_ctf_stream_class
*writer_stream_class
,
978 struct bt_ctf_event_class
*event_class
)
980 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
981 bt_ctf_event_class_get_id(event_class
));
985 struct bt_ctf_stream
*get_writer_stream(
986 struct debug_info_iterator
*debug_it
,
987 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
989 struct bt_ctf_stream_class
*stream_class
= NULL
;
990 struct bt_ctf_stream
*writer_stream
= NULL
;
992 stream_class
= bt_ctf_stream_get_class(stream
);
994 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
995 __func__
, __FILE__
, __LINE__
);
999 writer_stream
= lookup_stream(debug_it
, stream
);
1000 if (!writer_stream
) {
1001 writer_stream
= insert_new_stream(debug_it
, stream_class
, stream
);
1003 bt_get(writer_stream
);
1008 BT_PUT(writer_stream
);
1010 bt_put(stream_class
);
1011 return writer_stream
;
1015 struct bt_ctf_packet
*debug_info_new_packet(
1016 struct debug_info_iterator
*debug_it
,
1017 struct bt_ctf_packet
*packet
)
1019 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1020 struct bt_ctf_field
*writer_packet_context
= NULL
;
1021 struct bt_ctf_packet
*writer_packet
= NULL
;
1024 stream
= bt_ctf_packet_get_stream(packet
);
1026 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1027 __func__
, __FILE__
, __LINE__
);
1031 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1032 if (!writer_stream
) {
1033 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1034 __func__
, __FILE__
, __LINE__
);
1039 * If a packet was already opened, close it and remove it from
1042 writer_packet
= lookup_packet(debug_it
, packet
);
1043 if (writer_packet
) {
1044 g_hash_table_remove(debug_it
->packet_map
, packet
);
1045 BT_PUT(writer_packet
);
1048 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
);
1049 if (!writer_packet
) {
1050 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1051 __func__
, __FILE__
, __LINE__
);
1055 writer_packet_context
= ctf_copy_packet_context(debug_it
->err
, packet
,
1057 if (!writer_packet_context
) {
1058 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1059 __func__
, __FILE__
, __LINE__
);
1063 int_ret
= bt_ctf_packet_set_context(writer_packet
, writer_packet_context
);
1065 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1066 __func__
, __FILE__
, __LINE__
);
1074 bt_put(writer_packet_context
);
1075 bt_put(writer_stream
);
1077 return writer_packet
;
1081 struct bt_ctf_packet
*debug_info_close_packet(
1082 struct debug_info_iterator
*debug_it
,
1083 struct bt_ctf_packet
*packet
)
1085 struct bt_ctf_packet
*writer_packet
= NULL
;
1087 writer_packet
= lookup_packet(debug_it
, packet
);
1088 if (!writer_packet
) {
1089 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1090 __func__
, __FILE__
, __LINE__
);
1093 g_hash_table_remove(debug_it
->packet_map
, packet
);
1096 return writer_packet
;
1100 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1101 struct bt_ctf_stream
*stream
)
1103 struct bt_ctf_stream
*writer_stream
;
1105 writer_stream
= lookup_stream(debug_it
, stream
);
1106 if (!writer_stream
) {
1107 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1108 __func__
, __FILE__
, __LINE__
);
1111 bt_get(writer_stream
);
1112 g_hash_table_remove(debug_it
->stream_map
, stream
);
1115 return writer_stream
;
1119 struct debug_info_source
*lookup_debug_info(FILE *err
,
1120 struct bt_ctf_event
*event
,
1121 struct debug_info
*debug_info
)
1125 struct debug_info_source
*dbg_info_src
= NULL
;
1128 ret
= get_stream_event_context_int_field_value(err
, event
,
1134 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1140 /* Get debug info for this context. */
1141 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1144 return dbg_info_src
;
1148 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1149 struct debug_info_source
*dbg_info_src
,
1150 struct debug_info_component
*component
)
1152 int i
, nr_fields
, ret
= 0;
1153 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1154 struct bt_ctf_field
*field
= NULL
;
1155 struct bt_ctf_field_type
*field_type
= NULL
;
1157 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1158 if (!debug_field_type
) {
1159 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1160 __FILE__
, __LINE__
);
1164 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1165 for (i
= 0; i
< nr_fields
; i
++) {
1166 const char *field_name
;
1168 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1169 &field_name
, &field_type
, i
) < 0) {
1170 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1171 __FILE__
, __LINE__
);
1176 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1177 if (!strcmp(field_name
, "bin")) {
1178 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1179 GString
*tmp
= g_string_new(NULL
);
1181 if (component
->arg_full_path
) {
1182 g_string_printf(tmp
, "%s%s",
1183 dbg_info_src
->bin_path
,
1184 dbg_info_src
->bin_loc
);
1186 g_string_printf(tmp
, "%s%s",
1187 dbg_info_src
->short_bin_path
,
1188 dbg_info_src
->bin_loc
);
1190 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1191 g_string_free(tmp
, true);
1193 ret
= bt_ctf_field_string_set_value(field
, "");
1195 } else if (!strcmp(field_name
, "func")) {
1196 if (dbg_info_src
&& dbg_info_src
->func
) {
1197 ret
= bt_ctf_field_string_set_value(field
,
1198 dbg_info_src
->func
);
1200 ret
= bt_ctf_field_string_set_value(field
, "");
1202 } else if (!strcmp(field_name
, "src")) {
1203 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1204 GString
*tmp
= g_string_new(NULL
);
1206 if (component
->arg_full_path
) {
1207 g_string_printf(tmp
, "%s:%" PRId64
,
1208 dbg_info_src
->src_path
,
1209 dbg_info_src
->line_no
);
1211 g_string_printf(tmp
, "%s:%" PRId64
,
1212 dbg_info_src
->short_src_path
,
1213 dbg_info_src
->line_no
);
1215 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1216 g_string_free(tmp
, true);
1218 ret
= bt_ctf_field_string_set_value(field
, "");
1223 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1224 __FILE__
, __LINE__
);
1236 bt_put(debug_field_type
);
1241 int copy_set_debug_info_stream_event_context(FILE *err
,
1242 struct bt_ctf_field
*event_context
,
1243 struct bt_ctf_event
*event
,
1244 struct bt_ctf_event
*writer_event
,
1245 struct debug_info
*debug_info
,
1246 struct debug_info_component
*component
)
1248 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1249 struct bt_ctf_field
*writer_event_context
= NULL
;
1250 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1251 struct bt_ctf_field_type
*field_type
= NULL
;
1252 struct debug_info_source
*dbg_info_src
;
1253 int ret
, nr_fields
, i
;
1255 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1256 if (!writer_event_context
) {
1257 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1261 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1262 if (!writer_event_context_type
) {
1263 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1264 __FILE__
, __LINE__
);
1269 * If it is not a structure, we did not modify it to add the debug info
1270 * fields, so just assign it as is.
1272 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1273 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1277 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1279 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1280 for (i
= 0; i
< nr_fields
; i
++) {
1281 const char *field_name
;
1283 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1284 &field_name
, &field_type
, i
) < 0) {
1285 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1286 __FILE__
, __LINE__
);
1290 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1292 * The debug_info field, only exists in the writer event or
1293 * if it was set by a earlier pass of the debug_info plugin.
1295 * FIXME: are we replacing an exisiting debug_info struct here ??
1297 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1299 debug_field
= bt_ctf_field_structure_get_field_by_index(
1300 writer_event_context
, i
);
1302 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1303 __FILE__
, __LINE__
);
1306 ret
= set_debug_info_field(err
, debug_field
,
1307 dbg_info_src
, component
);
1309 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1310 __FILE__
, __LINE__
);
1313 BT_PUT(debug_field
);
1315 copy_field
= bt_ctf_field_copy(field
);
1317 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1318 __FILE__
, __LINE__
);
1322 ret
= bt_ctf_field_structure_set_field(writer_event_context
,
1323 field_name
, copy_field
);
1325 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1326 __FILE__
, __LINE__
);
1341 bt_put(writer_event_context_type
);
1342 bt_put(writer_event_context
);
1345 bt_put(debug_field
);
1351 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1352 struct bt_ctf_stream_class
*stream_class
)
1354 struct bt_ctf_trace
*trace
= NULL
;
1355 struct bt_ctf_clock_class
*clock_class
= NULL
;
1357 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1359 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1364 /* FIXME multi-clock? */
1365 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1374 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1376 struct bt_ctf_event_class
*event_class
= NULL
;
1377 struct bt_ctf_stream_class
*stream_class
= NULL
;
1378 struct bt_ctf_clock_class
*clock_class
= NULL
;
1380 event_class
= bt_ctf_event_get_class(event
);
1382 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1387 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1388 if (!stream_class
) {
1389 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1394 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1398 BT_PUT(clock_class
);
1400 bt_put(stream_class
);
1401 bt_put(event_class
);
1406 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1407 struct bt_ctf_event
*writer_event
)
1409 struct bt_ctf_clock_class
*clock_class
= NULL
;
1410 struct bt_ctf_clock_value
*clock_value
= NULL
;
1413 clock_class
= event_get_clock_class(err
, event
);
1415 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1420 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1422 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1428 * We share the same clocks, so we can assign the clock value to the
1431 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1433 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1444 bt_put(clock_class
);
1445 bt_put(clock_value
);
1450 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1451 struct bt_ctf_event_class
*writer_event_class
,
1452 struct debug_info
*debug_info
,
1453 struct debug_info_component
*component
)
1455 struct bt_ctf_event
*writer_event
= NULL
;
1456 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1459 writer_event
= bt_ctf_event_create(writer_event_class
);
1460 if (!writer_event
) {
1461 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1466 ret
= set_event_clock_value(err
, event
, writer_event
);
1468 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1469 __FILE__
, __LINE__
);
1473 /* Optional field, so it can fail silently. */
1474 field
= bt_ctf_event_get_header(event
);
1476 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1477 writer_event
, field
);
1479 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1480 __FILE__
, __LINE__
);
1486 /* Optional field, so it can fail silently. */
1487 field
= bt_ctf_event_get_stream_event_context(event
);
1489 ret
= copy_set_debug_info_stream_event_context(err
,
1490 field
, event
, writer_event
, debug_info
,
1493 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1494 __FILE__
, __LINE__
);
1500 /* Optional field, so it can fail silently. */
1501 field
= bt_ctf_event_get_event_context(event
);
1503 copy_field
= bt_ctf_field_copy(field
);
1505 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1506 __FILE__
, __LINE__
);
1509 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1511 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1512 __FILE__
, __LINE__
);
1519 field
= bt_ctf_event_get_event_payload(event
);
1521 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1522 __FILE__
, __LINE__
);
1525 copy_field
= bt_ctf_field_copy(field
);
1527 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
1529 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1530 __FILE__
, __LINE__
);
1540 BT_PUT(writer_event
);
1544 return writer_event
;
1548 struct bt_ctf_event
*debug_info_output_event(
1549 struct debug_info_iterator
*debug_it
,
1550 struct bt_ctf_event
*event
)
1552 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
1553 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
1554 struct bt_ctf_event
*writer_event
= NULL
;
1555 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
1556 struct bt_ctf_trace
*writer_trace
= NULL
;
1557 struct debug_info
*debug_info
;
1558 const char *event_name
;
1561 event_class
= bt_ctf_event_get_class(event
);
1563 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1564 __FILE__
, __LINE__
);
1568 event_name
= bt_ctf_event_class_get_name(event_class
);
1570 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1571 __FILE__
, __LINE__
);
1575 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1576 if (!stream_class
) {
1577 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1578 __FILE__
, __LINE__
);
1582 writer_stream_class
= g_hash_table_lookup(
1583 debug_it
->stream_class_map
,
1584 (gpointer
) stream_class
);
1585 if (!writer_stream_class
|| !bt_get(writer_stream_class
)) {
1586 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1587 __FILE__
, __LINE__
);
1591 writer_event_class
= get_event_class(debug_it
,
1592 writer_stream_class
, event_class
);
1593 if (!writer_event_class
) {
1594 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
1596 if (!writer_event_class
) {
1597 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1598 __func__
, __FILE__
, __LINE__
);
1601 int_ret
= bt_ctf_stream_class_add_event_class(
1602 writer_stream_class
, writer_event_class
);
1604 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1605 __func__
, __FILE__
, __LINE__
);
1610 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
1611 if (!writer_trace
) {
1612 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1613 __FILE__
, __LINE__
);
1617 debug_info
= get_trace_debug_info(debug_it
, writer_trace
);
1619 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
1622 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
1623 writer_event_class
, debug_info
,
1624 debug_it
->debug_info_component
);
1625 if (!writer_event
) {
1626 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1627 __FILE__
, __LINE__
);
1628 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
1629 bt_ctf_event_class_get_name(writer_event_class
));
1633 packet
= bt_ctf_event_get_packet(event
);
1635 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1636 __FILE__
, __LINE__
);
1640 writer_packet
= lookup_packet(debug_it
, packet
);
1641 if (!writer_packet
) {
1642 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1643 __FILE__
, __LINE__
);
1646 bt_get(writer_packet
);
1648 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
1650 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1651 __FILE__
, __LINE__
);
1652 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
1653 bt_ctf_event_class_get_name(writer_event_class
));
1657 /* Keep the reference on the writer event */
1661 BT_PUT(writer_event
);
1664 bt_put(writer_trace
);
1665 bt_put(writer_packet
);
1667 bt_put(writer_event_class
);
1668 bt_put(writer_stream_class
);
1669 bt_put(stream_class
);
1670 bt_put(event_class
);
1671 return writer_event
;