4 * Babeltrace Copy Trace Structure
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
8 * Author: Julien Desfossez <jdesfossez@efficios.com>
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 #include <babeltrace/ctf-ir/event.h>
31 #include <babeltrace/ctf-ir/packet.h>
32 #include <babeltrace/ctf-ir/event-class.h>
33 #include <babeltrace/ctf-ir/stream.h>
34 #include <babeltrace/ctf-ir/stream-class.h>
35 #include <babeltrace/ctf-ir/clock-class.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-writer/stream-class.h>
38 #include <babeltrace/ctf-writer/stream.h>
40 #include <ctfcopytrace.h>
41 #include "debug-info.h"
44 struct bt_ctf_stream
*insert_new_stream(
45 struct debug_info_iterator
*debug_it
,
46 struct bt_ctf_stream
*stream
,
47 struct debug_info_trace
*di_trace
);
50 void unref_stream(struct bt_ctf_stream
*stream
)
56 void unref_packet(struct bt_ctf_packet
*packet
)
62 void unref_stream_class(struct bt_ctf_stream_class
*stream_class
)
68 void unref_debug_info(struct debug_info
*debug_info
)
70 debug_info_destroy(debug_info
);
74 void destroy_stream_state_key(gpointer key
)
76 g_free((enum fs_writer_stream_state
*) key
);
80 struct bt_ctf_field
*get_payload_field(FILE *err
,
81 struct bt_ctf_event
*event
, const char *field_name
)
83 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
84 struct bt_ctf_field_type
*sec_type
= NULL
;
86 sec
= bt_ctf_event_get_payload(event
, NULL
);
88 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
93 sec_type
= bt_ctf_field_get_type(sec
);
95 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
100 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
101 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
106 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
115 struct bt_ctf_field
*get_stream_event_context_field(FILE *err
,
116 struct bt_ctf_event
*event
, const char *field_name
)
118 struct bt_ctf_field
*field
= NULL
, *sec
= NULL
;
119 struct bt_ctf_field_type
*sec_type
= NULL
;
121 sec
= bt_ctf_event_get_stream_event_context(event
);
126 sec_type
= bt_ctf_field_get_type(sec
);
128 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
133 if (bt_ctf_field_type_get_type_id(sec_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
134 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
139 field
= bt_ctf_field_structure_get_field(sec
, field_name
);
148 int get_stream_event_context_unsigned_int_field_value(FILE *err
,
149 struct bt_ctf_event
*event
, const char *field_name
,
153 struct bt_ctf_field
*field
= NULL
;
154 struct bt_ctf_field_type
*field_type
= NULL
;
156 field
= get_stream_event_context_field(err
, event
, field_name
);
161 field_type
= bt_ctf_field_get_type(field
);
163 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
168 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
169 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
174 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
175 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
180 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
192 int get_stream_event_context_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
193 const char *field_name
, int64_t *value
)
195 struct bt_ctf_field
*field
= NULL
;
196 struct bt_ctf_field_type
*field_type
= NULL
;
199 field
= get_stream_event_context_field(err
, event
, field_name
);
204 field_type
= bt_ctf_field_get_type(field
);
206 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
211 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
212 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
217 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
218 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
223 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
235 int get_payload_unsigned_int_field_value(FILE *err
,
236 struct bt_ctf_event
*event
, const char *field_name
,
239 struct bt_ctf_field
*field
= NULL
;
240 struct bt_ctf_field_type
*field_type
= NULL
;
243 field
= get_payload_field(err
, event
, field_name
);
245 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
250 field_type
= bt_ctf_field_get_type(field
);
252 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
257 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
258 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
263 if (bt_ctf_field_type_integer_get_signed(field_type
) != 0) {
264 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
269 ret
= bt_ctf_field_unsigned_integer_get_value(field
, value
);
281 int get_payload_int_field_value(FILE *err
, struct bt_ctf_event
*event
,
282 const char *field_name
, int64_t *value
)
284 struct bt_ctf_field
*field
= NULL
;
285 struct bt_ctf_field_type
*field_type
= NULL
;
288 field
= get_payload_field(err
, event
, field_name
);
290 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
295 field_type
= bt_ctf_field_get_type(field
);
297 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
302 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_INTEGER
) {
303 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
308 if (bt_ctf_field_type_integer_get_signed(field_type
) != 1) {
309 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
314 ret
= bt_ctf_field_signed_integer_get_value(field
, value
);
326 int get_payload_string_field_value(FILE *err
,
327 struct bt_ctf_event
*event
, const char *field_name
,
330 struct bt_ctf_field
*field
= NULL
;
331 struct bt_ctf_field_type
*field_type
= NULL
;
335 * The field might not exist, no error here.
337 field
= get_payload_field(err
, event
, field_name
);
342 field_type
= bt_ctf_field_get_type(field
);
344 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
349 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_STRING
) {
350 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
355 *value
= bt_ctf_field_string_get_value(field
);
357 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
374 int get_payload_build_id_field_value(FILE *err
,
375 struct bt_ctf_event
*event
, const char *field_name
,
376 uint8_t **build_id
, uint64_t *build_id_len
)
378 struct bt_ctf_field
*field
= NULL
, *seq_len
= NULL
;
379 struct bt_ctf_field_type
*field_type
= NULL
;
380 struct bt_ctf_field
*seq_field
= NULL
;
386 field
= get_payload_field(err
, event
, field_name
);
388 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
393 field_type
= bt_ctf_field_get_type(field
);
395 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
400 if (bt_ctf_field_type_get_type_id(field_type
) != BT_CTF_FIELD_TYPE_ID_SEQUENCE
) {
401 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
407 seq_len
= bt_ctf_field_sequence_get_length(field
);
409 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
414 ret
= bt_ctf_field_unsigned_integer_get_value(seq_len
, build_id_len
);
416 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
422 *build_id
= g_new0(uint8_t, *build_id_len
);
424 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
429 for (i
= 0; i
< *build_id_len
; i
++) {
432 seq_field
= bt_ctf_field_sequence_get_field(field
, i
);
434 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
439 ret
= bt_ctf_field_unsigned_integer_get_value(seq_field
, &tmp
);
441 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
446 (*build_id
)[i
] = (uint8_t) tmp
;
461 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
462 struct bt_ctf_trace
*writer_trace
,
463 struct debug_info_trace
*di_trace
)
465 return (struct debug_info
*) g_hash_table_lookup(
466 di_trace
->trace_debug_map
,
467 (gpointer
) writer_trace
);
471 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
472 struct bt_ctf_trace
*writer_trace
,
473 struct debug_info_trace
*di_trace
)
475 struct debug_info
*debug_info
= NULL
;
476 struct bt_value
*field
= NULL
;
477 const char *str_value
;
478 enum bt_value_status ret
;
480 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
482 /* No domain field, no debug info */
486 ret
= bt_value_string_get(field
, &str_value
);
487 if (ret
!= BT_VALUE_STATUS_OK
) {
488 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
492 /* Domain not ust, no debug info */
493 if (strcmp(str_value
, "ust") != 0) {
498 /* No tracer_name, no debug info */
499 field
= bt_ctf_trace_get_environment_field_value_by_name(writer_trace
,
501 /* No tracer_name, no debug info */
505 ret
= bt_value_string_get(field
, &str_value
);
506 if (ret
!= BT_VALUE_STATUS_OK
) {
507 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
511 /* Tracer_name not lttng-ust, no debug info */
512 if (strcmp(str_value
, "lttng-ust") != 0) {
517 debug_info
= debug_info_create(debug_it
->debug_info_component
);
519 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
524 g_hash_table_insert(di_trace
->trace_debug_map
, (gpointer
) writer_trace
,
533 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
534 struct bt_ctf_trace
*writer_trace
,
535 struct debug_info_trace
*di_trace
)
537 struct debug_info
*debug_info
;
539 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
, di_trace
);
544 debug_info
= insert_new_debug_info(debug_it
, writer_trace
, di_trace
);
551 struct debug_info_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
552 struct bt_ctf_trace
*trace
)
554 return (struct debug_info_trace
*) g_hash_table_lookup(
560 enum debug_info_stream_state
*insert_new_stream_state(
561 struct debug_info_iterator
*debug_it
,
562 struct debug_info_trace
*di_trace
, struct bt_ctf_stream
*stream
)
564 enum debug_info_stream_state
*v
= NULL
;
566 v
= g_new0(enum debug_info_stream_state
, 1);
568 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
572 *v
= DEBUG_INFO_UNKNOWN_STREAM
;
574 g_hash_table_insert(di_trace
->stream_states
, stream
, v
);
581 void check_completed_trace(gpointer key
, gpointer value
, gpointer user_data
)
583 enum debug_info_stream_state
*state
= value
;
584 int *trace_completed
= user_data
;
586 if (*state
!= DEBUG_INFO_COMPLETED_STREAM
) {
587 *trace_completed
= 0;
592 gboolean
empty_ht(gpointer key
, gpointer value
, gpointer user_data
)
598 void debug_info_close_trace(struct debug_info_iterator
*debug_it
,
599 struct debug_info_trace
*di_trace
)
601 if (di_trace
->static_listener_id
>= 0) {
602 bt_ctf_trace_remove_is_static_listener(di_trace
->trace
,
603 di_trace
->static_listener_id
);
606 /* Empty the stream class HT. */
607 g_hash_table_foreach_remove(di_trace
->stream_class_map
,
609 g_hash_table_destroy(di_trace
->stream_class_map
);
611 /* Empty the stream HT. */
612 g_hash_table_foreach_remove(di_trace
->stream_map
,
614 g_hash_table_destroy(di_trace
->stream_map
);
616 /* Empty the stream state HT. */
617 g_hash_table_foreach_remove(di_trace
->stream_states
,
619 g_hash_table_destroy(di_trace
->stream_states
);
621 /* Empty the packet HT. */
622 g_hash_table_foreach_remove(di_trace
->packet_map
,
624 g_hash_table_destroy(di_trace
->packet_map
);
626 /* Empty the trace_debug HT. */
627 g_hash_table_foreach_remove(di_trace
->trace_debug_map
,
629 g_hash_table_destroy(di_trace
->trace_debug_map
);
633 int sync_event_classes(struct debug_info_iterator
*debug_it
,
634 struct bt_ctf_stream
*stream
,
635 struct bt_ctf_stream
*writer_stream
)
638 struct bt_ctf_stream_class
*stream_class
= NULL
,
639 *writer_stream_class
= NULL
;
640 enum bt_component_status ret
;
642 stream_class
= bt_ctf_stream_get_class(stream
);
644 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
649 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
650 if (!writer_stream_class
) {
651 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
656 ret
= ctf_copy_event_classes(debug_it
->err
, stream_class
,
657 writer_stream_class
);
658 if (ret
!= BT_COMPONENT_STATUS_OK
) {
668 bt_put(stream_class
);
669 bt_put(writer_stream_class
);
674 void trace_is_static_listener(struct bt_ctf_trace
*trace
, void *data
)
676 struct debug_info_trace
*di_trace
= data
;
677 struct debug_info_iterator
*debug_it
= di_trace
->debug_it
;
678 int trace_completed
= 1, ret
, nr_stream
, i
;
679 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
680 struct bt_ctf_trace
*writer_trace
= di_trace
->writer_trace
;
683 * When the trace becomes static, make sure that we have all
684 * the event classes in our stream_class copies before setting it
687 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
688 for (i
= 0; i
< nr_stream
; i
++) {
689 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
691 fprintf(debug_it
->err
,
692 "[error] %s in %s:%d\n", __func__
,
696 writer_stream
= bt_ctf_trace_get_stream_by_index(writer_trace
, i
);
697 if (!writer_stream
) {
698 fprintf(debug_it
->err
,
699 "[error] %s in %s:%d\n", __func__
,
703 ret
= sync_event_classes(di_trace
->debug_it
, stream
, writer_stream
);
705 fprintf(debug_it
->err
,
706 "[error] %s in %s:%d\n", __func__
,
711 BT_PUT(writer_stream
);
714 bt_ctf_trace_set_is_static(di_trace
->writer_trace
);
715 di_trace
->trace_static
= 1;
717 g_hash_table_foreach(di_trace
->stream_states
,
718 check_completed_trace
, &trace_completed
);
719 if (trace_completed
) {
720 debug_info_close_trace(di_trace
->debug_it
, di_trace
);
721 g_hash_table_remove(di_trace
->debug_it
->trace_map
,
726 bt_put(writer_stream
);
731 struct debug_info_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
732 struct bt_ctf_stream
*stream
) {
733 struct bt_ctf_trace
*writer_trace
= NULL
;
734 struct debug_info_trace
*di_trace
= NULL
;
735 struct bt_ctf_trace
*trace
= NULL
;
736 struct bt_ctf_stream_class
*stream_class
= NULL
;
737 struct bt_ctf_stream
*writer_stream
= NULL
;
738 int ret
, nr_stream
, i
;
740 writer_trace
= bt_ctf_trace_create();
742 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
747 stream_class
= bt_ctf_stream_get_class(stream
);
749 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
754 trace
= bt_ctf_stream_class_get_trace(stream_class
);
756 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
761 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
762 if (ret
!= BT_COMPONENT_STATUS_OK
) {
763 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
768 di_trace
= g_new0(struct debug_info_trace
, 1);
770 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
775 di_trace
->trace
= trace
;
776 di_trace
->writer_trace
= writer_trace
;
777 di_trace
->debug_info_component
= debug_it
->debug_info_component
;
778 di_trace
->debug_it
= debug_it
;
779 di_trace
->stream_map
= g_hash_table_new_full(g_direct_hash
,
780 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream
);
781 di_trace
->stream_class_map
= g_hash_table_new_full(g_direct_hash
,
782 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream_class
);
783 di_trace
->packet_map
= g_hash_table_new_full(g_direct_hash
,
784 g_direct_equal
, NULL
, (GDestroyNotify
) unref_packet
);
785 di_trace
->trace_debug_map
= g_hash_table_new_full(g_direct_hash
,
786 g_direct_equal
, NULL
, (GDestroyNotify
) unref_debug_info
);
787 di_trace
->stream_states
= g_hash_table_new_full(g_direct_hash
,
788 g_direct_equal
, NULL
, destroy_stream_state_key
);
789 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, di_trace
);
791 /* Set all the existing streams in the unknown state. */
792 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
793 for (i
= 0; i
< nr_stream
; i
++) {
794 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
796 fprintf(debug_it
->err
,
797 "[error] %s in %s:%d\n", __func__
,
801 insert_new_stream_state(debug_it
, di_trace
, stream
);
802 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
803 if (!writer_stream
) {
804 fprintf(debug_it
->err
,
805 "[error] %s in %s:%d\n", __func__
,
809 bt_get(writer_stream
);
810 ret
= sync_event_classes(debug_it
, stream
, writer_stream
);
812 fprintf(debug_it
->err
,
813 "[error] %s in %s:%d\n", __func__
,
817 BT_PUT(writer_stream
);
821 /* Check if the trace is already static or register a listener. */
822 if (bt_ctf_trace_is_static(trace
)) {
823 di_trace
->trace_static
= 1;
824 di_trace
->static_listener_id
= -1;
825 bt_ctf_trace_set_is_static(writer_trace
);
827 ret
= bt_ctf_trace_add_is_static_listener(trace
,
828 trace_is_static_listener
, di_trace
);
830 fprintf(debug_it
->err
,
831 "[error] %s in %s:%d\n", __func__
, __FILE__
,
835 di_trace
->static_listener_id
= ret
;
842 BT_PUT(writer_trace
);
847 bt_put(writer_stream
);
848 bt_put(stream_class
);
854 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
855 struct bt_ctf_packet
*packet
,
856 struct debug_info_trace
*di_trace
)
858 return (struct bt_ctf_packet
*) g_hash_table_lookup(
859 di_trace
->packet_map
,
864 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
865 struct bt_ctf_packet
*packet
,
866 struct bt_ctf_stream
*writer_stream
,
867 struct debug_info_trace
*di_trace
)
869 struct bt_ctf_packet
*writer_packet
;
872 writer_packet
= bt_ctf_packet_create(writer_stream
);
873 if (!writer_packet
) {
874 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
879 ret
= ctf_packet_copy_header(debug_it
->err
, packet
, writer_packet
);
881 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
886 g_hash_table_insert(di_trace
->packet_map
, (gpointer
) packet
,
891 BT_PUT(writer_packet
);
893 return writer_packet
;
897 int add_debug_info_fields(FILE *err
,
898 struct bt_ctf_field_type
*writer_event_context_type
,
899 struct debug_info_component
*component
)
901 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
902 *bin_field_type
= NULL
, *func_field_type
= NULL
,
903 *src_field_type
= NULL
;
906 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
907 writer_event_context_type
, "_ip");
908 /* No ip field, so no debug info. */
914 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
915 writer_event_context_type
,
916 component
->arg_debug_info_field_name
);
917 /* Already existing debug_info field, no need to add it. */
918 if (debug_field_type
) {
922 debug_field_type
= bt_ctf_field_type_structure_create();
923 if (!debug_field_type
) {
924 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
929 bin_field_type
= bt_ctf_field_type_string_create();
930 if (!bin_field_type
) {
931 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
936 func_field_type
= bt_ctf_field_type_string_create();
937 if (!func_field_type
) {
938 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
943 src_field_type
= bt_ctf_field_type_string_create();
944 if (!src_field_type
) {
945 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
950 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
951 bin_field_type
, "bin");
953 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
958 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
959 func_field_type
, "func");
961 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
966 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
967 src_field_type
, "src");
969 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
974 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
975 debug_field_type
, component
->arg_debug_info_field_name
);
977 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
986 BT_PUT(debug_field_type
);
989 bt_put(src_field_type
);
990 bt_put(func_field_type
);
991 bt_put(bin_field_type
);
992 bt_put(debug_field_type
);
997 int create_debug_info_event_context_type(FILE *err
,
998 struct bt_ctf_field_type
*event_context_type
,
999 struct bt_ctf_field_type
*writer_event_context_type
,
1000 struct debug_info_component
*component
)
1002 int ret
, nr_fields
, i
;
1004 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
1005 for (i
= 0; i
< nr_fields
; i
++) {
1006 struct bt_ctf_field_type
*field_type
= NULL
;
1007 const char *field_name
;
1009 if (bt_ctf_field_type_structure_get_field(event_context_type
,
1010 &field_name
, &field_type
, i
) < 0) {
1011 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1012 __FILE__
, __LINE__
);
1016 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
1017 field_type
, field_name
);
1020 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1026 ret
= add_debug_info_fields(err
, writer_event_context_type
,
1037 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
1038 struct bt_ctf_stream_class
*stream_class
,
1039 struct bt_ctf_trace
*writer_trace
,
1040 struct debug_info_component
*component
)
1042 struct bt_ctf_field_type
*type
= NULL
;
1043 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1044 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1046 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
1048 writer_stream_class
= bt_ctf_stream_class_create_empty(name
);
1049 if (!writer_stream_class
) {
1050 fprintf(err
, "[error] %s in %s:%d\n",
1051 __func__
, __FILE__
, __LINE__
);
1055 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
1057 ret_int
= bt_ctf_stream_class_set_packet_context_type(
1058 writer_stream_class
, type
);
1060 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1067 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
1069 ret_int
= bt_ctf_stream_class_set_event_header_type(
1070 writer_stream_class
, type
);
1072 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1079 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
1081 writer_event_context_type
= bt_ctf_field_type_structure_create();
1082 if (!writer_event_context_type
) {
1083 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1087 ret_int
= create_debug_info_event_context_type(err
, type
,
1088 writer_event_context_type
, component
);
1090 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1096 ret_int
= bt_ctf_stream_class_set_event_context_type(
1097 writer_stream_class
, writer_event_context_type
);
1099 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1103 BT_PUT(writer_event_context_type
);
1109 BT_PUT(writer_stream_class
);
1111 bt_put(writer_event_context_type
);
1113 return writer_stream_class
;
1117 * Add the original clock classes to the new trace, we do not need to copy
1118 * them, and if we did, we would have to manually inspect the stream class
1119 * to update the integers mapping to a clock.
1122 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
1123 struct bt_ctf_stream_class
*writer_stream_class
,
1124 struct bt_ctf_trace
*trace
)
1126 int ret
, clock_class_count
, i
;
1128 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
1130 for (i
= 0; i
< clock_class_count
; i
++) {
1131 struct bt_ctf_clock_class
*clock_class
=
1132 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
1133 struct bt_ctf_clock_class
*existing_clock_class
= NULL
;
1136 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1141 existing_clock_class
= bt_ctf_trace_get_clock_class_by_name(
1142 writer_trace
, bt_ctf_clock_class_get_name(clock_class
));
1143 bt_put(existing_clock_class
);
1144 if (existing_clock_class
) {
1145 bt_put(clock_class
);
1149 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
1150 BT_PUT(clock_class
);
1152 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1169 struct bt_ctf_stream_class
*insert_new_stream_class(
1170 struct debug_info_iterator
*debug_it
,
1171 struct bt_ctf_stream_class
*stream_class
)
1173 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1174 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
1175 struct debug_info_trace
*di_trace
;
1176 enum bt_component_status ret
;
1179 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1181 fprintf(debug_it
->err
,
1182 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1187 di_trace
= lookup_trace(debug_it
, trace
);
1189 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1190 __FILE__
, __LINE__
);
1191 ret
= BT_COMPONENT_STATUS_ERROR
;
1194 writer_trace
= di_trace
->writer_trace
;
1195 bt_get(writer_trace
);
1197 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1198 writer_trace
, debug_it
->debug_info_component
);
1199 if (!writer_stream_class
) {
1200 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
1201 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1202 __func__
, __FILE__
, __LINE__
);
1206 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
1208 fprintf(debug_it
->err
,
1209 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1214 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1215 writer_stream_class
, trace
);
1216 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1217 fprintf(debug_it
->err
,
1218 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1223 g_hash_table_insert(di_trace
->stream_class_map
,
1224 (gpointer
) stream_class
, writer_stream_class
);
1229 BT_PUT(writer_stream_class
);
1232 bt_put(writer_trace
);
1233 return writer_stream_class
;
1237 struct bt_ctf_stream
*insert_new_stream(
1238 struct debug_info_iterator
*debug_it
,
1239 struct bt_ctf_stream
*stream
,
1240 struct debug_info_trace
*di_trace
)
1242 struct bt_ctf_stream
*writer_stream
= NULL
;
1243 struct bt_ctf_stream_class
*stream_class
= NULL
;
1244 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1246 stream_class
= bt_ctf_stream_get_class(stream
);
1247 if (!stream_class
) {
1248 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1249 __func__
, __FILE__
, __LINE__
);
1253 writer_stream_class
= g_hash_table_lookup(
1254 di_trace
->stream_class_map
,
1255 (gpointer
) stream_class
);
1257 if (!writer_stream_class
) {
1258 writer_stream_class
= insert_new_stream_class(debug_it
,
1260 if (!writer_stream_class
) {
1261 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1262 __func__
, __FILE__
, __LINE__
);
1266 bt_get(writer_stream_class
);
1268 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
1269 bt_ctf_stream_get_name(stream
));
1270 if (!writer_stream
) {
1271 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1272 __func__
, __FILE__
, __LINE__
);
1276 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1282 BT_PUT(writer_stream
);
1284 bt_put(stream_class
);
1285 bt_put(writer_stream_class
);
1286 return writer_stream
;
1290 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1291 struct bt_ctf_stream
*stream
,
1292 struct debug_info_trace
*di_trace
)
1294 return (struct bt_ctf_stream
*) g_hash_table_lookup(
1295 di_trace
->stream_map
, (gpointer
) stream
);
1299 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1300 struct bt_ctf_stream_class
*writer_stream_class
,
1301 struct bt_ctf_event_class
*event_class
)
1303 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
1304 bt_ctf_event_class_get_id(event_class
));
1308 struct debug_info_trace
*lookup_di_trace_from_stream(
1309 struct debug_info_iterator
*debug_it
,
1310 struct bt_ctf_stream
*stream
)
1312 struct bt_ctf_stream_class
*stream_class
= NULL
;
1313 struct bt_ctf_trace
*trace
= NULL
;
1314 struct debug_info_trace
*di_trace
= NULL
;
1316 stream_class
= bt_ctf_stream_get_class(stream
);
1317 if (!stream_class
) {
1318 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1319 __func__
, __FILE__
, __LINE__
);
1323 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1325 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1326 __func__
, __FILE__
, __LINE__
);
1330 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1331 debug_it
->trace_map
, (gpointer
) trace
);
1334 BT_PUT(stream_class
);
1340 struct bt_ctf_stream
*get_writer_stream(
1341 struct debug_info_iterator
*debug_it
,
1342 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
1344 struct bt_ctf_stream_class
*stream_class
= NULL
;
1345 struct bt_ctf_stream
*writer_stream
= NULL
;
1346 struct debug_info_trace
*di_trace
= NULL
;
1348 stream_class
= bt_ctf_stream_get_class(stream
);
1349 if (!stream_class
) {
1350 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1351 __func__
, __FILE__
, __LINE__
);
1355 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1357 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1358 __func__
, __FILE__
, __LINE__
);
1362 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1363 if (!writer_stream
) {
1364 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1365 __func__
, __FILE__
, __LINE__
);
1368 bt_get(writer_stream
);
1373 BT_PUT(writer_stream
);
1375 bt_put(stream_class
);
1376 return writer_stream
;
1380 struct bt_ctf_packet
*debug_info_new_packet(
1381 struct debug_info_iterator
*debug_it
,
1382 struct bt_ctf_packet
*packet
)
1384 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1385 struct bt_ctf_packet
*writer_packet
= NULL
;
1386 struct bt_ctf_field
*packet_context
= NULL
;
1387 struct debug_info_trace
*di_trace
;
1390 stream
= bt_ctf_packet_get_stream(packet
);
1392 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1393 __func__
, __FILE__
, __LINE__
);
1397 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1398 if (!writer_stream
) {
1399 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1400 __func__
, __FILE__
, __LINE__
);
1404 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1406 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1407 __FILE__
, __LINE__
);
1412 * If a packet was already opened, close it and remove it from
1415 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1416 if (writer_packet
) {
1417 g_hash_table_remove(di_trace
->packet_map
, packet
);
1418 BT_PUT(writer_packet
);
1421 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1423 if (!writer_packet
) {
1424 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1425 __func__
, __FILE__
, __LINE__
);
1429 packet_context
= bt_ctf_packet_get_context(packet
);
1430 if (packet_context
) {
1431 int_ret
= ctf_packet_copy_context(debug_it
->err
,
1432 packet
, writer_stream
, writer_packet
);
1434 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1435 __func__
, __FILE__
, __LINE__
);
1438 BT_PUT(packet_context
);
1441 bt_get(writer_packet
);
1447 bt_put(packet_context
);
1448 bt_put(writer_stream
);
1450 return writer_packet
;
1454 struct bt_ctf_packet
*debug_info_close_packet(
1455 struct debug_info_iterator
*debug_it
,
1456 struct bt_ctf_packet
*packet
)
1458 struct bt_ctf_packet
*writer_packet
= NULL
;
1459 struct bt_ctf_stream
*stream
= NULL
;
1460 struct debug_info_trace
*di_trace
;
1462 stream
= bt_ctf_packet_get_stream(packet
);
1464 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1465 __FILE__
, __LINE__
);
1469 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1471 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1472 __FILE__
, __LINE__
);
1476 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1477 if (!writer_packet
) {
1478 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1479 __func__
, __FILE__
, __LINE__
);
1482 bt_get(writer_packet
);
1483 g_hash_table_remove(di_trace
->packet_map
, packet
);
1487 return writer_packet
;
1491 struct bt_ctf_stream
*debug_info_stream_begin(
1492 struct debug_info_iterator
*debug_it
,
1493 struct bt_ctf_stream
*stream
)
1495 struct bt_ctf_stream
*writer_stream
= NULL
;
1496 enum debug_info_stream_state
*state
;
1497 struct debug_info_trace
*di_trace
= NULL
;
1499 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1501 di_trace
= insert_new_trace(debug_it
, stream
);
1503 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1504 __func__
, __FILE__
, __LINE__
);
1509 /* Set the stream as active */
1510 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1512 if (di_trace
->trace_static
) {
1513 fprintf(debug_it
->err
, "[error] Adding a new stream "
1514 "on a static trace\n");
1517 state
= insert_new_stream_state(debug_it
, di_trace
,
1520 fprintf(debug_it
->err
, "[error] Adding a new stream "
1521 "on a static trace\n");
1525 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1526 fprintf(debug_it
->err
, "[error] Unexpected stream state %d\n",
1530 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1532 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1533 if (!writer_stream
) {
1534 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1536 bt_get(writer_stream
);
1541 BT_PUT(writer_stream
);
1543 return writer_stream
;
1547 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1548 struct bt_ctf_stream
*stream
)
1550 struct bt_ctf_stream
*writer_stream
= NULL
;
1551 struct debug_info_trace
*di_trace
= NULL
;
1552 enum debug_info_stream_state
*state
;
1554 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1556 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1557 __func__
, __FILE__
, __LINE__
);
1561 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1562 if (!writer_stream
) {
1563 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1564 __func__
, __FILE__
, __LINE__
);
1568 * Take the ref on the stream and keep it until the notification
1571 bt_get(writer_stream
);
1573 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1574 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1575 fprintf(debug_it
->err
, "[error] Unexpected stream "
1576 "state %d\n", *state
);
1579 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1581 g_hash_table_remove(di_trace
->stream_map
, stream
);
1583 if (di_trace
->trace_static
) {
1584 int trace_completed
= 1;
1586 g_hash_table_foreach(di_trace
->stream_states
,
1587 check_completed_trace
, &trace_completed
);
1588 if (trace_completed
) {
1589 debug_info_close_trace(debug_it
, di_trace
);
1590 g_hash_table_remove(debug_it
->trace_map
,
1598 BT_PUT(writer_stream
);
1601 return writer_stream
;
1605 struct debug_info_source
*lookup_debug_info(FILE *err
,
1606 struct bt_ctf_event
*event
,
1607 struct debug_info
*debug_info
)
1611 struct debug_info_source
*dbg_info_src
= NULL
;
1614 ret
= get_stream_event_context_int_field_value(err
, event
,
1620 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1626 /* Get debug info for this context. */
1627 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1630 return dbg_info_src
;
1634 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1635 struct debug_info_source
*dbg_info_src
,
1636 struct debug_info_component
*component
)
1638 int i
, nr_fields
, ret
= 0;
1639 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1640 struct bt_ctf_field
*field
= NULL
;
1641 struct bt_ctf_field_type
*field_type
= NULL
;
1643 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1644 if (!debug_field_type
) {
1645 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1646 __FILE__
, __LINE__
);
1650 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1651 for (i
= 0; i
< nr_fields
; i
++) {
1652 const char *field_name
;
1654 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1655 &field_name
, &field_type
, i
) < 0) {
1656 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1657 __FILE__
, __LINE__
);
1662 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1663 if (!strcmp(field_name
, "bin")) {
1664 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1665 GString
*tmp
= g_string_new(NULL
);
1667 if (component
->arg_full_path
) {
1668 g_string_printf(tmp
, "%s%s",
1669 dbg_info_src
->bin_path
,
1670 dbg_info_src
->bin_loc
);
1672 g_string_printf(tmp
, "%s%s",
1673 dbg_info_src
->short_bin_path
,
1674 dbg_info_src
->bin_loc
);
1676 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1677 g_string_free(tmp
, true);
1679 ret
= bt_ctf_field_string_set_value(field
, "");
1681 } else if (!strcmp(field_name
, "func")) {
1682 if (dbg_info_src
&& dbg_info_src
->func
) {
1683 ret
= bt_ctf_field_string_set_value(field
,
1684 dbg_info_src
->func
);
1686 ret
= bt_ctf_field_string_set_value(field
, "");
1688 } else if (!strcmp(field_name
, "src")) {
1689 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1690 GString
*tmp
= g_string_new(NULL
);
1692 if (component
->arg_full_path
) {
1693 g_string_printf(tmp
, "%s:%" PRId64
,
1694 dbg_info_src
->src_path
,
1695 dbg_info_src
->line_no
);
1697 g_string_printf(tmp
, "%s:%" PRId64
,
1698 dbg_info_src
->short_src_path
,
1699 dbg_info_src
->line_no
);
1701 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1702 g_string_free(tmp
, true);
1704 ret
= bt_ctf_field_string_set_value(field
, "");
1709 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1710 __FILE__
, __LINE__
);
1722 bt_put(debug_field_type
);
1727 int copy_set_debug_info_stream_event_context(FILE *err
,
1728 struct bt_ctf_field
*event_context
,
1729 struct bt_ctf_event
*event
,
1730 struct bt_ctf_event
*writer_event
,
1731 struct debug_info
*debug_info
,
1732 struct debug_info_component
*component
)
1734 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1735 *event_context_type
= NULL
;
1736 struct bt_ctf_field
*writer_event_context
= NULL
;
1737 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1738 struct bt_ctf_field_type
*field_type
= NULL
;
1739 struct debug_info_source
*dbg_info_src
;
1740 int ret
, nr_fields
, i
;
1742 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1743 if (!writer_event_context
) {
1744 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1748 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1749 if (!writer_event_context_type
) {
1750 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1751 __FILE__
, __LINE__
);
1755 event_context_type
= bt_ctf_field_get_type(event_context
);
1756 if (!event_context_type
) {
1757 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1758 __FILE__
, __LINE__
);
1763 * If it is not a structure, we did not modify it to add the debug info
1764 * fields, so just assign it as is.
1766 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1767 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1771 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1773 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1774 for (i
= 0; i
< nr_fields
; i
++) {
1775 const char *field_name
;
1777 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1778 &field_name
, &field_type
, i
) < 0) {
1779 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1780 __FILE__
, __LINE__
);
1785 * Prevent illegal access in the event_context.
1787 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1788 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1791 * The debug_info field, only exists in the writer event or
1792 * if it was set by a earlier pass of the debug_info plugin.
1794 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1796 debug_field
= bt_ctf_field_structure_get_field_by_index(
1797 writer_event_context
, i
);
1799 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1800 __FILE__
, __LINE__
);
1803 ret
= set_debug_info_field(err
, debug_field
,
1804 dbg_info_src
, component
);
1806 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1807 __FILE__
, __LINE__
);
1810 BT_PUT(debug_field
);
1812 copy_field
= bt_ctf_field_copy(field
);
1814 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1815 __FILE__
, __LINE__
);
1819 ret
= bt_ctf_field_structure_set_field_by_name(
1820 writer_event_context
,
1821 field_name
, copy_field
);
1823 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1824 __FILE__
, __LINE__
);
1839 bt_put(event_context_type
);
1840 bt_put(writer_event_context_type
);
1841 bt_put(writer_event_context
);
1844 bt_put(debug_field
);
1850 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1851 struct bt_ctf_stream_class
*stream_class
)
1853 struct bt_ctf_trace
*trace
= NULL
;
1854 struct bt_ctf_clock_class
*clock_class
= NULL
;
1856 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1858 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1863 if (!bt_ctf_trace_get_clock_class_count(trace
)) {
1868 /* FIXME multi-clock? */
1869 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1878 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1880 struct bt_ctf_event_class
*event_class
= NULL
;
1881 struct bt_ctf_stream_class
*stream_class
= NULL
;
1882 struct bt_ctf_clock_class
*clock_class
= NULL
;
1884 event_class
= bt_ctf_event_get_class(event
);
1886 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1891 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1892 if (!stream_class
) {
1893 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1898 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1902 BT_PUT(clock_class
);
1904 bt_put(stream_class
);
1905 bt_put(event_class
);
1910 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1911 struct bt_ctf_event
*writer_event
)
1913 struct bt_ctf_clock_class
*clock_class
= NULL
;
1914 struct bt_ctf_clock_value
*clock_value
= NULL
;
1917 clock_class
= event_get_clock_class(err
, event
);
1919 /* No clock on input trace. */
1923 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1925 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1931 * We share the same clocks, so we can assign the clock value to the
1934 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1936 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1947 bt_put(clock_class
);
1948 bt_put(clock_value
);
1953 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1954 struct bt_ctf_event_class
*writer_event_class
,
1955 struct debug_info
*debug_info
,
1956 struct debug_info_component
*component
)
1958 struct bt_ctf_event
*writer_event
= NULL
;
1959 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1962 writer_event
= bt_ctf_event_create(writer_event_class
);
1963 if (!writer_event
) {
1964 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1969 ret
= set_event_clock_value(err
, event
, writer_event
);
1971 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1972 __FILE__
, __LINE__
);
1976 /* Optional field, so it can fail silently. */
1977 field
= bt_ctf_event_get_header(event
);
1979 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1980 writer_event
, field
);
1982 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1983 __FILE__
, __LINE__
);
1989 /* Optional field, so it can fail silently. */
1990 field
= bt_ctf_event_get_stream_event_context(event
);
1992 ret
= copy_set_debug_info_stream_event_context(err
,
1993 field
, event
, writer_event
, debug_info
,
1996 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1997 __FILE__
, __LINE__
);
2003 /* Optional field, so it can fail silently. */
2004 field
= bt_ctf_event_get_event_context(event
);
2006 copy_field
= bt_ctf_field_copy(field
);
2008 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2009 __FILE__
, __LINE__
);
2012 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
2014 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2015 __FILE__
, __LINE__
);
2022 field
= bt_ctf_event_get_event_payload(event
);
2024 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2025 __FILE__
, __LINE__
);
2028 copy_field
= bt_ctf_field_copy(field
);
2030 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
2032 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2033 __FILE__
, __LINE__
);
2043 BT_PUT(writer_event
);
2047 return writer_event
;
2051 struct bt_ctf_event
*debug_info_output_event(
2052 struct debug_info_iterator
*debug_it
,
2053 struct bt_ctf_event
*event
)
2055 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
2056 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
2057 struct bt_ctf_event
*writer_event
= NULL
;
2058 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
2059 struct bt_ctf_trace
*writer_trace
= NULL
;
2060 struct bt_ctf_stream
*stream
= NULL
;
2061 struct debug_info_trace
*di_trace
;
2062 struct debug_info
*debug_info
;
2063 const char *event_name
;
2066 event_class
= bt_ctf_event_get_class(event
);
2068 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2069 __FILE__
, __LINE__
);
2073 event_name
= bt_ctf_event_class_get_name(event_class
);
2075 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2076 __FILE__
, __LINE__
);
2080 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
2081 if (!stream_class
) {
2082 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2083 __FILE__
, __LINE__
);
2086 stream
= bt_ctf_event_get_stream(event
);
2088 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2089 __FILE__
, __LINE__
);
2092 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
2094 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2095 __FILE__
, __LINE__
);
2099 writer_stream_class
= g_hash_table_lookup(
2100 di_trace
->stream_class_map
,
2101 (gpointer
) stream_class
);
2102 if (!writer_stream_class
) {
2103 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2104 __FILE__
, __LINE__
);
2107 bt_get(writer_stream_class
);
2109 writer_event_class
= get_event_class(debug_it
,
2110 writer_stream_class
, event_class
);
2111 if (!writer_event_class
) {
2112 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
2114 if (!writer_event_class
) {
2115 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2116 __func__
, __FILE__
, __LINE__
);
2119 int_ret
= bt_ctf_stream_class_add_event_class(
2120 writer_stream_class
, writer_event_class
);
2122 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2123 __func__
, __FILE__
, __LINE__
);
2128 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
2129 if (!writer_trace
) {
2130 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2131 __FILE__
, __LINE__
);
2135 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
2137 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
2140 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
2141 writer_event_class
, debug_info
,
2142 debug_it
->debug_info_component
);
2143 if (!writer_event
) {
2144 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2145 __FILE__
, __LINE__
);
2146 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
2147 bt_ctf_event_class_get_name(writer_event_class
));
2151 packet
= bt_ctf_event_get_packet(event
);
2153 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2154 __FILE__
, __LINE__
);
2158 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
2159 if (!writer_packet
) {
2160 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2161 __FILE__
, __LINE__
);
2164 bt_get(writer_packet
);
2166 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
2168 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2169 __FILE__
, __LINE__
);
2170 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
2171 bt_ctf_event_class_get_name(writer_event_class
));
2175 /* Keep the reference on the writer event */
2179 BT_PUT(writer_event
);
2183 bt_put(writer_trace
);
2184 bt_put(writer_packet
);
2186 bt_put(writer_event_class
);
2187 bt_put(writer_stream_class
);
2188 bt_put(stream_class
);
2189 bt_put(event_class
);
2190 return writer_event
;