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__
,
571 *v
= DEBUG_INFO_UNKNOWN_STREAM
;
573 g_hash_table_insert(di_trace
->stream_states
, stream
, v
);
579 void check_completed_trace(gpointer key
, gpointer value
, gpointer user_data
)
581 enum debug_info_stream_state
*state
= value
;
582 int *trace_completed
= user_data
;
584 if (*state
!= DEBUG_INFO_COMPLETED_STREAM
) {
585 *trace_completed
= 0;
590 gboolean
empty_ht(gpointer key
, gpointer value
, gpointer user_data
)
596 void debug_info_close_trace(struct debug_info_iterator
*debug_it
,
597 struct debug_info_trace
*di_trace
)
599 if (di_trace
->static_listener_id
> 0) {
600 bt_ctf_trace_remove_is_static_listener(di_trace
->trace
,
601 di_trace
->static_listener_id
);
604 /* Empty the stream class HT. */
605 g_hash_table_foreach_remove(di_trace
->stream_class_map
,
607 g_hash_table_destroy(di_trace
->stream_class_map
);
609 /* Empty the stream HT. */
610 g_hash_table_foreach_remove(di_trace
->stream_map
,
612 g_hash_table_destroy(di_trace
->stream_map
);
614 /* Empty the stream state HT. */
615 g_hash_table_foreach_remove(di_trace
->stream_states
,
617 g_hash_table_destroy(di_trace
->stream_states
);
619 /* Empty the packet HT. */
620 g_hash_table_foreach_remove(di_trace
->packet_map
,
622 g_hash_table_destroy(di_trace
->packet_map
);
624 /* Empty the trace_debug HT. */
625 g_hash_table_foreach_remove(di_trace
->trace_debug_map
,
627 g_hash_table_destroy(di_trace
->trace_debug_map
);
631 int sync_event_classes(struct debug_info_iterator
*debug_it
,
632 struct bt_ctf_stream
*stream
,
633 struct bt_ctf_stream
*writer_stream
)
636 struct bt_ctf_stream_class
*stream_class
= NULL
,
637 *writer_stream_class
= NULL
;
638 enum bt_component_status ret
;
640 stream_class
= bt_ctf_stream_get_class(stream
);
642 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
647 writer_stream_class
= bt_ctf_stream_get_class(writer_stream
);
648 if (!writer_stream_class
) {
649 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
654 ret
= ctf_copy_event_classes(debug_it
->err
, stream_class
,
655 writer_stream_class
);
656 if (ret
!= BT_COMPONENT_STATUS_OK
) {
666 bt_put(stream_class
);
667 bt_put(writer_stream_class
);
672 void trace_is_static_listener(struct bt_ctf_trace
*trace
, void *data
)
674 struct debug_info_trace
*di_trace
= data
;
675 struct debug_info_iterator
*debug_it
= di_trace
->debug_it
;
676 int trace_completed
= 1, ret
, nr_stream
, i
;
677 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
678 struct bt_ctf_trace
*writer_trace
= di_trace
->writer_trace
;
681 * When the trace becomes static, make sure that we have all
682 * the event classes in our stream_class copies before setting it
685 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
686 for (i
= 0; i
< nr_stream
; i
++) {
687 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
689 fprintf(debug_it
->err
,
690 "[error] %s in %s:%d\n", __func__
,
694 writer_stream
= bt_ctf_trace_get_stream_by_index(writer_trace
, i
);
695 if (!writer_stream
) {
696 fprintf(debug_it
->err
,
697 "[error] %s in %s:%d\n", __func__
,
701 ret
= sync_event_classes(di_trace
->debug_it
, stream
, writer_stream
);
703 fprintf(debug_it
->err
,
704 "[error] %s in %s:%d\n", __func__
,
709 BT_PUT(writer_stream
);
712 bt_ctf_trace_set_is_static(di_trace
->writer_trace
);
713 di_trace
->trace_static
= 1;
715 g_hash_table_foreach(di_trace
->stream_states
,
716 check_completed_trace
, &trace_completed
);
717 if (trace_completed
) {
718 debug_info_close_trace(di_trace
->debug_it
, di_trace
);
719 g_hash_table_remove(di_trace
->debug_it
->trace_map
,
724 bt_put(writer_stream
);
729 struct debug_info_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
730 struct bt_ctf_stream
*stream
) {
731 struct bt_ctf_trace
*writer_trace
= NULL
;
732 struct debug_info_trace
*di_trace
= NULL
;
733 struct bt_ctf_trace
*trace
= NULL
;
734 struct bt_ctf_stream_class
*stream_class
= NULL
;
735 struct bt_ctf_stream
*writer_stream
= NULL
;
736 int ret
, nr_stream
, i
;
738 writer_trace
= bt_ctf_trace_create();
740 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
745 stream_class
= bt_ctf_stream_get_class(stream
);
747 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
752 trace
= bt_ctf_stream_class_get_trace(stream_class
);
754 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
759 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
760 if (ret
!= BT_COMPONENT_STATUS_OK
) {
761 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
766 di_trace
= g_new0(struct debug_info_trace
, 1);
768 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
773 di_trace
->trace
= trace
;
774 di_trace
->writer_trace
= writer_trace
;
775 di_trace
->debug_info_component
= debug_it
->debug_info_component
;
776 di_trace
->debug_it
= debug_it
;
777 di_trace
->stream_map
= g_hash_table_new_full(g_direct_hash
,
778 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream
);
779 di_trace
->stream_class_map
= g_hash_table_new_full(g_direct_hash
,
780 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream_class
);
781 di_trace
->packet_map
= g_hash_table_new_full(g_direct_hash
,
782 g_direct_equal
, NULL
, (GDestroyNotify
) unref_packet
);
783 di_trace
->trace_debug_map
= g_hash_table_new_full(g_direct_hash
,
784 g_direct_equal
, NULL
, (GDestroyNotify
) unref_debug_info
);
785 di_trace
->stream_states
= g_hash_table_new_full(g_direct_hash
,
786 g_direct_equal
, NULL
, destroy_stream_state_key
);
787 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, di_trace
);
789 /* Set all the existing streams in the unknown state. */
790 nr_stream
= bt_ctf_trace_get_stream_count(trace
);
791 for (i
= 0; i
< nr_stream
; i
++) {
792 stream
= bt_ctf_trace_get_stream_by_index(trace
, i
);
794 fprintf(debug_it
->err
,
795 "[error] %s in %s:%d\n", __func__
,
799 insert_new_stream_state(debug_it
, di_trace
, stream
);
800 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
801 if (!writer_stream
) {
802 fprintf(debug_it
->err
,
803 "[error] %s in %s:%d\n", __func__
,
807 bt_get(writer_stream
);
808 ret
= sync_event_classes(debug_it
, stream
, writer_stream
);
810 fprintf(debug_it
->err
,
811 "[error] %s in %s:%d\n", __func__
,
815 BT_PUT(writer_stream
);
819 /* Check if the trace is already static or register a listener. */
820 if (bt_ctf_trace_is_static(trace
)) {
821 di_trace
->trace_static
= 1;
822 di_trace
->static_listener_id
= -1;
823 bt_ctf_trace_set_is_static(writer_trace
);
825 ret
= bt_ctf_trace_add_is_static_listener(trace
,
826 trace_is_static_listener
, di_trace
);
828 fprintf(debug_it
->err
,
829 "[error] %s in %s:%d\n", __func__
, __FILE__
,
833 di_trace
->static_listener_id
= ret
;
840 BT_PUT(writer_trace
);
845 bt_put(writer_stream
);
846 bt_put(stream_class
);
852 struct bt_ctf_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
853 struct bt_ctf_packet
*packet
,
854 struct debug_info_trace
*di_trace
)
856 return (struct bt_ctf_packet
*) g_hash_table_lookup(
857 di_trace
->packet_map
,
862 struct bt_ctf_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
863 struct bt_ctf_packet
*packet
,
864 struct bt_ctf_stream
*writer_stream
,
865 struct debug_info_trace
*di_trace
)
867 struct bt_ctf_packet
*writer_packet
;
869 writer_packet
= bt_ctf_packet_create(writer_stream
);
870 if (!writer_packet
) {
871 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
875 g_hash_table_insert(di_trace
->packet_map
, (gpointer
) packet
, writer_packet
);
878 return writer_packet
;
882 int add_debug_info_fields(FILE *err
,
883 struct bt_ctf_field_type
*writer_event_context_type
,
884 struct debug_info_component
*component
)
886 struct bt_ctf_field_type
*ip_field
= NULL
, *debug_field_type
= NULL
,
887 *bin_field_type
= NULL
, *func_field_type
= NULL
,
888 *src_field_type
= NULL
;
891 ip_field
= bt_ctf_field_type_structure_get_field_type_by_name(
892 writer_event_context_type
, "_ip");
893 /* No ip field, so no debug info. */
899 debug_field_type
= bt_ctf_field_type_structure_get_field_type_by_name(
900 writer_event_context_type
,
901 component
->arg_debug_info_field_name
);
902 /* Already existing debug_info field, no need to add it. */
903 if (debug_field_type
) {
907 debug_field_type
= bt_ctf_field_type_structure_create();
908 if (!debug_field_type
) {
909 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
914 bin_field_type
= bt_ctf_field_type_string_create();
915 if (!bin_field_type
) {
916 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
921 func_field_type
= bt_ctf_field_type_string_create();
922 if (!func_field_type
) {
923 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
928 src_field_type
= bt_ctf_field_type_string_create();
929 if (!src_field_type
) {
930 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
935 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
936 bin_field_type
, "bin");
938 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
943 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
944 func_field_type
, "func");
946 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
951 ret
= bt_ctf_field_type_structure_add_field(debug_field_type
,
952 src_field_type
, "src");
954 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
959 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
960 debug_field_type
, component
->arg_debug_info_field_name
);
962 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
971 BT_PUT(debug_field_type
);
974 bt_put(src_field_type
);
975 bt_put(func_field_type
);
976 bt_put(bin_field_type
);
977 bt_put(debug_field_type
);
982 int create_debug_info_event_context_type(FILE *err
,
983 struct bt_ctf_field_type
*event_context_type
,
984 struct bt_ctf_field_type
*writer_event_context_type
,
985 struct debug_info_component
*component
)
987 int ret
, nr_fields
, i
;
989 nr_fields
= bt_ctf_field_type_structure_get_field_count(event_context_type
);
990 for (i
= 0; i
< nr_fields
; i
++) {
991 struct bt_ctf_field_type
*field_type
= NULL
;
992 const char *field_name
;
994 if (bt_ctf_field_type_structure_get_field(event_context_type
,
995 &field_name
, &field_type
, i
) < 0) {
996 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1001 ret
= bt_ctf_field_type_structure_add_field(writer_event_context_type
,
1002 field_type
, field_name
);
1005 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1011 ret
= add_debug_info_fields(err
, writer_event_context_type
,
1022 struct bt_ctf_stream_class
*copy_stream_class_debug_info(FILE *err
,
1023 struct bt_ctf_stream_class
*stream_class
,
1024 struct bt_ctf_trace
*writer_trace
,
1025 struct debug_info_component
*component
)
1027 struct bt_ctf_field_type
*type
= NULL
;
1028 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1029 struct bt_ctf_field_type
*writer_event_context_type
= NULL
;
1031 const char *name
= bt_ctf_stream_class_get_name(stream_class
);
1033 if (strlen(name
) == 0) {
1037 writer_stream_class
= bt_ctf_stream_class_create(name
);
1038 if (!writer_stream_class
) {
1039 fprintf(err
, "[error] %s in %s:%d\n",
1040 __func__
, __FILE__
, __LINE__
);
1044 type
= bt_ctf_stream_class_get_packet_context_type(stream_class
);
1046 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1051 ret_int
= bt_ctf_stream_class_set_packet_context_type(
1052 writer_stream_class
, type
);
1054 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1060 type
= bt_ctf_stream_class_get_event_header_type(stream_class
);
1062 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1067 ret_int
= bt_ctf_stream_class_set_event_header_type(
1068 writer_stream_class
, type
);
1070 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1076 type
= bt_ctf_stream_class_get_event_context_type(stream_class
);
1078 writer_event_context_type
= bt_ctf_field_type_structure_create();
1079 if (!writer_event_context_type
) {
1080 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1084 ret_int
= create_debug_info_event_context_type(err
, type
,
1085 writer_event_context_type
, component
);
1087 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1093 ret_int
= bt_ctf_stream_class_set_event_context_type(
1094 writer_stream_class
, writer_event_context_type
);
1096 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1100 BT_PUT(writer_event_context_type
);
1106 BT_PUT(writer_stream_class
);
1108 bt_put(writer_event_context_type
);
1110 return writer_stream_class
;
1114 * Add the original clock classes to the new trace, we do not need to copy
1115 * them, and if we did, we would have to manually inspect the stream class
1116 * to update the integers mapping to a clock.
1119 int add_clock_classes(FILE *err
, struct bt_ctf_trace
*writer_trace
,
1120 struct bt_ctf_stream_class
*writer_stream_class
,
1121 struct bt_ctf_trace
*trace
)
1123 int ret
, clock_class_count
, i
;
1125 clock_class_count
= bt_ctf_trace_get_clock_class_count(trace
);
1127 for (i
= 0; i
< clock_class_count
; i
++) {
1128 struct bt_ctf_clock_class
*clock_class
=
1129 bt_ctf_trace_get_clock_class_by_index(trace
, i
);
1132 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1137 ret
= bt_ctf_trace_add_clock_class(writer_trace
, clock_class
);
1138 BT_PUT(clock_class
);
1140 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1157 struct bt_ctf_stream_class
*insert_new_stream_class(
1158 struct debug_info_iterator
*debug_it
,
1159 struct bt_ctf_stream_class
*stream_class
)
1161 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1162 struct bt_ctf_trace
*trace
, *writer_trace
= NULL
;
1163 struct debug_info_trace
*di_trace
;
1164 enum bt_component_status ret
;
1167 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1169 fprintf(debug_it
->err
,
1170 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1175 di_trace
= lookup_trace(debug_it
, trace
);
1177 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1178 __FILE__
, __LINE__
);
1179 ret
= BT_COMPONENT_STATUS_ERROR
;
1182 writer_trace
= di_trace
->writer_trace
;
1183 bt_get(writer_trace
);
1185 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1186 writer_trace
, debug_it
->debug_info_component
);
1187 if (!writer_stream_class
) {
1188 fprintf(debug_it
->err
, "[error] Failed to copy stream class\n");
1189 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1190 __func__
, __FILE__
, __LINE__
);
1194 int_ret
= bt_ctf_trace_add_stream_class(writer_trace
, writer_stream_class
);
1196 fprintf(debug_it
->err
,
1197 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1202 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1203 writer_stream_class
, trace
);
1204 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1205 fprintf(debug_it
->err
,
1206 "[error] %s in %s:%d\n", __func__
, __FILE__
,
1211 g_hash_table_insert(di_trace
->stream_class_map
,
1212 (gpointer
) stream_class
, writer_stream_class
);
1217 BT_PUT(writer_stream_class
);
1220 bt_put(writer_trace
);
1221 return writer_stream_class
;
1225 struct bt_ctf_stream
*insert_new_stream(
1226 struct debug_info_iterator
*debug_it
,
1227 struct bt_ctf_stream
*stream
,
1228 struct debug_info_trace
*di_trace
)
1230 struct bt_ctf_stream
*writer_stream
= NULL
;
1231 struct bt_ctf_stream_class
*stream_class
= NULL
;
1232 struct bt_ctf_stream_class
*writer_stream_class
= NULL
;
1234 stream_class
= bt_ctf_stream_get_class(stream
);
1235 if (!stream_class
) {
1236 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1237 __func__
, __FILE__
, __LINE__
);
1241 writer_stream_class
= g_hash_table_lookup(
1242 di_trace
->stream_class_map
,
1243 (gpointer
) stream_class
);
1245 if (!writer_stream_class
) {
1246 writer_stream_class
= insert_new_stream_class(debug_it
,
1248 if (!writer_stream_class
) {
1249 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1250 __func__
, __FILE__
, __LINE__
);
1254 bt_get(writer_stream_class
);
1256 writer_stream
= bt_ctf_stream_create(writer_stream_class
,
1257 bt_ctf_stream_get_name(stream
));
1258 if (!writer_stream
) {
1259 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1260 __func__
, __FILE__
, __LINE__
);
1264 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1270 BT_PUT(writer_stream
);
1272 bt_put(stream_class
);
1273 bt_put(writer_stream_class
);
1274 return writer_stream
;
1278 struct bt_ctf_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1279 struct bt_ctf_stream
*stream
,
1280 struct debug_info_trace
*di_trace
)
1282 return (struct bt_ctf_stream
*) g_hash_table_lookup(
1283 di_trace
->stream_map
, (gpointer
) stream
);
1287 struct bt_ctf_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1288 struct bt_ctf_stream_class
*writer_stream_class
,
1289 struct bt_ctf_event_class
*event_class
)
1291 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class
,
1292 bt_ctf_event_class_get_id(event_class
));
1296 struct debug_info_trace
*lookup_di_trace_from_stream(
1297 struct debug_info_iterator
*debug_it
,
1298 struct bt_ctf_stream
*stream
)
1300 struct bt_ctf_stream_class
*stream_class
= NULL
;
1301 struct bt_ctf_trace
*trace
= NULL
;
1302 struct debug_info_trace
*di_trace
= NULL
;
1304 stream_class
= bt_ctf_stream_get_class(stream
);
1305 if (!stream_class
) {
1306 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1307 __func__
, __FILE__
, __LINE__
);
1311 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1313 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1314 __func__
, __FILE__
, __LINE__
);
1318 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1319 debug_it
->trace_map
, (gpointer
) trace
);
1322 BT_PUT(stream_class
);
1328 struct bt_ctf_stream
*get_writer_stream(
1329 struct debug_info_iterator
*debug_it
,
1330 struct bt_ctf_packet
*packet
, struct bt_ctf_stream
*stream
)
1332 struct bt_ctf_stream_class
*stream_class
= NULL
;
1333 struct bt_ctf_stream
*writer_stream
= NULL
;
1334 struct debug_info_trace
*di_trace
= NULL
;
1336 stream_class
= bt_ctf_stream_get_class(stream
);
1337 if (!stream_class
) {
1338 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1339 __func__
, __FILE__
, __LINE__
);
1343 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1345 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1346 __func__
, __FILE__
, __LINE__
);
1350 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1351 if (!writer_stream
) {
1352 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1353 __func__
, __FILE__
, __LINE__
);
1356 bt_get(writer_stream
);
1361 BT_PUT(writer_stream
);
1363 bt_put(stream_class
);
1364 return writer_stream
;
1368 struct bt_ctf_packet
*debug_info_new_packet(
1369 struct debug_info_iterator
*debug_it
,
1370 struct bt_ctf_packet
*packet
)
1372 struct bt_ctf_stream
*stream
= NULL
, *writer_stream
= NULL
;
1373 struct bt_ctf_field
*writer_packet_context
= NULL
;
1374 struct bt_ctf_packet
*writer_packet
= NULL
;
1375 struct debug_info_trace
*di_trace
;
1378 stream
= bt_ctf_packet_get_stream(packet
);
1380 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1381 __func__
, __FILE__
, __LINE__
);
1385 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1386 if (!writer_stream
) {
1387 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1388 __func__
, __FILE__
, __LINE__
);
1392 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1394 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
1395 __FILE__
, __LINE__
);
1400 * If a packet was already opened, close it and remove it from
1403 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1404 if (writer_packet
) {
1405 g_hash_table_remove(di_trace
->packet_map
, packet
);
1406 BT_PUT(writer_packet
);
1409 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1411 if (!writer_packet
) {
1412 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1413 __func__
, __FILE__
, __LINE__
);
1417 writer_packet_context
= ctf_copy_packet_context(debug_it
->err
, packet
,
1419 if (!writer_packet_context
) {
1420 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1421 __func__
, __FILE__
, __LINE__
);
1425 int_ret
= bt_ctf_packet_set_context(writer_packet
, writer_packet_context
);
1427 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1428 __func__
, __FILE__
, __LINE__
);
1432 bt_get(writer_packet
);
1438 bt_put(writer_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 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1512 fprintf(debug_it
->err
, "[error] Unexpected stream state %d\n",
1516 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1518 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1519 if (!writer_stream
) {
1520 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1522 bt_get(writer_stream
);
1527 BT_PUT(writer_stream
);
1529 return writer_stream
;
1533 struct bt_ctf_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1534 struct bt_ctf_stream
*stream
)
1536 struct bt_ctf_stream
*writer_stream
= NULL
;
1537 struct debug_info_trace
*di_trace
= NULL
;
1538 enum debug_info_stream_state
*state
;
1540 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1542 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1543 __func__
, __FILE__
, __LINE__
);
1547 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1548 if (!writer_stream
) {
1549 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
1550 __func__
, __FILE__
, __LINE__
);
1554 * Take the ref on the stream and keep it until the notification
1557 bt_get(writer_stream
);
1559 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1560 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1561 fprintf(debug_it
->err
, "[error] Unexpected stream "
1562 "state %d\n", *state
);
1565 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1567 g_hash_table_remove(di_trace
->stream_map
, stream
);
1569 if (di_trace
->trace_static
) {
1570 int trace_completed
= 1;
1572 g_hash_table_foreach(di_trace
->stream_states
,
1573 check_completed_trace
, &trace_completed
);
1574 if (trace_completed
) {
1575 debug_info_close_trace(debug_it
, di_trace
);
1576 g_hash_table_remove(debug_it
->trace_map
,
1584 BT_PUT(writer_stream
);
1587 return writer_stream
;
1591 struct debug_info_source
*lookup_debug_info(FILE *err
,
1592 struct bt_ctf_event
*event
,
1593 struct debug_info
*debug_info
)
1597 struct debug_info_source
*dbg_info_src
= NULL
;
1600 ret
= get_stream_event_context_int_field_value(err
, event
,
1606 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1612 /* Get debug info for this context. */
1613 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1616 return dbg_info_src
;
1620 int set_debug_info_field(FILE *err
, struct bt_ctf_field
*debug_field
,
1621 struct debug_info_source
*dbg_info_src
,
1622 struct debug_info_component
*component
)
1624 int i
, nr_fields
, ret
= 0;
1625 struct bt_ctf_field_type
*debug_field_type
= NULL
;
1626 struct bt_ctf_field
*field
= NULL
;
1627 struct bt_ctf_field_type
*field_type
= NULL
;
1629 debug_field_type
= bt_ctf_field_get_type(debug_field
);
1630 if (!debug_field_type
) {
1631 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1632 __FILE__
, __LINE__
);
1636 nr_fields
= bt_ctf_field_type_structure_get_field_count(debug_field_type
);
1637 for (i
= 0; i
< nr_fields
; i
++) {
1638 const char *field_name
;
1640 if (bt_ctf_field_type_structure_get_field(debug_field_type
,
1641 &field_name
, &field_type
, i
) < 0) {
1642 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1643 __FILE__
, __LINE__
);
1648 field
= bt_ctf_field_structure_get_field_by_index(debug_field
, i
);
1649 if (!strcmp(field_name
, "bin")) {
1650 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1651 GString
*tmp
= g_string_new(NULL
);
1653 if (component
->arg_full_path
) {
1654 g_string_printf(tmp
, "%s%s",
1655 dbg_info_src
->bin_path
,
1656 dbg_info_src
->bin_loc
);
1658 g_string_printf(tmp
, "%s%s",
1659 dbg_info_src
->short_bin_path
,
1660 dbg_info_src
->bin_loc
);
1662 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1663 g_string_free(tmp
, true);
1665 ret
= bt_ctf_field_string_set_value(field
, "");
1667 } else if (!strcmp(field_name
, "func")) {
1668 if (dbg_info_src
&& dbg_info_src
->func
) {
1669 ret
= bt_ctf_field_string_set_value(field
,
1670 dbg_info_src
->func
);
1672 ret
= bt_ctf_field_string_set_value(field
, "");
1674 } else if (!strcmp(field_name
, "src")) {
1675 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1676 GString
*tmp
= g_string_new(NULL
);
1678 if (component
->arg_full_path
) {
1679 g_string_printf(tmp
, "%s:%" PRId64
,
1680 dbg_info_src
->src_path
,
1681 dbg_info_src
->line_no
);
1683 g_string_printf(tmp
, "%s:%" PRId64
,
1684 dbg_info_src
->short_src_path
,
1685 dbg_info_src
->line_no
);
1687 ret
= bt_ctf_field_string_set_value(field
, tmp
->str
);
1688 g_string_free(tmp
, true);
1690 ret
= bt_ctf_field_string_set_value(field
, "");
1695 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1696 __FILE__
, __LINE__
);
1708 bt_put(debug_field_type
);
1713 int copy_set_debug_info_stream_event_context(FILE *err
,
1714 struct bt_ctf_field
*event_context
,
1715 struct bt_ctf_event
*event
,
1716 struct bt_ctf_event
*writer_event
,
1717 struct debug_info
*debug_info
,
1718 struct debug_info_component
*component
)
1720 struct bt_ctf_field_type
*writer_event_context_type
= NULL
,
1721 *event_context_type
= NULL
;
1722 struct bt_ctf_field
*writer_event_context
= NULL
;
1723 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1724 struct bt_ctf_field_type
*field_type
= NULL
;
1725 struct debug_info_source
*dbg_info_src
;
1726 int ret
, nr_fields
, i
;
1728 writer_event_context
= bt_ctf_event_get_stream_event_context(writer_event
);
1729 if (!writer_event_context
) {
1730 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
, __LINE__
);
1734 writer_event_context_type
= bt_ctf_field_get_type(writer_event_context
);
1735 if (!writer_event_context_type
) {
1736 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1737 __FILE__
, __LINE__
);
1741 event_context_type
= bt_ctf_field_get_type(event_context
);
1742 if (!event_context_type
) {
1743 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1744 __FILE__
, __LINE__
);
1749 * If it is not a structure, we did not modify it to add the debug info
1750 * fields, so just assign it as is.
1752 if (bt_ctf_field_type_get_type_id(writer_event_context_type
) != BT_CTF_FIELD_TYPE_ID_STRUCT
) {
1753 ret
= bt_ctf_event_set_event_context(writer_event
, event_context
);
1757 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1759 nr_fields
= bt_ctf_field_type_structure_get_field_count(writer_event_context_type
);
1760 for (i
= 0; i
< nr_fields
; i
++) {
1761 const char *field_name
;
1763 if (bt_ctf_field_type_structure_get_field(writer_event_context_type
,
1764 &field_name
, &field_type
, i
) < 0) {
1765 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1766 __FILE__
, __LINE__
);
1771 * Prevent illegal access in the event_context.
1773 if (i
< bt_ctf_field_type_structure_get_field_count(event_context_type
)) {
1774 field
= bt_ctf_field_structure_get_field_by_index(event_context
, i
);
1777 * The debug_info field, only exists in the writer event or
1778 * if it was set by a earlier pass of the debug_info plugin.
1780 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1782 debug_field
= bt_ctf_field_structure_get_field_by_index(
1783 writer_event_context
, i
);
1785 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1786 __FILE__
, __LINE__
);
1789 ret
= set_debug_info_field(err
, debug_field
,
1790 dbg_info_src
, component
);
1792 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1793 __FILE__
, __LINE__
);
1796 BT_PUT(debug_field
);
1798 copy_field
= bt_ctf_field_copy(field
);
1800 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1801 __FILE__
, __LINE__
);
1805 ret
= bt_ctf_field_structure_set_field(writer_event_context
,
1806 field_name
, copy_field
);
1808 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1809 __FILE__
, __LINE__
);
1824 bt_put(event_context_type
);
1825 bt_put(writer_event_context_type
);
1826 bt_put(writer_event_context
);
1829 bt_put(debug_field
);
1835 struct bt_ctf_clock_class
*stream_class_get_clock_class(FILE *err
,
1836 struct bt_ctf_stream_class
*stream_class
)
1838 struct bt_ctf_trace
*trace
= NULL
;
1839 struct bt_ctf_clock_class
*clock_class
= NULL
;
1841 trace
= bt_ctf_stream_class_get_trace(stream_class
);
1843 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1848 /* FIXME multi-clock? */
1849 clock_class
= bt_ctf_trace_get_clock_class_by_index(trace
, 0);
1858 struct bt_ctf_clock_class
*event_get_clock_class(FILE *err
, struct bt_ctf_event
*event
)
1860 struct bt_ctf_event_class
*event_class
= NULL
;
1861 struct bt_ctf_stream_class
*stream_class
= NULL
;
1862 struct bt_ctf_clock_class
*clock_class
= NULL
;
1864 event_class
= bt_ctf_event_get_class(event
);
1866 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1871 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
1872 if (!stream_class
) {
1873 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1878 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1882 BT_PUT(clock_class
);
1884 bt_put(stream_class
);
1885 bt_put(event_class
);
1890 int set_event_clock_value(FILE *err
, struct bt_ctf_event
*event
,
1891 struct bt_ctf_event
*writer_event
)
1893 struct bt_ctf_clock_class
*clock_class
= NULL
;
1894 struct bt_ctf_clock_value
*clock_value
= NULL
;
1897 clock_class
= event_get_clock_class(err
, event
);
1899 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1904 clock_value
= bt_ctf_event_get_clock_value(event
, clock_class
);
1906 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1912 * We share the same clocks, so we can assign the clock value to the
1915 ret
= bt_ctf_event_set_clock_value(writer_event
, clock_value
);
1917 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1928 bt_put(clock_class
);
1929 bt_put(clock_value
);
1934 struct bt_ctf_event
*debug_info_copy_event(FILE *err
, struct bt_ctf_event
*event
,
1935 struct bt_ctf_event_class
*writer_event_class
,
1936 struct debug_info
*debug_info
,
1937 struct debug_info_component
*component
)
1939 struct bt_ctf_event
*writer_event
= NULL
;
1940 struct bt_ctf_field
*field
= NULL
, *copy_field
= NULL
;
1943 writer_event
= bt_ctf_event_create(writer_event_class
);
1944 if (!writer_event
) {
1945 fprintf(err
, "[error] %s in %s:%d\n", __func__
, __FILE__
,
1950 ret
= set_event_clock_value(err
, event
, writer_event
);
1952 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1953 __FILE__
, __LINE__
);
1957 /* Optional field, so it can fail silently. */
1958 field
= bt_ctf_event_get_header(event
);
1960 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1961 writer_event
, field
);
1963 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1964 __FILE__
, __LINE__
);
1970 /* Optional field, so it can fail silently. */
1971 field
= bt_ctf_event_get_stream_event_context(event
);
1973 ret
= copy_set_debug_info_stream_event_context(err
,
1974 field
, event
, writer_event
, debug_info
,
1977 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1978 __FILE__
, __LINE__
);
1984 /* Optional field, so it can fail silently. */
1985 field
= bt_ctf_event_get_event_context(event
);
1987 copy_field
= bt_ctf_field_copy(field
);
1989 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1990 __FILE__
, __LINE__
);
1993 ret
= bt_ctf_event_set_event_context(writer_event
, copy_field
);
1995 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
1996 __FILE__
, __LINE__
);
2003 field
= bt_ctf_event_get_event_payload(event
);
2005 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2006 __FILE__
, __LINE__
);
2009 copy_field
= bt_ctf_field_copy(field
);
2011 ret
= bt_ctf_event_set_event_payload(writer_event
, copy_field
);
2013 fprintf(err
, "[error] %s in %s:%d\n", __func__
,
2014 __FILE__
, __LINE__
);
2024 BT_PUT(writer_event
);
2028 return writer_event
;
2032 struct bt_ctf_event
*debug_info_output_event(
2033 struct debug_info_iterator
*debug_it
,
2034 struct bt_ctf_event
*event
)
2036 struct bt_ctf_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
2037 struct bt_ctf_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
2038 struct bt_ctf_event
*writer_event
= NULL
;
2039 struct bt_ctf_packet
*packet
= NULL
, *writer_packet
= NULL
;
2040 struct bt_ctf_trace
*writer_trace
= NULL
;
2041 struct bt_ctf_stream
*stream
= NULL
;
2042 struct debug_info_trace
*di_trace
;
2043 struct debug_info
*debug_info
;
2044 const char *event_name
;
2047 event_class
= bt_ctf_event_get_class(event
);
2049 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2050 __FILE__
, __LINE__
);
2054 event_name
= bt_ctf_event_class_get_name(event_class
);
2056 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2057 __FILE__
, __LINE__
);
2061 stream_class
= bt_ctf_event_class_get_stream_class(event_class
);
2062 if (!stream_class
) {
2063 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2064 __FILE__
, __LINE__
);
2067 stream
= bt_ctf_event_get_stream(event
);
2069 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2070 __FILE__
, __LINE__
);
2073 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
2075 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2076 __FILE__
, __LINE__
);
2080 writer_stream_class
= g_hash_table_lookup(
2081 di_trace
->stream_class_map
,
2082 (gpointer
) stream_class
);
2083 if (!writer_stream_class
) {
2084 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2085 __FILE__
, __LINE__
);
2088 bt_get(writer_stream_class
);
2090 writer_event_class
= get_event_class(debug_it
,
2091 writer_stream_class
, event_class
);
2092 if (!writer_event_class
) {
2093 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
2095 if (!writer_event_class
) {
2096 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2097 __func__
, __FILE__
, __LINE__
);
2100 int_ret
= bt_ctf_stream_class_add_event_class(
2101 writer_stream_class
, writer_event_class
);
2103 fprintf(debug_it
->err
, "[error] %s in %s:%d\n",
2104 __func__
, __FILE__
, __LINE__
);
2109 writer_trace
= bt_ctf_stream_class_get_trace(writer_stream_class
);
2110 if (!writer_trace
) {
2111 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2112 __FILE__
, __LINE__
);
2116 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
2118 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
2121 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
2122 writer_event_class
, debug_info
,
2123 debug_it
->debug_info_component
);
2124 if (!writer_event
) {
2125 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2126 __FILE__
, __LINE__
);
2127 fprintf(debug_it
->err
, "[error] Failed to copy event %s\n",
2128 bt_ctf_event_class_get_name(writer_event_class
));
2132 packet
= bt_ctf_event_get_packet(event
);
2134 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2135 __FILE__
, __LINE__
);
2139 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
2140 if (!writer_packet
) {
2141 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2142 __FILE__
, __LINE__
);
2145 bt_get(writer_packet
);
2147 int_ret
= bt_ctf_event_set_packet(writer_event
, writer_packet
);
2149 fprintf(debug_it
->err
, "[error] %s in %s:%d\n", __func__
,
2150 __FILE__
, __LINE__
);
2151 fprintf(debug_it
->err
, "[error] Failed to append event %s\n",
2152 bt_ctf_event_class_get_name(writer_event_class
));
2156 /* Keep the reference on the writer event */
2160 BT_PUT(writer_event
);
2164 bt_put(writer_trace
);
2165 bt_put(writer_packet
);
2167 bt_put(writer_event_class
);
2168 bt_put(writer_stream_class
);
2169 bt_put(stream_class
);
2170 bt_put(event_class
);
2171 return writer_event
;