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 if (strlen(name
) == 0) {
1052 writer_stream_class
= bt_ctf_stream_class_create_empty(name
);
1053 if (!writer_stream_class
) {
1054 fprintf(err
, "[error] %s in %s:%d\n",
1055 __func__
, __FILE__
, __LINE__
);
1059 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
1061 ret_int
= bt_ctf_stream_class_set_packet_context_type(
1062 writer_stream_class
, type
);
1064 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1071 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
1073 ret_int
= bt_ctf_stream_class_set_event_header_type(
1074 writer_stream_class
, type
);
1076 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1083 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
1085 writer_event_context_type
= bt_ctf_field_type_structure_create();
1086 if (!writer_event_context_type
) {
1087 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1091 ret_int
= create_debug_info_event_context_type(err
, type
,
1092 writer_event_context_type
, component
);
1094 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1100 ret_int
= bt_ctf_stream_class_set_event_context_type(
1101 writer_stream_class
, writer_event_context_type
);
1103 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1107 BT_PUT(writer_event_context_type
);
1113 BT_PUT(writer_stream_class
);
1115 bt_put(writer_event_context_type
);
1117 return writer_stream_class
;
1121 * Add the original clock classes to the new trace, we do not need to copy
1122 * them, and if we did, we would have to manually inspect the stream class
1123 * to update the integers mapping to a clock.
1126 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
1127 struct bt_ctf_stream_class
*writer_stream_class
,
1128 struct bt_ctf_trace
*trace
)
1130 int ret
, clock_class_count
, i
;
1132 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
1134 for (i
= 0; i
< clock_class_count
; i
++) {
1135 struct bt_ctf_clock_class
*clock_class
=
1136 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
1139 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1144 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
1145 BT_PUT(clock_class
);
1147 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1164 struct bt_ctf_stream_class
*insert_new_stream_class(
1165 struct debug_info_iterator
*debug_it
,
1166 struct bt_ctf_stream_class
*stream_class
)
1168 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1169 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
1170 struct debug_info_trace
*di_trace
;
1171 enum bt_component_status ret
;
1174 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1176 fprintf(debug_it
->err
,
1177 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1182 di_trace
= lookup_trace(debug_it
, trace
);
1184 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1185 __FILE__
, __LINE__
);
1186 ret
= BT_COMPONENT_STATUS_ERROR
;
1189 writer_trace
= di_trace
->writer_trace
;
1190 bt_get(writer_trace
);
1192 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1193 writer_trace
, debug_it
->debug_info_component
);
1194 if (!writer_stream_class
) {
1195 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
1196 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1197 __func__
, __FILE__
, __LINE__
);
1201 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
1203 fprintf(debug_it
->err
,
1204 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1209 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1210 writer_stream_class
, trace
);
1211 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1212 fprintf(debug_it
->err
,
1213 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1218 g_hash_table_insert(di_trace
->stream_class_map
,
1219 (gpointer
) stream_class
, writer_stream_class
);
1224 BT_PUT(writer_stream_class
);
1227 bt_put(writer_trace
);
1228 return writer_stream_class
;
1232 struct bt_ctf_stream
*insert_new_stream(
1233 struct debug_info_iterator
*debug_it
,
1234 struct bt_ctf_stream
*stream
,
1235 struct debug_info_trace
*di_trace
)
1237 struct bt_ctf_stream
*writer_stream
= NULL
;
1238 struct bt_ctf_stream_class
*stream_class
= NULL
;
1239 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1241 stream_class
= bt_ctf_stream_get_class(stream
);
1242 if (!stream_class
) {
1243 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1244 __func__
, __FILE__
, __LINE__
);
1248 writer_stream_class
= g_hash_table_lookup(
1249 di_trace
->stream_class_map
,
1250 (gpointer
) stream_class
);
1252 if (!writer_stream_class
) {
1253 writer_stream_class
= insert_new_stream_class(debug_it
,
1255 if (!writer_stream_class
) {
1256 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1257 __func__
, __FILE__
, __LINE__
);
1261 bt_get(writer_stream_class
);
1263 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
1264 bt_ctf_stream_get_name(stream
));
1265 if (!writer_stream
) {
1266 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1267 __func__
, __FILE__
, __LINE__
);
1271 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1277 BT_PUT(writer_stream
);
1279 bt_put(stream_class
);
1280 bt_put(writer_stream_class
);
1281 return writer_stream
;
1285 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1286 struct bt_ctf_stream
*stream
,
1287 struct debug_info_trace
*di_trace
)
1289 return (struct bt_ctf_stream
*) g_hash_table_lookup(
1290 di_trace
->stream_map
, (gpointer
) stream
);
1294 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1295 struct bt_ctf_stream_class
*writer_stream_class
,
1296 struct bt_ctf_event_class
*event_class
)
1298 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
1299 bt_ctf_event_class_get_id(event_class
));
1303 struct debug_info_trace
*lookup_di_trace_from_stream(
1304 struct debug_info_iterator
*debug_it
,
1305 struct bt_ctf_stream
*stream
)
1307 struct bt_ctf_stream_class
*stream_class
= NULL
;
1308 struct bt_ctf_trace
*trace
= NULL
;
1309 struct debug_info_trace
*di_trace
= NULL
;
1311 stream_class
= bt_ctf_stream_get_class(stream
);
1312 if (!stream_class
) {
1313 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1314 __func__
, __FILE__
, __LINE__
);
1318 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1320 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1321 __func__
, __FILE__
, __LINE__
);
1325 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1326 debug_it
->trace_map
, (gpointer
) trace
);
1329 BT_PUT(stream_class
);
1335 struct bt_ctf_stream
*get_writer_stream(
1336 struct debug_info_iterator
*debug_it
,
1337 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
1339 struct bt_ctf_stream_class
*stream_class
= NULL
;
1340 struct bt_ctf_stream
*writer_stream
= NULL
;
1341 struct debug_info_trace
*di_trace
= NULL
;
1343 stream_class
= bt_ctf_stream_get_class(stream
);
1344 if (!stream_class
) {
1345 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1346 __func__
, __FILE__
, __LINE__
);
1350 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1352 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1353 __func__
, __FILE__
, __LINE__
);
1357 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1358 if (!writer_stream
) {
1359 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1360 __func__
, __FILE__
, __LINE__
);
1363 bt_get(writer_stream
);
1368 BT_PUT(writer_stream
);
1370 bt_put(stream_class
);
1371 return writer_stream
;
1375 struct bt_ctf_packet
*debug_info_new_packet(
1376 struct debug_info_iterator
*debug_it
,
1377 struct bt_ctf_packet
*packet
)
1379 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1380 struct bt_ctf_packet
*writer_packet
= NULL
;
1381 struct bt_ctf_field
*packet_context
= NULL
;
1382 struct debug_info_trace
*di_trace
;
1385 stream
= bt_ctf_packet_get_stream(packet
);
1387 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1388 __func__
, __FILE__
, __LINE__
);
1392 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1393 if (!writer_stream
) {
1394 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1395 __func__
, __FILE__
, __LINE__
);
1399 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1401 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1402 __FILE__
, __LINE__
);
1407 * If a packet was already opened, close it and remove it from
1410 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1411 if (writer_packet
) {
1412 g_hash_table_remove(di_trace
->packet_map
, packet
);
1413 BT_PUT(writer_packet
);
1416 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1418 if (!writer_packet
) {
1419 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1420 __func__
, __FILE__
, __LINE__
);
1424 packet_context
= bt_ctf_packet_get_context(packet
);
1425 if (packet_context
) {
1426 int_ret
= ctf_packet_copy_context(debug_it
->err
,
1427 packet
, writer_stream
, writer_packet
);
1429 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1430 __func__
, __FILE__
, __LINE__
);
1433 BT_PUT(packet_context
);
1436 bt_get(writer_packet
);
1442 bt_put(packet_context
);
1443 bt_put(writer_stream
);
1445 return writer_packet
;
1449 struct bt_ctf_packet
*debug_info_close_packet(
1450 struct debug_info_iterator
*debug_it
,
1451 struct bt_ctf_packet
*packet
)
1453 struct bt_ctf_packet
*writer_packet
= NULL
;
1454 struct bt_ctf_stream
*stream
= NULL
;
1455 struct debug_info_trace
*di_trace
;
1457 stream
= bt_ctf_packet_get_stream(packet
);
1459 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1460 __FILE__
, __LINE__
);
1464 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1466 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1467 __FILE__
, __LINE__
);
1471 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1472 if (!writer_packet
) {
1473 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1474 __func__
, __FILE__
, __LINE__
);
1477 bt_get(writer_packet
);
1478 g_hash_table_remove(di_trace
->packet_map
, packet
);
1482 return writer_packet
;
1486 struct bt_ctf_stream
*debug_info_stream_begin(
1487 struct debug_info_iterator
*debug_it
,
1488 struct bt_ctf_stream
*stream
)
1490 struct bt_ctf_stream
*writer_stream
= NULL
;
1491 enum debug_info_stream_state
*state
;
1492 struct debug_info_trace
*di_trace
= NULL
;
1494 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1496 di_trace
= insert_new_trace(debug_it
, stream
);
1498 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1499 __func__
, __FILE__
, __LINE__
);
1504 /* Set the stream as active */
1505 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1507 if (di_trace
->trace_static
) {
1508 fprintf(debug_it
->err
, "[error] Adding a new stream "
1509 "on a static trace\n");
1512 state
= insert_new_stream_state(debug_it
, di_trace
,
1515 fprintf(debug_it
->err
, "[error] Adding a new stream "
1516 "on a static trace\n");
1520 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1521 fprintf(debug_it
->err
, "[error] Unexpected stream state %d\n",
1525 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1527 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1528 if (!writer_stream
) {
1529 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1531 bt_get(writer_stream
);
1536 BT_PUT(writer_stream
);
1538 return writer_stream
;
1542 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1543 struct bt_ctf_stream
*stream
)
1545 struct bt_ctf_stream
*writer_stream
= NULL
;
1546 struct debug_info_trace
*di_trace
= NULL
;
1547 enum debug_info_stream_state
*state
;
1549 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1551 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1552 __func__
, __FILE__
, __LINE__
);
1556 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1557 if (!writer_stream
) {
1558 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1559 __func__
, __FILE__
, __LINE__
);
1563 * Take the ref on the stream and keep it until the notification
1566 bt_get(writer_stream
);
1568 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1569 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1570 fprintf(debug_it
->err
, "[error] Unexpected stream "
1571 "state %d\n", *state
);
1574 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1576 g_hash_table_remove(di_trace
->stream_map
, stream
);
1578 if (di_trace
->trace_static
) {
1579 int trace_completed
= 1;
1581 g_hash_table_foreach(di_trace
->stream_states
,
1582 check_completed_trace
, &trace_completed
);
1583 if (trace_completed
) {
1584 debug_info_close_trace(debug_it
, di_trace
);
1585 g_hash_table_remove(debug_it
->trace_map
,
1593 BT_PUT(writer_stream
);
1596 return writer_stream
;
1600 struct debug_info_source
*lookup_debug_info(FILE *err
,
1601 struct bt_ctf_event
*event
,
1602 struct debug_info
*debug_info
)
1606 struct debug_info_source
*dbg_info_src
= NULL
;
1609 ret
= get_stream_event_context_int_field_value(err
, event
,
1615 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1621 /* Get debug info for this context. */
1622 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1625 return dbg_info_src
;
1629 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1630 struct debug_info_source
*dbg_info_src
,
1631 struct debug_info_component
*component
)
1633 int i
, nr_fields
, ret
= 0;
1634 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1635 struct bt_ctf_field
*field
= NULL
;
1636 struct bt_ctf_field_type
*field_type
= NULL
;
1638 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1639 if (!debug_field_type
) {
1640 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1641 __FILE__
, __LINE__
);
1645 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1646 for (i
= 0; i
< nr_fields
; i
++) {
1647 const char *field_name
;
1649 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1650 &field_name
, &field_type
, i
) < 0) {
1651 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1652 __FILE__
, __LINE__
);
1657 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1658 if (!strcmp(field_name
, "bin")) {
1659 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1660 GString
*tmp
= g_string_new(NULL
);
1662 if (component
->arg_full_path
) {
1663 g_string_printf(tmp
, "%s%s",
1664 dbg_info_src
->bin_path
,
1665 dbg_info_src
->bin_loc
);
1667 g_string_printf(tmp
, "%s%s",
1668 dbg_info_src
->short_bin_path
,
1669 dbg_info_src
->bin_loc
);
1671 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1672 g_string_free(tmp
, true);
1674 ret
= bt_ctf_field_string_set_value(field
, "");
1676 } else if (!strcmp(field_name
, "func")) {
1677 if (dbg_info_src
&& dbg_info_src
->func
) {
1678 ret
= bt_ctf_field_string_set_value(field
,
1679 dbg_info_src
->func
);
1681 ret
= bt_ctf_field_string_set_value(field
, "");
1683 } else if (!strcmp(field_name
, "src")) {
1684 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1685 GString
*tmp
= g_string_new(NULL
);
1687 if (component
->arg_full_path
) {
1688 g_string_printf(tmp
, "%s:%" PRId64
,
1689 dbg_info_src
->src_path
,
1690 dbg_info_src
->line_no
);
1692 g_string_printf(tmp
, "%s:%" PRId64
,
1693 dbg_info_src
->short_src_path
,
1694 dbg_info_src
->line_no
);
1696 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1697 g_string_free(tmp
, true);
1699 ret
= bt_ctf_field_string_set_value(field
, "");
1704 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1705 __FILE__
, __LINE__
);
1717 bt_put(debug_field_type
);
1722 int copy_set_debug_info_stream_event_context(FILE *err
,
1723 struct bt_ctf_field
*event_context
,
1724 struct bt_ctf_event
*event
,
1725 struct bt_ctf_event
*writer_event
,
1726 struct debug_info
*debug_info
,
1727 struct debug_info_component
*component
)
1729 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1730 *event_context_type
= NULL
;
1731 struct bt_ctf_field
*writer_event_context
= NULL
;
1732 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1733 struct bt_ctf_field_type
*field_type
= NULL
;
1734 struct debug_info_source
*dbg_info_src
;
1735 int ret
, nr_fields
, i
;
1737 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1738 if (!writer_event_context
) {
1739 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1743 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1744 if (!writer_event_context_type
) {
1745 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1746 __FILE__
, __LINE__
);
1750 event_context_type
= bt_ctf_field_get_type(event_context
);
1751 if (!event_context_type
) {
1752 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1753 __FILE__
, __LINE__
);
1758 * If it is not a structure, we did not modify it to add the debug info
1759 * fields, so just assign it as is.
1761 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1762 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1766 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1768 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1769 for (i
= 0; i
< nr_fields
; i
++) {
1770 const char *field_name
;
1772 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1773 &field_name
, &field_type
, i
) < 0) {
1774 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1775 __FILE__
, __LINE__
);
1780 * Prevent illegal access in the event_context.
1782 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1783 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1786 * The debug_info field, only exists in the writer event or
1787 * if it was set by a earlier pass of the debug_info plugin.
1789 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1791 debug_field
= bt_ctf_field_structure_get_field_by_index(
1792 writer_event_context
, i
);
1794 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1795 __FILE__
, __LINE__
);
1798 ret
= set_debug_info_field(err
, debug_field
,
1799 dbg_info_src
, component
);
1801 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1802 __FILE__
, __LINE__
);
1805 BT_PUT(debug_field
);
1807 copy_field
= bt_ctf_field_copy(field
);
1809 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1810 __FILE__
, __LINE__
);
1814 ret
= bt_ctf_field_structure_set_field_by_name(
1815 writer_event_context
,
1816 field_name
, copy_field
);
1818 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1819 __FILE__
, __LINE__
);
1834 bt_put(event_context_type
);
1835 bt_put(writer_event_context_type
);
1836 bt_put(writer_event_context
);
1839 bt_put(debug_field
);
1845 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1846 struct bt_ctf_stream_class
*stream_class
)
1848 struct bt_ctf_trace
*trace
= NULL
;
1849 struct bt_ctf_clock_class
*clock_class
= NULL
;
1851 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1853 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1858 if (!bt_ctf_trace_get_clock_class_count(trace
)) {
1863 /* FIXME multi-clock? */
1864 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1873 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1875 struct bt_ctf_event_class
*event_class
= NULL
;
1876 struct bt_ctf_stream_class
*stream_class
= NULL
;
1877 struct bt_ctf_clock_class
*clock_class
= NULL
;
1879 event_class
= bt_ctf_event_get_class(event
);
1881 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1886 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1887 if (!stream_class
) {
1888 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1893 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1897 BT_PUT(clock_class
);
1899 bt_put(stream_class
);
1900 bt_put(event_class
);
1905 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1906 struct bt_ctf_event
*writer_event
)
1908 struct bt_ctf_clock_class
*clock_class
= NULL
;
1909 struct bt_ctf_clock_value
*clock_value
= NULL
;
1912 clock_class
= event_get_clock_class(err
, event
);
1914 /* No clock on input trace. */
1918 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1920 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1926 * We share the same clocks, so we can assign the clock value to the
1929 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1931 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1942 bt_put(clock_class
);
1943 bt_put(clock_value
);
1948 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1949 struct bt_ctf_event_class
*writer_event_class
,
1950 struct debug_info
*debug_info
,
1951 struct debug_info_component
*component
)
1953 struct bt_ctf_event
*writer_event
= NULL
;
1954 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1957 writer_event
= bt_ctf_event_create(writer_event_class
);
1958 if (!writer_event
) {
1959 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1964 ret
= set_event_clock_value(err
, event
, writer_event
);
1966 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1967 __FILE__
, __LINE__
);
1971 /* Optional field, so it can fail silently. */
1972 field
= bt_ctf_event_get_header(event
);
1974 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1975 writer_event
, field
);
1977 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1978 __FILE__
, __LINE__
);
1984 /* Optional field, so it can fail silently. */
1985 field
= bt_ctf_event_get_stream_event_context(event
);
1987 ret
= copy_set_debug_info_stream_event_context(err
,
1988 field
, event
, writer_event
, debug_info
,
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_event_context(event
);
2001 copy_field
= bt_ctf_field_copy(field
);
2003 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2004 __FILE__
, __LINE__
);
2007 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
2009 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2010 __FILE__
, __LINE__
);
2017 field
= bt_ctf_event_get_event_payload(event
);
2019 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2020 __FILE__
, __LINE__
);
2023 copy_field
= bt_ctf_field_copy(field
);
2025 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
2027 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2028 __FILE__
, __LINE__
);
2038 BT_PUT(writer_event
);
2042 return writer_event
;
2046 struct bt_ctf_event
*debug_info_output_event(
2047 struct debug_info_iterator
*debug_it
,
2048 struct bt_ctf_event
*event
)
2050 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
2051 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
2052 struct bt_ctf_event
*writer_event
= NULL
;
2053 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
2054 struct bt_ctf_trace
*writer_trace
= NULL
;
2055 struct bt_ctf_stream
*stream
= NULL
;
2056 struct debug_info_trace
*di_trace
;
2057 struct debug_info
*debug_info
;
2058 const char *event_name
;
2061 event_class
= bt_ctf_event_get_class(event
);
2063 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2064 __FILE__
, __LINE__
);
2068 event_name
= bt_ctf_event_class_get_name(event_class
);
2070 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2071 __FILE__
, __LINE__
);
2075 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
2076 if (!stream_class
) {
2077 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2078 __FILE__
, __LINE__
);
2081 stream
= bt_ctf_event_get_stream(event
);
2083 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2084 __FILE__
, __LINE__
);
2087 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
2089 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2090 __FILE__
, __LINE__
);
2094 writer_stream_class
= g_hash_table_lookup(
2095 di_trace
->stream_class_map
,
2096 (gpointer
) stream_class
);
2097 if (!writer_stream_class
) {
2098 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2099 __FILE__
, __LINE__
);
2102 bt_get(writer_stream_class
);
2104 writer_event_class
= get_event_class(debug_it
,
2105 writer_stream_class
, event_class
);
2106 if (!writer_event_class
) {
2107 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
2109 if (!writer_event_class
) {
2110 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2111 __func__
, __FILE__
, __LINE__
);
2114 int_ret
= bt_ctf_stream_class_add_event_class(
2115 writer_stream_class
, writer_event_class
);
2117 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2118 __func__
, __FILE__
, __LINE__
);
2123 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
2124 if (!writer_trace
) {
2125 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2126 __FILE__
, __LINE__
);
2130 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
2132 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
2135 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
2136 writer_event_class
, debug_info
,
2137 debug_it
->debug_info_component
);
2138 if (!writer_event
) {
2139 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2140 __FILE__
, __LINE__
);
2141 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
2142 bt_ctf_event_class_get_name(writer_event_class
));
2146 packet
= bt_ctf_event_get_packet(event
);
2148 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2149 __FILE__
, __LINE__
);
2153 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
2154 if (!writer_packet
) {
2155 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2156 __FILE__
, __LINE__
);
2159 bt_get(writer_packet
);
2161 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
2163 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2164 __FILE__
, __LINE__
);
2165 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
2166 bt_ctf_event_class_get_name(writer_event_class
));
2170 /* Keep the reference on the writer event */
2174 BT_PUT(writer_event
);
2178 bt_put(writer_trace
);
2179 bt_put(writer_packet
);
2181 bt_put(writer_event_class
);
2182 bt_put(writer_stream_class
);
2183 bt_put(stream_class
);
2184 bt_put(event_class
);
2185 return writer_event
;