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_stream
*insert_new_stream(
45 struct debug_info_iterator
*debug_it
,
46 struct bt_ctf_stream
*stream
,
47 struct debug_info_trace
*di_trace
);
50 void unref_stream(struct bt_ctf_stream
*stream
)
56 void unref_packet(struct bt_ctf_packet
*packet
)
62 void unref_stream_class(struct bt_ctf_stream_class
*stream_class
)
68 void unref_debug_info(struct debug_info
*debug_info
)
70 debug_info_destroy(debug_info
);
74 void destroy_stream_state_key(gpointer key
)
76 g_free((enum fs_writer_stream_state
*) key
);
80 struct bt_ctf_field
*get_payload_field(FILE *err
,
81 struct bt_ctf_event
*event
, const char *field_name
)
83 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
84 struct bt_ctf_field_type
*sec_type
= NULL
;
86 sec
= bt_ctf_event_get_payload(event
, NULL
);
88 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
93 sec_type
= bt_ctf_field_get_type(sec
);
95 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
100 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
101 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
106 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
115 struct bt_ctf_field
*get_stream_event_context_field(FILE *err
,
116 struct bt_ctf_event
*event
, const char *field_name
)
118 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
119 struct bt_ctf_field_type
*sec_type
= NULL
;
121 sec
= bt_ctf_event_get_stream_event_context(event
);
126 sec_type
= bt_ctf_field_get_type(sec
);
128 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
133 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
134 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
139 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
148 int get_stream_event_context_unsigned_int_field_value(FILE *err
,
149 struct bt_ctf_event
*event
, const char *field_name
,
153 struct bt_ctf_field
*field
= NULL
;
154 struct bt_ctf_field_type
*field_type
= NULL
;
156 field
= get_stream_event_context_field(err
, event
, field_name
);
161 field_type
= bt_ctf_field_get_type(field
);
163 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
168 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
169 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
174 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
175 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
180 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
192 int get_stream_event_context_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
193 const char *field_name
, int64_t *value
)
195 struct bt_ctf_field
*field
= NULL
;
196 struct bt_ctf_field_type
*field_type
= NULL
;
199 field
= get_stream_event_context_field(err
, event
, field_name
);
204 field_type
= bt_ctf_field_get_type(field
);
206 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
211 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
212 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
217 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
218 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
223 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
235 int get_payload_unsigned_int_field_value(FILE *err
,
236 struct bt_ctf_event
*event
, const char *field_name
,
239 struct bt_ctf_field
*field
= NULL
;
240 struct bt_ctf_field_type
*field_type
= NULL
;
243 field
= get_payload_field(err
, event
, field_name
);
245 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
250 field_type
= bt_ctf_field_get_type(field
);
252 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
257 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
258 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
263 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
264 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
269 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
281 int get_payload_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
282 const char *field_name
, int64_t *value
)
284 struct bt_ctf_field
*field
= NULL
;
285 struct bt_ctf_field_type
*field_type
= NULL
;
288 field
= get_payload_field(err
, event
, field_name
);
290 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
295 field_type
= bt_ctf_field_get_type(field
);
297 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
302 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
303 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
308 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
309 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
314 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
326 int get_payload_string_field_value(FILE *err
,
327 struct bt_ctf_event
*event
, const char *field_name
,
330 struct bt_ctf_field
*field
= NULL
;
331 struct bt_ctf_field_type
*field_type
= NULL
;
335 * The field might not exist, no error here.
337 field
= get_payload_field(err
, event
, field_name
);
342 field_type
= bt_ctf_field_get_type(field
);
344 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
349 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_STRING
) {
350 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
355 *value
= bt_ctf_field_string_get_value(field
);
357 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
374 int get_payload_build_id_field_value(FILE *err
,
375 struct bt_ctf_event
*event
, const char *field_name
,
376 uint8_t **build_id
, uint64_t *build_id_len
)
378 struct bt_ctf_field
*field
= NULL
, *seq_len
= NULL
;
379 struct bt_ctf_field_type
*field_type
= NULL
;
380 struct bt_ctf_field
*seq_field
= NULL
;
386 field
= get_payload_field(err
, event
, field_name
);
388 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
393 field_type
= bt_ctf_field_get_type(field
);
395 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
400 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
401 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
407 seq_len
= bt_ctf_field_sequence_get_length(field
);
409 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
414 ret
= bt_ctf_field_unsigned_integer_get_value(seq_len
, build_id_len
);
416 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
422 *build_id
= g_new0(uint8_t, *build_id_len
);
424 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
429 for (i
= 0; i
< *build_id_len
; i
++) {
432 seq_field
= bt_ctf_field_sequence_get_field(field
, i
);
434 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
439 ret
= bt_ctf_field_unsigned_integer_get_value(seq_field
, &tmp
);
441 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
446 (*build_id
)[i
] = (uint8_t) tmp
;
461 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
462 struct bt_ctf_trace
*writer_trace
,
463 struct debug_info_trace
*di_trace
)
465 return (struct debug_info
*) g_hash_table_lookup(
466 di_trace
->trace_debug_map
,
467 (gpointer
) writer_trace
);
471 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
472 struct bt_ctf_trace
*writer_trace
,
473 struct debug_info_trace
*di_trace
)
475 struct debug_info
*debug_info
= NULL
;
476 struct bt_value
*field
= NULL
;
477 const char *str_value
;
478 enum bt_value_status ret
;
480 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
482 /* No domain field, no debug info */
486 ret
= bt_value_string_get(field
, &str_value
);
487 if (ret
!= BT_VALUE_STATUS_OK
) {
488 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
492 /* Domain not ust, no debug info */
493 if (strcmp(str_value
, "ust") != 0) {
498 /* No tracer_name, no debug info */
499 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
501 /* No tracer_name, no debug info */
505 ret
= bt_value_string_get(field
, &str_value
);
506 if (ret
!= BT_VALUE_STATUS_OK
) {
507 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
511 /* Tracer_name not lttng-ust, no debug info */
512 if (strcmp(str_value
, "lttng-ust") != 0) {
517 debug_info
= debug_info_create(debug_it
->debug_info_component
);
519 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
524 g_hash_table_insert(di_trace
->trace_debug_map
, (gpointer
) writer_trace
,
533 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
534 struct bt_ctf_trace
*writer_trace
,
535 struct debug_info_trace
*di_trace
)
537 struct debug_info
*debug_info
;
539 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
, di_trace
);
544 debug_info
= insert_new_debug_info(debug_it
, writer_trace
, di_trace
);
551 struct debug_info_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
552 struct bt_ctf_trace
*trace
)
554 return (struct debug_info_trace
*) g_hash_table_lookup(
560 enum debug_info_stream_state
*insert_new_stream_state(
561 struct debug_info_iterator
*debug_it
,
562 struct debug_info_trace
*di_trace
, struct bt_ctf_stream
*stream
)
564 enum debug_info_stream_state
*v
= NULL
;
566 v
= g_new0(enum debug_info_stream_state
, 1);
568 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
572 *v
= DEBUG_INFO_UNKNOWN_STREAM
;
574 g_hash_table_insert(di_trace
->stream_states
, stream
, v
);
581 void check_completed_trace(gpointer key
, gpointer value
, gpointer user_data
)
583 enum debug_info_stream_state
*state
= value
;
584 int *trace_completed
= user_data
;
586 if (*state
!= DEBUG_INFO_COMPLETED_STREAM
) {
587 *trace_completed
= 0;
592 gboolean
empty_ht(gpointer key
, gpointer value
, gpointer user_data
)
598 void debug_info_close_trace(struct debug_info_iterator
*debug_it
,
599 struct debug_info_trace
*di_trace
)
601 if (di_trace
->static_listener_id
>= 0) {
602 bt_ctf_trace_remove_is_static_listener(di_trace
->trace
,
603 di_trace
->static_listener_id
);
606 /* Empty the stream class HT. */
607 g_hash_table_foreach_remove(di_trace
->stream_class_map
,
609 g_hash_table_destroy(di_trace
->stream_class_map
);
611 /* Empty the stream HT. */
612 g_hash_table_foreach_remove(di_trace
->stream_map
,
614 g_hash_table_destroy(di_trace
->stream_map
);
616 /* Empty the stream state HT. */
617 g_hash_table_foreach_remove(di_trace
->stream_states
,
619 g_hash_table_destroy(di_trace
->stream_states
);
621 /* Empty the packet HT. */
622 g_hash_table_foreach_remove(di_trace
->packet_map
,
624 g_hash_table_destroy(di_trace
->packet_map
);
626 /* Empty the trace_debug HT. */
627 g_hash_table_foreach_remove(di_trace
->trace_debug_map
,
629 g_hash_table_destroy(di_trace
->trace_debug_map
);
633 int sync_event_classes(struct debug_info_iterator
*debug_it
,
634 struct bt_ctf_stream
*stream
,
635 struct bt_ctf_stream
*writer_stream
)
638 struct bt_ctf_stream_class
*stream_class
= NULL
,
639 *writer_stream_class
= NULL
;
640 enum bt_component_status ret
;
642 stream_class
= bt_ctf_stream_get_class(stream
);
644 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
649 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
650 if (!writer_stream_class
) {
651 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
656 ret
= ctf_copy_event_classes(debug_it
->err
, stream_class
,
657 writer_stream_class
);
658 if (ret
!= BT_COMPONENT_STATUS_OK
) {
668 bt_put(stream_class
);
669 bt_put(writer_stream_class
);
674 void trace_is_static_listener(struct bt_ctf_trace
*trace
, void *data
)
676 struct debug_info_trace
*di_trace
= data
;
677 struct debug_info_iterator
*debug_it
= di_trace
->debug_it
;
678 int trace_completed
= 1, ret
, nr_stream
, i
;
679 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
680 struct bt_ctf_trace
*writer_trace
= di_trace
->writer_trace
;
683 * When the trace becomes static, make sure that we have all
684 * the event classes in our stream_class copies before setting it
687 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
688 for (i
= 0; i
< nr_stream
; i
++) {
689 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
691 fprintf(debug_it
->err
,
692 "[error] %s in %s:%d\n", __func__
,
696 writer_stream
= bt_ctf_trace_get_stream_by_index(writer_trace
, i
);
697 if (!writer_stream
) {
698 fprintf(debug_it
->err
,
699 "[error] %s in %s:%d\n", __func__
,
703 ret
= sync_event_classes(di_trace
->debug_it
, stream
, writer_stream
);
705 fprintf(debug_it
->err
,
706 "[error] %s in %s:%d\n", __func__
,
711 BT_PUT(writer_stream
);
714 bt_ctf_trace_set_is_static(di_trace
->writer_trace
);
715 di_trace
->trace_static
= 1;
717 g_hash_table_foreach(di_trace
->stream_states
,
718 check_completed_trace
, &trace_completed
);
719 if (trace_completed
) {
720 debug_info_close_trace(di_trace
->debug_it
, di_trace
);
721 g_hash_table_remove(di_trace
->debug_it
->trace_map
,
726 bt_put(writer_stream
);
731 struct debug_info_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
732 struct bt_ctf_stream
*stream
) {
733 struct bt_ctf_trace
*writer_trace
= NULL
;
734 struct debug_info_trace
*di_trace
= NULL
;
735 struct bt_ctf_trace
*trace
= NULL
;
736 struct bt_ctf_stream_class
*stream_class
= NULL
;
737 struct bt_ctf_stream
*writer_stream
= NULL
;
738 int ret
, nr_stream
, i
;
740 writer_trace
= bt_ctf_trace_create();
742 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
747 stream_class
= bt_ctf_stream_get_class(stream
);
749 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
754 trace
= bt_ctf_stream_class_get_trace(stream_class
);
756 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
761 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
762 if (ret
!= BT_COMPONENT_STATUS_OK
) {
763 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
768 di_trace
= g_new0(struct debug_info_trace
, 1);
770 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
775 di_trace
->trace
= trace
;
776 di_trace
->writer_trace
= writer_trace
;
777 di_trace
->debug_info_component
= debug_it
->debug_info_component
;
778 di_trace
->debug_it
= debug_it
;
779 di_trace
->stream_map
= g_hash_table_new_full(g_direct_hash
,
780 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream
);
781 di_trace
->stream_class_map
= g_hash_table_new_full(g_direct_hash
,
782 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream_class
);
783 di_trace
->packet_map
= g_hash_table_new_full(g_direct_hash
,
784 g_direct_equal
, NULL
, (GDestroyNotify
) unref_packet
);
785 di_trace
->trace_debug_map
= g_hash_table_new_full(g_direct_hash
,
786 g_direct_equal
, NULL
, (GDestroyNotify
) unref_debug_info
);
787 di_trace
->stream_states
= g_hash_table_new_full(g_direct_hash
,
788 g_direct_equal
, NULL
, destroy_stream_state_key
);
789 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, di_trace
);
791 /* Set all the existing streams in the unknown state. */
792 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
793 for (i
= 0; i
< nr_stream
; i
++) {
794 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
796 fprintf(debug_it
->err
,
797 "[error] %s in %s:%d\n", __func__
,
801 insert_new_stream_state(debug_it
, di_trace
, stream
);
802 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
803 if (!writer_stream
) {
804 fprintf(debug_it
->err
,
805 "[error] %s in %s:%d\n", __func__
,
809 bt_get(writer_stream
);
810 ret
= sync_event_classes(debug_it
, stream
, writer_stream
);
812 fprintf(debug_it
->err
,
813 "[error] %s in %s:%d\n", __func__
,
817 BT_PUT(writer_stream
);
821 /* Check if the trace is already static or register a listener. */
822 if (bt_ctf_trace_is_static(trace
)) {
823 di_trace
->trace_static
= 1;
824 di_trace
->static_listener_id
= -1;
825 bt_ctf_trace_set_is_static(writer_trace
);
827 ret
= bt_ctf_trace_add_is_static_listener(trace
,
828 trace_is_static_listener
, di_trace
);
830 fprintf(debug_it
->err
,
831 "[error] %s in %s:%d\n", __func__
, __FILE__
,
835 di_trace
->static_listener_id
= ret
;
842 BT_PUT(writer_trace
);
847 bt_put(writer_stream
);
848 bt_put(stream_class
);
854 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
855 struct bt_ctf_packet
*packet
,
856 struct debug_info_trace
*di_trace
)
858 return (struct bt_ctf_packet
*) g_hash_table_lookup(
859 di_trace
->packet_map
,
864 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
865 struct bt_ctf_packet
*packet
,
866 struct bt_ctf_stream
*writer_stream
,
867 struct debug_info_trace
*di_trace
)
869 struct bt_ctf_packet
*writer_packet
;
872 writer_packet
= bt_ctf_packet_create(writer_stream
);
873 if (!writer_packet
) {
874 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
879 ret
= ctf_packet_copy_header(debug_it
->err
, packet
, writer_packet
);
881 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
886 g_hash_table_insert(di_trace
->packet_map
, (gpointer
) packet
,
891 BT_PUT(writer_packet
);
893 return writer_packet
;
897 int add_debug_info_fields(FILE *err
,
898 struct bt_ctf_field_type
*writer_event_context_type
,
899 struct debug_info_component
*component
)
901 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
902 *bin_field_type
= NULL
, *func_field_type
= NULL
,
903 *src_field_type
= NULL
;
906 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
907 writer_event_context_type
, "_ip");
908 /* No ip field, so no debug info. */
914 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
915 writer_event_context_type
,
916 component
->arg_debug_info_field_name
);
917 /* Already existing debug_info field, no need to add it. */
918 if (debug_field_type
) {
922 debug_field_type
= bt_ctf_field_type_structure_create();
923 if (!debug_field_type
) {
924 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
929 bin_field_type
= bt_ctf_field_type_string_create();
930 if (!bin_field_type
) {
931 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
936 func_field_type
= bt_ctf_field_type_string_create();
937 if (!func_field_type
) {
938 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
943 src_field_type
= bt_ctf_field_type_string_create();
944 if (!src_field_type
) {
945 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
950 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
951 bin_field_type
, "bin");
953 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
958 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
959 func_field_type
, "func");
961 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
966 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
967 src_field_type
, "src");
969 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
974 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
975 debug_field_type
, component
->arg_debug_info_field_name
);
977 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
986 BT_PUT(debug_field_type
);
989 bt_put(src_field_type
);
990 bt_put(func_field_type
);
991 bt_put(bin_field_type
);
992 bt_put(debug_field_type
);
997 int create_debug_info_event_context_type(FILE *err
,
998 struct bt_ctf_field_type
*event_context_type
,
999 struct bt_ctf_field_type
*writer_event_context_type
,
1000 struct debug_info_component
*component
)
1002 int ret
, nr_fields
, i
;
1004 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
1005 for (i
= 0; i
< nr_fields
; i
++) {
1006 struct bt_ctf_field_type
*field_type
= NULL
;
1007 const char *field_name
;
1009 if (bt_ctf_field_type_structure_get_field(event_context_type
,
1010 &field_name
, &field_type
, i
) < 0) {
1011 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1012 __FILE__
, __LINE__
);
1016 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
1017 field_type
, field_name
);
1020 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1026 ret
= add_debug_info_fields(err
, writer_event_context_type
,
1037 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
1038 struct bt_ctf_stream_class
*stream_class
,
1039 struct bt_ctf_trace
*writer_trace
,
1040 struct debug_info_component
*component
)
1042 struct bt_ctf_field_type
*type
= NULL
;
1043 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1044 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1046 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
1048 writer_stream_class
= bt_ctf_stream_class_create_empty(name
);
1049 if (!writer_stream_class
) {
1050 fprintf(err
, "[error] %s in %s:%d\n",
1051 __func__
, __FILE__
, __LINE__
);
1055 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
1057 ret_int
= bt_ctf_stream_class_set_packet_context_type(
1058 writer_stream_class
, type
);
1060 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1067 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
1069 ret_int
= bt_ctf_stream_class_set_event_header_type(
1070 writer_stream_class
, type
);
1072 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1079 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
1081 writer_event_context_type
= bt_ctf_field_type_structure_create();
1082 if (!writer_event_context_type
) {
1083 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1087 ret_int
= create_debug_info_event_context_type(err
, type
,
1088 writer_event_context_type
, component
);
1090 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1096 ret_int
= bt_ctf_stream_class_set_event_context_type(
1097 writer_stream_class
, writer_event_context_type
);
1099 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1103 BT_PUT(writer_event_context_type
);
1109 BT_PUT(writer_stream_class
);
1111 bt_put(writer_event_context_type
);
1113 return writer_stream_class
;
1117 * Add the original clock classes to the new trace, we do not need to copy
1118 * them, and if we did, we would have to manually inspect the stream class
1119 * to update the integers mapping to a clock.
1122 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
1123 struct bt_ctf_stream_class
*writer_stream_class
,
1124 struct bt_ctf_trace
*trace
)
1126 int ret
, clock_class_count
, i
;
1128 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
1130 for (i
= 0; i
< clock_class_count
; i
++) {
1131 struct bt_ctf_clock_class
*clock_class
=
1132 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
1133 struct bt_ctf_clock_class
*existing_clock_class
= NULL
;
1136 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1141 existing_clock_class
= bt_ctf_trace_get_clock_class_by_name(
1142 writer_trace
, bt_ctf_clock_class_get_name(clock_class
));
1143 bt_put(existing_clock_class
);
1144 if (existing_clock_class
) {
1145 bt_put(clock_class
);
1149 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
1150 BT_PUT(clock_class
);
1152 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1169 struct bt_ctf_stream_class
*insert_new_stream_class(
1170 struct debug_info_iterator
*debug_it
,
1171 struct bt_ctf_stream_class
*stream_class
)
1173 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1174 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
1175 struct debug_info_trace
*di_trace
;
1176 enum bt_component_status ret
;
1179 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1181 fprintf(debug_it
->err
,
1182 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1187 di_trace
= lookup_trace(debug_it
, trace
);
1189 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1190 __FILE__
, __LINE__
);
1191 ret
= BT_COMPONENT_STATUS_ERROR
;
1194 writer_trace
= di_trace
->writer_trace
;
1195 bt_get(writer_trace
);
1197 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1198 writer_trace
, debug_it
->debug_info_component
);
1199 if (!writer_stream_class
) {
1200 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
1201 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1202 __func__
, __FILE__
, __LINE__
);
1206 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
1208 fprintf(debug_it
->err
,
1209 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1214 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1215 writer_stream_class
, trace
);
1216 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1217 fprintf(debug_it
->err
,
1218 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1223 g_hash_table_insert(di_trace
->stream_class_map
,
1224 (gpointer
) stream_class
, writer_stream_class
);
1229 BT_PUT(writer_stream_class
);
1232 bt_put(writer_trace
);
1233 return writer_stream_class
;
1237 struct bt_ctf_stream
*insert_new_stream(
1238 struct debug_info_iterator
*debug_it
,
1239 struct bt_ctf_stream
*stream
,
1240 struct debug_info_trace
*di_trace
)
1242 struct bt_ctf_stream
*writer_stream
= NULL
;
1243 struct bt_ctf_stream_class
*stream_class
= NULL
;
1244 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1247 stream_class
= bt_ctf_stream_get_class(stream
);
1248 if (!stream_class
) {
1249 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1250 __func__
, __FILE__
, __LINE__
);
1254 writer_stream_class
= g_hash_table_lookup(
1255 di_trace
->stream_class_map
,
1256 (gpointer
) stream_class
);
1258 if (!writer_stream_class
) {
1259 writer_stream_class
= insert_new_stream_class(debug_it
,
1261 if (!writer_stream_class
) {
1262 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1263 __func__
, __FILE__
, __LINE__
);
1267 bt_get(writer_stream_class
);
1269 id
= bt_ctf_stream_get_id(stream
);
1271 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
1272 bt_ctf_stream_get_name(stream
));
1274 writer_stream
= bt_ctf_stream_create_with_id(
1275 writer_stream_class
,
1276 bt_ctf_stream_get_name(stream
), id
);
1279 if (!writer_stream
) {
1280 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1281 __func__
, __FILE__
, __LINE__
);
1285 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1291 BT_PUT(writer_stream
);
1293 bt_put(stream_class
);
1294 bt_put(writer_stream_class
);
1295 return writer_stream
;
1299 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1300 struct bt_ctf_stream
*stream
,
1301 struct debug_info_trace
*di_trace
)
1303 return (struct bt_ctf_stream
*) g_hash_table_lookup(
1304 di_trace
->stream_map
, (gpointer
) stream
);
1308 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1309 struct bt_ctf_stream_class
*writer_stream_class
,
1310 struct bt_ctf_event_class
*event_class
)
1312 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
1313 bt_ctf_event_class_get_id(event_class
));
1317 struct debug_info_trace
*lookup_di_trace_from_stream(
1318 struct debug_info_iterator
*debug_it
,
1319 struct bt_ctf_stream
*stream
)
1321 struct bt_ctf_stream_class
*stream_class
= NULL
;
1322 struct bt_ctf_trace
*trace
= NULL
;
1323 struct debug_info_trace
*di_trace
= NULL
;
1325 stream_class
= bt_ctf_stream_get_class(stream
);
1326 if (!stream_class
) {
1327 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1328 __func__
, __FILE__
, __LINE__
);
1332 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1334 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1335 __func__
, __FILE__
, __LINE__
);
1339 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1340 debug_it
->trace_map
, (gpointer
) trace
);
1343 BT_PUT(stream_class
);
1349 struct bt_ctf_stream
*get_writer_stream(
1350 struct debug_info_iterator
*debug_it
,
1351 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
1353 struct bt_ctf_stream_class
*stream_class
= NULL
;
1354 struct bt_ctf_stream
*writer_stream
= NULL
;
1355 struct debug_info_trace
*di_trace
= NULL
;
1357 stream_class
= bt_ctf_stream_get_class(stream
);
1358 if (!stream_class
) {
1359 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1360 __func__
, __FILE__
, __LINE__
);
1364 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1366 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1367 __func__
, __FILE__
, __LINE__
);
1371 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1372 if (!writer_stream
) {
1373 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1374 __func__
, __FILE__
, __LINE__
);
1377 bt_get(writer_stream
);
1382 BT_PUT(writer_stream
);
1384 bt_put(stream_class
);
1385 return writer_stream
;
1389 struct bt_ctf_packet
*debug_info_new_packet(
1390 struct debug_info_iterator
*debug_it
,
1391 struct bt_ctf_packet
*packet
)
1393 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1394 struct bt_ctf_packet
*writer_packet
= NULL
;
1395 struct bt_ctf_field
*packet_context
= NULL
;
1396 struct debug_info_trace
*di_trace
;
1399 stream
= bt_ctf_packet_get_stream(packet
);
1401 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1402 __func__
, __FILE__
, __LINE__
);
1406 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1407 if (!writer_stream
) {
1408 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1409 __func__
, __FILE__
, __LINE__
);
1413 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1415 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1416 __FILE__
, __LINE__
);
1421 * If a packet was already opened, close it and remove it from
1424 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1425 if (writer_packet
) {
1426 g_hash_table_remove(di_trace
->packet_map
, packet
);
1427 BT_PUT(writer_packet
);
1430 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1432 if (!writer_packet
) {
1433 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1434 __func__
, __FILE__
, __LINE__
);
1438 packet_context
= bt_ctf_packet_get_context(packet
);
1439 if (packet_context
) {
1440 int_ret
= ctf_packet_copy_context(debug_it
->err
,
1441 packet
, writer_stream
, writer_packet
);
1443 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1444 __func__
, __FILE__
, __LINE__
);
1447 BT_PUT(packet_context
);
1450 bt_get(writer_packet
);
1456 bt_put(packet_context
);
1457 bt_put(writer_stream
);
1459 return writer_packet
;
1463 struct bt_ctf_packet
*debug_info_close_packet(
1464 struct debug_info_iterator
*debug_it
,
1465 struct bt_ctf_packet
*packet
)
1467 struct bt_ctf_packet
*writer_packet
= NULL
;
1468 struct bt_ctf_stream
*stream
= NULL
;
1469 struct debug_info_trace
*di_trace
;
1471 stream
= bt_ctf_packet_get_stream(packet
);
1473 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1474 __FILE__
, __LINE__
);
1478 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1480 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1481 __FILE__
, __LINE__
);
1485 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1486 if (!writer_packet
) {
1487 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1488 __func__
, __FILE__
, __LINE__
);
1491 bt_get(writer_packet
);
1492 g_hash_table_remove(di_trace
->packet_map
, packet
);
1496 return writer_packet
;
1500 struct bt_ctf_stream
*debug_info_stream_begin(
1501 struct debug_info_iterator
*debug_it
,
1502 struct bt_ctf_stream
*stream
)
1504 struct bt_ctf_stream
*writer_stream
= NULL
;
1505 enum debug_info_stream_state
*state
;
1506 struct debug_info_trace
*di_trace
= NULL
;
1508 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1510 di_trace
= insert_new_trace(debug_it
, stream
);
1512 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1513 __func__
, __FILE__
, __LINE__
);
1518 /* Set the stream as active */
1519 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1521 if (di_trace
->trace_static
) {
1522 fprintf(debug_it
->err
, "[error] Adding a new stream "
1523 "on a static trace\n");
1526 state
= insert_new_stream_state(debug_it
, di_trace
,
1529 fprintf(debug_it
->err
, "[error] Adding a new stream "
1530 "on a static trace\n");
1534 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1535 fprintf(debug_it
->err
, "[error] Unexpected stream state %d\n",
1539 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1541 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1542 if (!writer_stream
) {
1543 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1545 bt_get(writer_stream
);
1550 BT_PUT(writer_stream
);
1552 return writer_stream
;
1556 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1557 struct bt_ctf_stream
*stream
)
1559 struct bt_ctf_stream
*writer_stream
= NULL
;
1560 struct debug_info_trace
*di_trace
= NULL
;
1561 enum debug_info_stream_state
*state
;
1563 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1565 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1566 __func__
, __FILE__
, __LINE__
);
1570 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1571 if (!writer_stream
) {
1572 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1573 __func__
, __FILE__
, __LINE__
);
1577 * Take the ref on the stream and keep it until the notification
1580 bt_get(writer_stream
);
1582 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1583 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1584 fprintf(debug_it
->err
, "[error] Unexpected stream "
1585 "state %d\n", *state
);
1588 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1590 g_hash_table_remove(di_trace
->stream_map
, stream
);
1592 if (di_trace
->trace_static
) {
1593 int trace_completed
= 1;
1595 g_hash_table_foreach(di_trace
->stream_states
,
1596 check_completed_trace
, &trace_completed
);
1597 if (trace_completed
) {
1598 debug_info_close_trace(debug_it
, di_trace
);
1599 g_hash_table_remove(debug_it
->trace_map
,
1607 BT_PUT(writer_stream
);
1610 return writer_stream
;
1614 struct debug_info_source
*lookup_debug_info(FILE *err
,
1615 struct bt_ctf_event
*event
,
1616 struct debug_info
*debug_info
)
1620 struct debug_info_source
*dbg_info_src
= NULL
;
1623 ret
= get_stream_event_context_int_field_value(err
, event
,
1629 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1635 /* Get debug info for this context. */
1636 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1639 return dbg_info_src
;
1643 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1644 struct debug_info_source
*dbg_info_src
,
1645 struct debug_info_component
*component
)
1647 int i
, nr_fields
, ret
= 0;
1648 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1649 struct bt_ctf_field
*field
= NULL
;
1650 struct bt_ctf_field_type
*field_type
= NULL
;
1652 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1653 if (!debug_field_type
) {
1654 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1655 __FILE__
, __LINE__
);
1659 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1660 for (i
= 0; i
< nr_fields
; i
++) {
1661 const char *field_name
;
1663 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1664 &field_name
, &field_type
, i
) < 0) {
1665 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1666 __FILE__
, __LINE__
);
1671 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1672 if (!strcmp(field_name
, "bin")) {
1673 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1674 GString
*tmp
= g_string_new(NULL
);
1676 if (component
->arg_full_path
) {
1677 g_string_printf(tmp
, "%s%s",
1678 dbg_info_src
->bin_path
,
1679 dbg_info_src
->bin_loc
);
1681 g_string_printf(tmp
, "%s%s",
1682 dbg_info_src
->short_bin_path
,
1683 dbg_info_src
->bin_loc
);
1685 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1686 g_string_free(tmp
, true);
1688 ret
= bt_ctf_field_string_set_value(field
, "");
1690 } else if (!strcmp(field_name
, "func")) {
1691 if (dbg_info_src
&& dbg_info_src
->func
) {
1692 ret
= bt_ctf_field_string_set_value(field
,
1693 dbg_info_src
->func
);
1695 ret
= bt_ctf_field_string_set_value(field
, "");
1697 } else if (!strcmp(field_name
, "src")) {
1698 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1699 GString
*tmp
= g_string_new(NULL
);
1701 if (component
->arg_full_path
) {
1702 g_string_printf(tmp
, "%s:%" PRId64
,
1703 dbg_info_src
->src_path
,
1704 dbg_info_src
->line_no
);
1706 g_string_printf(tmp
, "%s:%" PRId64
,
1707 dbg_info_src
->short_src_path
,
1708 dbg_info_src
->line_no
);
1710 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1711 g_string_free(tmp
, true);
1713 ret
= bt_ctf_field_string_set_value(field
, "");
1718 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1719 __FILE__
, __LINE__
);
1731 bt_put(debug_field_type
);
1736 int copy_set_debug_info_stream_event_context(FILE *err
,
1737 struct bt_ctf_field
*event_context
,
1738 struct bt_ctf_event
*event
,
1739 struct bt_ctf_event
*writer_event
,
1740 struct debug_info
*debug_info
,
1741 struct debug_info_component
*component
)
1743 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1744 *event_context_type
= NULL
;
1745 struct bt_ctf_field
*writer_event_context
= NULL
;
1746 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1747 struct bt_ctf_field_type
*field_type
= NULL
;
1748 struct debug_info_source
*dbg_info_src
;
1749 int ret
, nr_fields
, i
;
1751 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1752 if (!writer_event_context
) {
1753 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1757 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1758 if (!writer_event_context_type
) {
1759 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1760 __FILE__
, __LINE__
);
1764 event_context_type
= bt_ctf_field_get_type(event_context
);
1765 if (!event_context_type
) {
1766 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1767 __FILE__
, __LINE__
);
1772 * If it is not a structure, we did not modify it to add the debug info
1773 * fields, so just assign it as is.
1775 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1776 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1780 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1782 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1783 for (i
= 0; i
< nr_fields
; i
++) {
1784 const char *field_name
;
1786 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1787 &field_name
, &field_type
, i
) < 0) {
1788 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1789 __FILE__
, __LINE__
);
1794 * Prevent illegal access in the event_context.
1796 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1797 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1800 * The debug_info field, only exists in the writer event or
1801 * if it was set by a earlier pass of the debug_info plugin.
1803 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1805 debug_field
= bt_ctf_field_structure_get_field_by_index(
1806 writer_event_context
, i
);
1808 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1809 __FILE__
, __LINE__
);
1812 ret
= set_debug_info_field(err
, debug_field
,
1813 dbg_info_src
, component
);
1815 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1816 __FILE__
, __LINE__
);
1819 BT_PUT(debug_field
);
1821 copy_field
= bt_ctf_field_copy(field
);
1823 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1824 __FILE__
, __LINE__
);
1828 ret
= bt_ctf_field_structure_set_field_by_name(
1829 writer_event_context
,
1830 field_name
, copy_field
);
1832 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1833 __FILE__
, __LINE__
);
1848 bt_put(event_context_type
);
1849 bt_put(writer_event_context_type
);
1850 bt_put(writer_event_context
);
1853 bt_put(debug_field
);
1859 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1860 struct bt_ctf_stream_class
*stream_class
)
1862 struct bt_ctf_trace
*trace
= NULL
;
1863 struct bt_ctf_clock_class
*clock_class
= NULL
;
1865 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1867 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1872 if (!bt_ctf_trace_get_clock_class_count(trace
)) {
1877 /* FIXME multi-clock? */
1878 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1887 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1889 struct bt_ctf_event_class
*event_class
= NULL
;
1890 struct bt_ctf_stream_class
*stream_class
= NULL
;
1891 struct bt_ctf_clock_class
*clock_class
= NULL
;
1893 event_class
= bt_ctf_event_get_class(event
);
1895 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1900 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1901 if (!stream_class
) {
1902 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1907 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1911 BT_PUT(clock_class
);
1913 bt_put(stream_class
);
1914 bt_put(event_class
);
1919 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1920 struct bt_ctf_event
*writer_event
)
1922 struct bt_ctf_clock_class
*clock_class
= NULL
;
1923 struct bt_ctf_clock_value
*clock_value
= NULL
;
1926 clock_class
= event_get_clock_class(err
, event
);
1928 /* No clock on input trace. */
1932 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1934 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1940 * We share the same clocks, so we can assign the clock value to the
1943 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1945 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1956 bt_put(clock_class
);
1957 bt_put(clock_value
);
1962 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1963 struct bt_ctf_event_class
*writer_event_class
,
1964 struct debug_info
*debug_info
,
1965 struct debug_info_component
*component
)
1967 struct bt_ctf_event
*writer_event
= NULL
;
1968 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1971 writer_event
= bt_ctf_event_create(writer_event_class
);
1972 if (!writer_event
) {
1973 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1978 ret
= set_event_clock_value(err
, event
, writer_event
);
1980 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1981 __FILE__
, __LINE__
);
1985 /* Optional field, so it can fail silently. */
1986 field
= bt_ctf_event_get_header(event
);
1988 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1989 writer_event
, field
);
1991 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1992 __FILE__
, __LINE__
);
1998 /* Optional field, so it can fail silently. */
1999 field
= bt_ctf_event_get_stream_event_context(event
);
2001 ret
= copy_set_debug_info_stream_event_context(err
,
2002 field
, event
, writer_event
, debug_info
,
2005 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2006 __FILE__
, __LINE__
);
2012 /* Optional field, so it can fail silently. */
2013 field
= bt_ctf_event_get_event_context(event
);
2015 copy_field
= bt_ctf_field_copy(field
);
2017 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2018 __FILE__
, __LINE__
);
2021 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
2023 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2024 __FILE__
, __LINE__
);
2031 field
= bt_ctf_event_get_event_payload(event
);
2033 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2034 __FILE__
, __LINE__
);
2037 copy_field
= bt_ctf_field_copy(field
);
2039 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
2041 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2042 __FILE__
, __LINE__
);
2052 BT_PUT(writer_event
);
2056 return writer_event
;
2060 struct bt_ctf_event
*debug_info_output_event(
2061 struct debug_info_iterator
*debug_it
,
2062 struct bt_ctf_event
*event
)
2064 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
2065 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
2066 struct bt_ctf_event
*writer_event
= NULL
;
2067 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
2068 struct bt_ctf_trace
*writer_trace
= NULL
;
2069 struct bt_ctf_stream
*stream
= NULL
;
2070 struct debug_info_trace
*di_trace
;
2071 struct debug_info
*debug_info
;
2072 const char *event_name
;
2075 event_class
= bt_ctf_event_get_class(event
);
2077 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2078 __FILE__
, __LINE__
);
2082 event_name
= bt_ctf_event_class_get_name(event_class
);
2084 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2085 __FILE__
, __LINE__
);
2089 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
2090 if (!stream_class
) {
2091 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2092 __FILE__
, __LINE__
);
2095 stream
= bt_ctf_event_get_stream(event
);
2097 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2098 __FILE__
, __LINE__
);
2101 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
2103 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2104 __FILE__
, __LINE__
);
2108 writer_stream_class
= g_hash_table_lookup(
2109 di_trace
->stream_class_map
,
2110 (gpointer
) stream_class
);
2111 if (!writer_stream_class
) {
2112 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2113 __FILE__
, __LINE__
);
2116 bt_get(writer_stream_class
);
2118 writer_event_class
= get_event_class(debug_it
,
2119 writer_stream_class
, event_class
);
2120 if (!writer_event_class
) {
2121 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
2123 if (!writer_event_class
) {
2124 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2125 __func__
, __FILE__
, __LINE__
);
2128 int_ret
= bt_ctf_stream_class_add_event_class(
2129 writer_stream_class
, writer_event_class
);
2131 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2132 __func__
, __FILE__
, __LINE__
);
2137 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
2138 if (!writer_trace
) {
2139 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2140 __FILE__
, __LINE__
);
2144 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
2146 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
2149 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
2150 writer_event_class
, debug_info
,
2151 debug_it
->debug_info_component
);
2152 if (!writer_event
) {
2153 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2154 __FILE__
, __LINE__
);
2155 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
2156 bt_ctf_event_class_get_name(writer_event_class
));
2160 packet
= bt_ctf_event_get_packet(event
);
2162 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2163 __FILE__
, __LINE__
);
2167 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
2168 if (!writer_packet
) {
2169 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2170 __FILE__
, __LINE__
);
2173 bt_get(writer_packet
);
2175 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
2177 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2178 __FILE__
, __LINE__
);
2179 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
2180 bt_ctf_event_class_get_name(writer_event_class
));
2184 /* Keep the reference on the writer event */
2188 BT_PUT(writer_event
);
2192 bt_put(writer_trace
);
2193 bt_put(writer_packet
);
2195 bt_put(writer_event_class
);
2196 bt_put(writer_stream_class
);
2197 bt_put(stream_class
);
2198 bt_put(event_class
);
2199 return writer_event
;