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
);
1135 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1140 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
1141 BT_PUT(clock_class
);
1143 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1160 struct bt_ctf_stream_class
*insert_new_stream_class(
1161 struct debug_info_iterator
*debug_it
,
1162 struct bt_ctf_stream_class
*stream_class
)
1164 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1165 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
1166 struct debug_info_trace
*di_trace
;
1167 enum bt_component_status ret
;
1170 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1172 fprintf(debug_it
->err
,
1173 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1178 di_trace
= lookup_trace(debug_it
, trace
);
1180 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1181 __FILE__
, __LINE__
);
1182 ret
= BT_COMPONENT_STATUS_ERROR
;
1185 writer_trace
= di_trace
->writer_trace
;
1186 bt_get(writer_trace
);
1188 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1189 writer_trace
, debug_it
->debug_info_component
);
1190 if (!writer_stream_class
) {
1191 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
1192 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1193 __func__
, __FILE__
, __LINE__
);
1197 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
1199 fprintf(debug_it
->err
,
1200 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1205 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1206 writer_stream_class
, trace
);
1207 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1208 fprintf(debug_it
->err
,
1209 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1214 g_hash_table_insert(di_trace
->stream_class_map
,
1215 (gpointer
) stream_class
, writer_stream_class
);
1220 BT_PUT(writer_stream_class
);
1223 bt_put(writer_trace
);
1224 return writer_stream_class
;
1228 struct bt_ctf_stream
*insert_new_stream(
1229 struct debug_info_iterator
*debug_it
,
1230 struct bt_ctf_stream
*stream
,
1231 struct debug_info_trace
*di_trace
)
1233 struct bt_ctf_stream
*writer_stream
= NULL
;
1234 struct bt_ctf_stream_class
*stream_class
= NULL
;
1235 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1237 stream_class
= bt_ctf_stream_get_class(stream
);
1238 if (!stream_class
) {
1239 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1240 __func__
, __FILE__
, __LINE__
);
1244 writer_stream_class
= g_hash_table_lookup(
1245 di_trace
->stream_class_map
,
1246 (gpointer
) stream_class
);
1248 if (!writer_stream_class
) {
1249 writer_stream_class
= insert_new_stream_class(debug_it
,
1251 if (!writer_stream_class
) {
1252 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1253 __func__
, __FILE__
, __LINE__
);
1257 bt_get(writer_stream_class
);
1259 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
1260 bt_ctf_stream_get_name(stream
));
1261 if (!writer_stream
) {
1262 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1263 __func__
, __FILE__
, __LINE__
);
1267 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1273 BT_PUT(writer_stream
);
1275 bt_put(stream_class
);
1276 bt_put(writer_stream_class
);
1277 return writer_stream
;
1281 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1282 struct bt_ctf_stream
*stream
,
1283 struct debug_info_trace
*di_trace
)
1285 return (struct bt_ctf_stream
*) g_hash_table_lookup(
1286 di_trace
->stream_map
, (gpointer
) stream
);
1290 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1291 struct bt_ctf_stream_class
*writer_stream_class
,
1292 struct bt_ctf_event_class
*event_class
)
1294 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
1295 bt_ctf_event_class_get_id(event_class
));
1299 struct debug_info_trace
*lookup_di_trace_from_stream(
1300 struct debug_info_iterator
*debug_it
,
1301 struct bt_ctf_stream
*stream
)
1303 struct bt_ctf_stream_class
*stream_class
= NULL
;
1304 struct bt_ctf_trace
*trace
= NULL
;
1305 struct debug_info_trace
*di_trace
= NULL
;
1307 stream_class
= bt_ctf_stream_get_class(stream
);
1308 if (!stream_class
) {
1309 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1310 __func__
, __FILE__
, __LINE__
);
1314 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1316 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1317 __func__
, __FILE__
, __LINE__
);
1321 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1322 debug_it
->trace_map
, (gpointer
) trace
);
1325 BT_PUT(stream_class
);
1331 struct bt_ctf_stream
*get_writer_stream(
1332 struct debug_info_iterator
*debug_it
,
1333 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
1335 struct bt_ctf_stream_class
*stream_class
= NULL
;
1336 struct bt_ctf_stream
*writer_stream
= NULL
;
1337 struct debug_info_trace
*di_trace
= NULL
;
1339 stream_class
= bt_ctf_stream_get_class(stream
);
1340 if (!stream_class
) {
1341 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1342 __func__
, __FILE__
, __LINE__
);
1346 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1348 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1349 __func__
, __FILE__
, __LINE__
);
1353 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1354 if (!writer_stream
) {
1355 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1356 __func__
, __FILE__
, __LINE__
);
1359 bt_get(writer_stream
);
1364 BT_PUT(writer_stream
);
1366 bt_put(stream_class
);
1367 return writer_stream
;
1371 struct bt_ctf_packet
*debug_info_new_packet(
1372 struct debug_info_iterator
*debug_it
,
1373 struct bt_ctf_packet
*packet
)
1375 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1376 struct bt_ctf_packet
*writer_packet
= NULL
;
1377 struct bt_ctf_field
*packet_context
= NULL
;
1378 struct debug_info_trace
*di_trace
;
1381 stream
= bt_ctf_packet_get_stream(packet
);
1383 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1384 __func__
, __FILE__
, __LINE__
);
1388 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1389 if (!writer_stream
) {
1390 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1391 __func__
, __FILE__
, __LINE__
);
1395 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1397 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1398 __FILE__
, __LINE__
);
1403 * If a packet was already opened, close it and remove it from
1406 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1407 if (writer_packet
) {
1408 g_hash_table_remove(di_trace
->packet_map
, packet
);
1409 BT_PUT(writer_packet
);
1412 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1414 if (!writer_packet
) {
1415 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1416 __func__
, __FILE__
, __LINE__
);
1420 packet_context
= bt_ctf_packet_get_context(packet
);
1421 if (packet_context
) {
1422 int_ret
= ctf_packet_copy_context(debug_it
->err
,
1423 packet
, writer_stream
, writer_packet
);
1425 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1426 __func__
, __FILE__
, __LINE__
);
1429 BT_PUT(packet_context
);
1432 bt_get(writer_packet
);
1438 bt_put(packet_context
);
1439 bt_put(writer_stream
);
1441 return writer_packet
;
1445 struct bt_ctf_packet
*debug_info_close_packet(
1446 struct debug_info_iterator
*debug_it
,
1447 struct bt_ctf_packet
*packet
)
1449 struct bt_ctf_packet
*writer_packet
= NULL
;
1450 struct bt_ctf_stream
*stream
= NULL
;
1451 struct debug_info_trace
*di_trace
;
1453 stream
= bt_ctf_packet_get_stream(packet
);
1455 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1456 __FILE__
, __LINE__
);
1460 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1462 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1463 __FILE__
, __LINE__
);
1467 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1468 if (!writer_packet
) {
1469 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1470 __func__
, __FILE__
, __LINE__
);
1473 bt_get(writer_packet
);
1474 g_hash_table_remove(di_trace
->packet_map
, packet
);
1478 return writer_packet
;
1482 struct bt_ctf_stream
*debug_info_stream_begin(
1483 struct debug_info_iterator
*debug_it
,
1484 struct bt_ctf_stream
*stream
)
1486 struct bt_ctf_stream
*writer_stream
= NULL
;
1487 enum debug_info_stream_state
*state
;
1488 struct debug_info_trace
*di_trace
= NULL
;
1490 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1492 di_trace
= insert_new_trace(debug_it
, stream
);
1494 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1495 __func__
, __FILE__
, __LINE__
);
1500 /* Set the stream as active */
1501 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1503 if (di_trace
->trace_static
) {
1504 fprintf(debug_it
->err
, "[error] Adding a new stream "
1505 "on a static trace\n");
1508 state
= insert_new_stream_state(debug_it
, di_trace
,
1511 fprintf(debug_it
->err
, "[error] Adding a new stream "
1512 "on a static trace\n");
1516 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1517 fprintf(debug_it
->err
, "[error] Unexpected stream state %d\n",
1521 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1523 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1524 if (!writer_stream
) {
1525 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1527 bt_get(writer_stream
);
1532 BT_PUT(writer_stream
);
1534 return writer_stream
;
1538 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1539 struct bt_ctf_stream
*stream
)
1541 struct bt_ctf_stream
*writer_stream
= NULL
;
1542 struct debug_info_trace
*di_trace
= NULL
;
1543 enum debug_info_stream_state
*state
;
1545 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1547 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1548 __func__
, __FILE__
, __LINE__
);
1552 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1553 if (!writer_stream
) {
1554 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1555 __func__
, __FILE__
, __LINE__
);
1559 * Take the ref on the stream and keep it until the notification
1562 bt_get(writer_stream
);
1564 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1565 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1566 fprintf(debug_it
->err
, "[error] Unexpected stream "
1567 "state %d\n", *state
);
1570 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1572 g_hash_table_remove(di_trace
->stream_map
, stream
);
1574 if (di_trace
->trace_static
) {
1575 int trace_completed
= 1;
1577 g_hash_table_foreach(di_trace
->stream_states
,
1578 check_completed_trace
, &trace_completed
);
1579 if (trace_completed
) {
1580 debug_info_close_trace(debug_it
, di_trace
);
1581 g_hash_table_remove(debug_it
->trace_map
,
1589 BT_PUT(writer_stream
);
1592 return writer_stream
;
1596 struct debug_info_source
*lookup_debug_info(FILE *err
,
1597 struct bt_ctf_event
*event
,
1598 struct debug_info
*debug_info
)
1602 struct debug_info_source
*dbg_info_src
= NULL
;
1605 ret
= get_stream_event_context_int_field_value(err
, event
,
1611 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1617 /* Get debug info for this context. */
1618 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1621 return dbg_info_src
;
1625 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1626 struct debug_info_source
*dbg_info_src
,
1627 struct debug_info_component
*component
)
1629 int i
, nr_fields
, ret
= 0;
1630 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1631 struct bt_ctf_field
*field
= NULL
;
1632 struct bt_ctf_field_type
*field_type
= NULL
;
1634 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1635 if (!debug_field_type
) {
1636 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1637 __FILE__
, __LINE__
);
1641 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1642 for (i
= 0; i
< nr_fields
; i
++) {
1643 const char *field_name
;
1645 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1646 &field_name
, &field_type
, i
) < 0) {
1647 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1648 __FILE__
, __LINE__
);
1653 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1654 if (!strcmp(field_name
, "bin")) {
1655 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1656 GString
*tmp
= g_string_new(NULL
);
1658 if (component
->arg_full_path
) {
1659 g_string_printf(tmp
, "%s%s",
1660 dbg_info_src
->bin_path
,
1661 dbg_info_src
->bin_loc
);
1663 g_string_printf(tmp
, "%s%s",
1664 dbg_info_src
->short_bin_path
,
1665 dbg_info_src
->bin_loc
);
1667 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1668 g_string_free(tmp
, true);
1670 ret
= bt_ctf_field_string_set_value(field
, "");
1672 } else if (!strcmp(field_name
, "func")) {
1673 if (dbg_info_src
&& dbg_info_src
->func
) {
1674 ret
= bt_ctf_field_string_set_value(field
,
1675 dbg_info_src
->func
);
1677 ret
= bt_ctf_field_string_set_value(field
, "");
1679 } else if (!strcmp(field_name
, "src")) {
1680 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1681 GString
*tmp
= g_string_new(NULL
);
1683 if (component
->arg_full_path
) {
1684 g_string_printf(tmp
, "%s:%" PRId64
,
1685 dbg_info_src
->src_path
,
1686 dbg_info_src
->line_no
);
1688 g_string_printf(tmp
, "%s:%" PRId64
,
1689 dbg_info_src
->short_src_path
,
1690 dbg_info_src
->line_no
);
1692 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1693 g_string_free(tmp
, true);
1695 ret
= bt_ctf_field_string_set_value(field
, "");
1700 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1701 __FILE__
, __LINE__
);
1713 bt_put(debug_field_type
);
1718 int copy_set_debug_info_stream_event_context(FILE *err
,
1719 struct bt_ctf_field
*event_context
,
1720 struct bt_ctf_event
*event
,
1721 struct bt_ctf_event
*writer_event
,
1722 struct debug_info
*debug_info
,
1723 struct debug_info_component
*component
)
1725 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1726 *event_context_type
= NULL
;
1727 struct bt_ctf_field
*writer_event_context
= NULL
;
1728 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1729 struct bt_ctf_field_type
*field_type
= NULL
;
1730 struct debug_info_source
*dbg_info_src
;
1731 int ret
, nr_fields
, i
;
1733 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1734 if (!writer_event_context
) {
1735 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1739 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1740 if (!writer_event_context_type
) {
1741 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1742 __FILE__
, __LINE__
);
1746 event_context_type
= bt_ctf_field_get_type(event_context
);
1747 if (!event_context_type
) {
1748 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1749 __FILE__
, __LINE__
);
1754 * If it is not a structure, we did not modify it to add the debug info
1755 * fields, so just assign it as is.
1757 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1758 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1762 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1764 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1765 for (i
= 0; i
< nr_fields
; i
++) {
1766 const char *field_name
;
1768 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1769 &field_name
, &field_type
, i
) < 0) {
1770 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1771 __FILE__
, __LINE__
);
1776 * Prevent illegal access in the event_context.
1778 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1779 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1782 * The debug_info field, only exists in the writer event or
1783 * if it was set by a earlier pass of the debug_info plugin.
1785 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1787 debug_field
= bt_ctf_field_structure_get_field_by_index(
1788 writer_event_context
, i
);
1790 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1791 __FILE__
, __LINE__
);
1794 ret
= set_debug_info_field(err
, debug_field
,
1795 dbg_info_src
, component
);
1797 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1798 __FILE__
, __LINE__
);
1801 BT_PUT(debug_field
);
1803 copy_field
= bt_ctf_field_copy(field
);
1805 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1806 __FILE__
, __LINE__
);
1810 ret
= bt_ctf_field_structure_set_field_by_name(
1811 writer_event_context
,
1812 field_name
, copy_field
);
1814 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1815 __FILE__
, __LINE__
);
1830 bt_put(event_context_type
);
1831 bt_put(writer_event_context_type
);
1832 bt_put(writer_event_context
);
1835 bt_put(debug_field
);
1841 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1842 struct bt_ctf_stream_class
*stream_class
)
1844 struct bt_ctf_trace
*trace
= NULL
;
1845 struct bt_ctf_clock_class
*clock_class
= NULL
;
1847 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1849 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1854 if (!bt_ctf_trace_get_clock_class_count(trace
)) {
1859 /* FIXME multi-clock? */
1860 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1869 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1871 struct bt_ctf_event_class
*event_class
= NULL
;
1872 struct bt_ctf_stream_class
*stream_class
= NULL
;
1873 struct bt_ctf_clock_class
*clock_class
= NULL
;
1875 event_class
= bt_ctf_event_get_class(event
);
1877 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1882 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1883 if (!stream_class
) {
1884 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1889 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1893 BT_PUT(clock_class
);
1895 bt_put(stream_class
);
1896 bt_put(event_class
);
1901 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1902 struct bt_ctf_event
*writer_event
)
1904 struct bt_ctf_clock_class
*clock_class
= NULL
;
1905 struct bt_ctf_clock_value
*clock_value
= NULL
;
1908 clock_class
= event_get_clock_class(err
, event
);
1910 /* No clock on input trace. */
1914 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1916 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1922 * We share the same clocks, so we can assign the clock value to the
1925 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1927 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1938 bt_put(clock_class
);
1939 bt_put(clock_value
);
1944 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1945 struct bt_ctf_event_class
*writer_event_class
,
1946 struct debug_info
*debug_info
,
1947 struct debug_info_component
*component
)
1949 struct bt_ctf_event
*writer_event
= NULL
;
1950 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1953 writer_event
= bt_ctf_event_create(writer_event_class
);
1954 if (!writer_event
) {
1955 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1960 ret
= set_event_clock_value(err
, event
, writer_event
);
1962 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1963 __FILE__
, __LINE__
);
1967 /* Optional field, so it can fail silently. */
1968 field
= bt_ctf_event_get_header(event
);
1970 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1971 writer_event
, field
);
1973 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1974 __FILE__
, __LINE__
);
1980 /* Optional field, so it can fail silently. */
1981 field
= bt_ctf_event_get_stream_event_context(event
);
1983 ret
= copy_set_debug_info_stream_event_context(err
,
1984 field
, event
, writer_event
, debug_info
,
1987 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1988 __FILE__
, __LINE__
);
1994 /* Optional field, so it can fail silently. */
1995 field
= bt_ctf_event_get_event_context(event
);
1997 copy_field
= bt_ctf_field_copy(field
);
1999 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2000 __FILE__
, __LINE__
);
2003 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
2005 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2006 __FILE__
, __LINE__
);
2013 field
= bt_ctf_event_get_event_payload(event
);
2015 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2016 __FILE__
, __LINE__
);
2019 copy_field
= bt_ctf_field_copy(field
);
2021 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
2023 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2024 __FILE__
, __LINE__
);
2034 BT_PUT(writer_event
);
2038 return writer_event
;
2042 struct bt_ctf_event
*debug_info_output_event(
2043 struct debug_info_iterator
*debug_it
,
2044 struct bt_ctf_event
*event
)
2046 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
2047 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
2048 struct bt_ctf_event
*writer_event
= NULL
;
2049 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
2050 struct bt_ctf_trace
*writer_trace
= NULL
;
2051 struct bt_ctf_stream
*stream
= NULL
;
2052 struct debug_info_trace
*di_trace
;
2053 struct debug_info
*debug_info
;
2054 const char *event_name
;
2057 event_class
= bt_ctf_event_get_class(event
);
2059 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2060 __FILE__
, __LINE__
);
2064 event_name
= bt_ctf_event_class_get_name(event_class
);
2066 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2067 __FILE__
, __LINE__
);
2071 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
2072 if (!stream_class
) {
2073 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2074 __FILE__
, __LINE__
);
2077 stream
= bt_ctf_event_get_stream(event
);
2079 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2080 __FILE__
, __LINE__
);
2083 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
2085 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2086 __FILE__
, __LINE__
);
2090 writer_stream_class
= g_hash_table_lookup(
2091 di_trace
->stream_class_map
,
2092 (gpointer
) stream_class
);
2093 if (!writer_stream_class
) {
2094 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2095 __FILE__
, __LINE__
);
2098 bt_get(writer_stream_class
);
2100 writer_event_class
= get_event_class(debug_it
,
2101 writer_stream_class
, event_class
);
2102 if (!writer_event_class
) {
2103 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
2105 if (!writer_event_class
) {
2106 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2107 __func__
, __FILE__
, __LINE__
);
2110 int_ret
= bt_ctf_stream_class_add_event_class(
2111 writer_stream_class
, writer_event_class
);
2113 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2114 __func__
, __FILE__
, __LINE__
);
2119 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
2120 if (!writer_trace
) {
2121 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2122 __FILE__
, __LINE__
);
2126 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
2128 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
2131 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
2132 writer_event_class
, debug_info
,
2133 debug_it
->debug_info_component
);
2134 if (!writer_event
) {
2135 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2136 __FILE__
, __LINE__
);
2137 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
2138 bt_ctf_event_class_get_name(writer_event_class
));
2142 packet
= bt_ctf_event_get_packet(event
);
2144 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2145 __FILE__
, __LINE__
);
2149 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
2150 if (!writer_packet
) {
2151 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2152 __FILE__
, __LINE__
);
2155 bt_get(writer_packet
);
2157 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
2159 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2160 __FILE__
, __LINE__
);
2161 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
2162 bt_ctf_event_class_get_name(writer_event_class
));
2166 /* Keep the reference on the writer event */
2170 BT_PUT(writer_event
);
2174 bt_put(writer_trace
);
2175 bt_put(writer_packet
);
2177 bt_put(writer_event_class
);
2178 bt_put(writer_stream_class
);
2179 bt_put(stream_class
);
2180 bt_put(event_class
);
2181 return writer_event
;