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
29 #define BT_LOG_TAG "PLUGIN-LTTNG-UTILS-DEBUG-INFO-FLT-COPY"
33 #include <babeltrace/assert-internal.h>
34 #include <babeltrace/babeltrace.h>
36 #include <ctfcopytrace.h>
37 #include "debug-info.h"
40 const bt_stream
*insert_new_stream(
41 struct debug_info_iterator
*debug_it
,
42 const bt_stream
*stream
,
43 struct debug_info_trace
*di_trace
);
46 void unref_stream(const bt_stream
*stream
)
48 bt_stream_put_ref(stream
);
52 void unref_packet(const bt_packet
*packet
)
54 bt_packet_put_ref(packet
);
58 void unref_stream_class(const bt_stream_class
*stream_class
)
60 bt_stream_class_put_ref(stream_class
);
64 void unref_debug_info(struct debug_info
*debug_info
)
66 debug_info_destroy(debug_info
);
70 void destroy_stream_state_key(gpointer key
)
72 g_free((enum fs_writer_stream_state
*) key
);
76 const bt_field
*get_payload_field(FILE *err
,
77 const bt_event
*event
, const char *field_name
)
79 const bt_field
*field
= NULL
, *payload
= NULL
;
80 const bt_field_class
*payload_class
= NULL
;
82 payload
= bt_event_get_payload(event
, NULL
);
85 payload_class
= bt_field_get_class(payload
);
86 BT_ASSERT(payload_class
);
88 if (bt_field_class_id(payload_class
) != BT_FIELD_CLASS_TYPE_STRUCT
) {
89 BT_LOGE("Wrong type, expected struct: field-name=\"%s\"",
94 field
= bt_field_structure_get_field_by_name(payload
, field_name
);
97 bt_field_class_put_ref(payload_class
);
98 bt_object_put_ref(payload
);
103 const bt_field
*get_stream_event_context_field(FILE *err
,
104 const bt_event
*event
, const char *field_name
)
106 const bt_field
*field
= NULL
, *sec
= NULL
;
107 const bt_field_class
*sec_class
= NULL
;
109 sec
= bt_event_get_stream_event_context(event
);
114 sec_class
= bt_field_get_class(sec
);
115 BT_ASSERT(sec_class
);
117 if (bt_field_class_id(sec_class
) != BT_FIELD_CLASS_TYPE_STRUCT
) {
118 BT_LOGE("Wrong type, expected struct, field-name=\"%s\"",
123 field
= bt_field_structure_get_field_by_name(sec
, field_name
);
126 bt_field_class_put_ref(sec_class
);
127 bt_object_put_ref(sec
);
132 int get_stream_event_context_unsigned_int_field_value(FILE *err
,
133 const bt_event
*event
, const char *field_name
,
137 const bt_field
*field
= NULL
;
138 const bt_field_class
*field_class
= NULL
;
140 field
= get_stream_event_context_field(err
, event
, field_name
);
145 field_class
= bt_field_get_class(field
);
146 BT_ASSERT(field_class
);
148 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_INTEGER
) {
149 BT_LOGE("Wrong type, expected integer: field-name=\"%s\"",
154 if (bt_ctf_field_class_integer_get_signed(field_class
) != 0) {
155 BT_LOGE("Wrong type, expected unsigned integer: field-name=\"%s\"",
160 ret
= bt_field_unsigned_integer_get_value(field
, value
);
162 BT_LOGE("Failed to get value: field-name=\"%s\"",
171 bt_field_class_put_ref(field_class
);
172 bt_object_put_ref(field
);
177 int get_stream_event_context_int_field_value(FILE *err
, const bt_event
*event
,
178 const char *field_name
, int64_t *value
)
180 const bt_field
*field
= NULL
;
181 const bt_field_class
*field_class
= NULL
;
184 field
= get_stream_event_context_field(err
, event
, field_name
);
189 field_class
= bt_field_get_class(field
);
190 BT_ASSERT(field_class
);
192 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_INTEGER
) {
193 BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", field_name
);
197 if (bt_ctf_field_class_integer_get_signed(field_class
) != 1) {
198 BT_LOGE("Wrong type, expected signed integer: field-name=\"%s\"",
203 ret
= bt_field_signed_integer_get_value(field
, value
);
209 bt_field_class_put_ref(field_class
);
210 bt_object_put_ref(field
);
215 int get_payload_unsigned_int_field_value(FILE *err
,
216 const bt_event
*event
, const char *field_name
,
219 const bt_field
*field
= NULL
;
220 const bt_field_class
*field_class
= NULL
;
223 field
= get_payload_field(err
, event
, field_name
);
225 BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name
);
229 field_class
= bt_field_get_class(field
);
230 BT_ASSERT(field_class
);
232 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_INTEGER
) {
233 BT_LOGE("Wrong type, expected integer: field-name=\"%s\"",
238 if (bt_ctf_field_class_integer_get_signed(field_class
) != 0) {
239 BT_LOGE("Wrong type, expected unsigned integer: field-name=\"%s\"",
244 ret
= bt_field_unsigned_integer_get_value(field
, value
);
246 BT_LOGE("Failed to get value: field-name=\"%s\"",
255 bt_field_class_put_ref(field_class
);
256 bt_object_put_ref(field
);
261 int get_payload_int_field_value(FILE *err
, const bt_event
*event
,
262 const char *field_name
, int64_t *value
)
264 const bt_field
*field
= NULL
;
265 const bt_field_class
*field_class
= NULL
;
268 field
= get_payload_field(err
, event
, field_name
);
270 BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name
);
274 field_class
= bt_field_get_class(field
);
275 BT_ASSERT(field_class
);
277 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_INTEGER
) {
278 BT_LOGE("Wrong type, expected integer: field-name=\"%s\"", field_name
);
282 if (bt_ctf_field_class_integer_get_signed(field_class
) != 1) {
283 BT_LOGE("Wrong type, expected signed integer field-name=\"%s\"",
288 ret
= bt_field_signed_integer_get_value(field
, value
);
290 BT_LOGE("Failed to get value: field-name=\"%s\"",
299 bt_field_class_put_ref(field_class
);
300 bt_object_put_ref(field
);
305 int get_payload_string_field_value(FILE *err
,
306 const bt_event
*event
, const char *field_name
,
309 const bt_field
*field
= NULL
;
310 const bt_field_class
*field_class
= NULL
;
314 * The field might not exist, no error here.
316 field
= get_payload_field(err
, event
, field_name
);
321 field_class
= bt_field_get_class(field
);
322 BT_ASSERT(field_class
);
324 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_STRING
) {
325 BT_LOGE("Wrong type, expected string: field-name=\"%s\"",
330 *value
= bt_field_string_get_value(field
);
332 BT_LOGE("Failed to get value: field-name=\"%s\"",
343 bt_field_class_put_ref(field_class
);
344 bt_object_put_ref(field
);
349 int get_payload_build_id_field_value(FILE *err
,
350 const bt_event
*event
, const char *field_name
,
351 uint8_t **build_id
, uint64_t *build_id_len
)
353 const bt_field
*field
= NULL
, *seq_len
= NULL
;
354 const bt_field_class
*field_class
= NULL
;
355 const bt_field
*seq_field
= NULL
;
361 field
= get_payload_field(err
, event
, field_name
);
363 BT_LOGE("Failed to get payload: field-name=\"%s\"", field_name
);
367 field_class
= bt_field_get_class(field
);
368 BT_ASSERT(field_class
);
370 if (bt_field_class_id(field_class
) != BT_FIELD_CLASS_TYPE_SEQUENCE
) {
371 BT_LOGE("Wrong type, expected sequence: field-name=\"%s\"", field_name
);
374 BT_FIELD_CLASS_PUT_REF_AND_RESET(field_class
);
376 seq_len
= bt_field_sequence_get_length(field
);
379 ret
= bt_field_unsigned_integer_get_value(seq_len
, build_id_len
);
381 BT_LOGE("Failed to get value: field-name=\"%s\"",
385 BT_OBJECT_PUT_REF_AND_RESET(seq_len
);
387 *build_id
= g_new0(uint8_t, *build_id_len
);
389 BT_LOGE_STR("Failed to allocate build_id.");
393 for (i
= 0; i
< *build_id_len
; i
++) {
396 seq_field
= bt_field_sequence_get_field(field
, i
);
398 BT_LOGE("Failed to get field in sequence: sequence-name=\"%s\", index=%" PRIu64
,
403 ret
= bt_field_unsigned_integer_get_value(seq_field
, &tmp
);
405 BT_LOGE("Failed to get value: field-name=\"%s\"",
410 BT_OBJECT_PUT_REF_AND_RESET(seq_field
);
411 (*build_id
)[i
] = (uint8_t) tmp
;
420 bt_field_class_put_ref(field_class
);
421 bt_object_put_ref(field
);
426 struct debug_info
*lookup_trace_debug_info(struct debug_info_iterator
*debug_it
,
427 const bt_trace
*writer_trace
,
428 struct debug_info_trace
*di_trace
)
430 return (struct debug_info
*) g_hash_table_lookup(
431 di_trace
->trace_debug_map
,
432 (gpointer
) writer_trace
);
436 struct debug_info
*insert_new_debug_info(struct debug_info_iterator
*debug_it
,
437 const bt_trace
*writer_trace
,
438 struct debug_info_trace
*di_trace
)
440 struct debug_info
*debug_info
= NULL
;
441 bt_value
*field
= NULL
;
442 const char *str_value
;
445 field
= bt_trace_get_environment_field_value_by_name(writer_trace
,
447 /* No domain field, no debug info */
451 str_value
= bt_value_string_get(field
);
453 /* Domain not ust, no debug info */
454 if (strcmp(str_value
, "ust") != 0) {
457 BT_VALUE_PUT_REF_AND_RESET(field
);
459 /* No tracer_name, no debug info */
460 field
= bt_trace_get_environment_field_value_by_name(writer_trace
,
462 /* No tracer_name, no debug info */
466 str_value
= bt_value_string_get(field
);
468 /* Tracer_name not lttng-ust, no debug info */
469 if (strcmp(str_value
, "lttng-ust") != 0) {
472 BT_VALUE_PUT_REF_AND_RESET(field
);
474 debug_info
= debug_info_create(debug_it
->debug_info_component
);
476 BT_LOGE_STR("Failed to create debug info.");
480 g_hash_table_insert(di_trace
->trace_debug_map
, (gpointer
) writer_trace
,
484 bt_value_put_ref(field
);
489 struct debug_info
*get_trace_debug_info(struct debug_info_iterator
*debug_it
,
490 const bt_trace
*writer_trace
,
491 struct debug_info_trace
*di_trace
)
493 struct debug_info
*debug_info
;
495 debug_info
= lookup_trace_debug_info(debug_it
, writer_trace
, di_trace
);
500 debug_info
= insert_new_debug_info(debug_it
, writer_trace
, di_trace
);
507 struct debug_info_trace
*lookup_trace(struct debug_info_iterator
*debug_it
,
508 const bt_trace
*trace
)
510 return (struct debug_info_trace
*) g_hash_table_lookup(
516 enum debug_info_stream_state
*insert_new_stream_state(
517 struct debug_info_iterator
*debug_it
,
518 struct debug_info_trace
*di_trace
, const bt_stream
*stream
)
520 enum debug_info_stream_state
*v
= NULL
;
522 v
= g_new0(enum debug_info_stream_state
, 1);
524 BT_LOGE_STR("Failed to allocate debug_info_stream_state.");
527 *v
= DEBUG_INFO_UNKNOWN_STREAM
;
529 g_hash_table_insert(di_trace
->stream_states
, stream
, v
);
536 void check_completed_trace(gpointer key
, gpointer value
, gpointer user_data
)
538 enum debug_info_stream_state
*state
= value
;
539 int *trace_completed
= user_data
;
541 if (*state
!= DEBUG_INFO_COMPLETED_STREAM
) {
542 *trace_completed
= 0;
547 gboolean
empty_ht(gpointer key
, gpointer value
, gpointer user_data
)
553 void debug_info_close_trace(struct debug_info_iterator
*debug_it
,
554 struct debug_info_trace
*di_trace
)
556 if (di_trace
->static_listener_id
>= 0) {
557 bt_trace_remove_is_static_listener(di_trace
->trace
,
558 di_trace
->static_listener_id
);
561 /* Empty the stream class HT. */
562 g_hash_table_foreach_remove(di_trace
->stream_class_map
,
564 g_hash_table_destroy(di_trace
->stream_class_map
);
566 /* Empty the stream HT. */
567 g_hash_table_foreach_remove(di_trace
->stream_map
,
569 g_hash_table_destroy(di_trace
->stream_map
);
571 /* Empty the stream state HT. */
572 g_hash_table_foreach_remove(di_trace
->stream_states
,
574 g_hash_table_destroy(di_trace
->stream_states
);
576 /* Empty the packet HT. */
577 g_hash_table_foreach_remove(di_trace
->packet_map
,
579 g_hash_table_destroy(di_trace
->packet_map
);
581 /* Empty the trace_debug HT. */
582 g_hash_table_foreach_remove(di_trace
->trace_debug_map
,
584 g_hash_table_destroy(di_trace
->trace_debug_map
);
588 int sync_event_classes(struct debug_info_iterator
*debug_it
,
589 const bt_stream
*stream
,
590 const bt_stream
*writer_stream
)
593 const bt_stream_class
*stream_class
= NULL
,
594 *writer_stream_class
= NULL
;
595 bt_component_status ret
;
597 stream_class
= bt_stream_get_class(stream
);
598 BT_ASSERT(stream_class
);
600 writer_stream_class
= bt_stream_get_class(writer_stream
);
601 BT_ASSERT(writer_stream_class
);
603 ret
= ctf_copy_event_classes(debug_it
->err
, stream_class
,
604 writer_stream_class
);
605 if (ret
!= BT_COMPONENT_STATUS_OK
) {
606 BT_LOGE_STR("Failed to copy event classes.");
616 bt_stream_class_put_ref(stream_class
);
617 bt_stream_class_put_ref(writer_stream_class
);
622 void trace_is_static_listener(const bt_trace
*trace
, void *data
)
624 struct debug_info_trace
*di_trace
= data
;
625 int trace_completed
= 1, ret
, nr_stream
, i
;
626 const bt_stream
*stream
= NULL
, *writer_stream
= NULL
;
627 const bt_trace
*writer_trace
= di_trace
->writer_trace
;
630 * When the trace becomes static, make sure that we have all
631 * the event classes in our stream_class copies before setting it
634 nr_stream
= bt_trace_get_stream_count(trace
);
635 for (i
= 0; i
< nr_stream
; i
++) {
636 stream
= bt_trace_get_stream_by_index(trace
, i
);
639 writer_stream
= bt_trace_get_stream_by_index(writer_trace
, i
);
640 BT_ASSERT(writer_stream
);
642 ret
= sync_event_classes(di_trace
->debug_it
, stream
, writer_stream
);
644 BT_LOGE_STR("Failed to synchronize the event classes.");
647 BT_STREAM_PUT_REF_AND_RESET(stream
);
648 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
651 bt_trace_set_is_static(di_trace
->writer_trace
);
652 di_trace
->trace_static
= 1;
654 g_hash_table_foreach(di_trace
->stream_states
,
655 check_completed_trace
, &trace_completed
);
656 if (trace_completed
) {
657 debug_info_close_trace(di_trace
->debug_it
, di_trace
);
658 g_hash_table_remove(di_trace
->debug_it
->trace_map
,
663 bt_stream_put_ref(writer_stream
);
664 bt_stream_put_ref(stream
);
668 struct debug_info_trace
*insert_new_trace(struct debug_info_iterator
*debug_it
,
669 const bt_stream
*stream
) {
670 const bt_trace
*writer_trace
= NULL
;
671 struct debug_info_trace
*di_trace
= NULL
;
672 const bt_trace
*trace
= NULL
;
673 const bt_stream_class
*stream_class
= NULL
;
674 const bt_stream
*writer_stream
= NULL
;
675 int ret
, nr_stream
, i
;
677 writer_trace
= bt_trace_create();
679 BT_LOGE_STR("Failed to create a new trace.");
683 stream_class
= bt_stream_get_class(stream
);
684 BT_ASSERT(stream_class
);
686 trace
= bt_stream_class_get_trace(stream_class
);
689 ret
= ctf_copy_trace(debug_it
->err
, trace
, writer_trace
);
690 if (ret
!= BT_COMPONENT_STATUS_OK
) {
691 BT_LOGE_STR("Failed to copy CTF trace.");
695 di_trace
= g_new0(struct debug_info_trace
, 1);
697 BT_LOGE_STR("Failed to allocate debug_info_trace.");
701 di_trace
->trace
= trace
;
702 di_trace
->writer_trace
= writer_trace
;
703 di_trace
->debug_info_component
= debug_it
->debug_info_component
;
704 di_trace
->debug_it
= debug_it
;
705 di_trace
->stream_map
= g_hash_table_new_full(g_direct_hash
,
706 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream
);
707 di_trace
->stream_class_map
= g_hash_table_new_full(g_direct_hash
,
708 g_direct_equal
, NULL
, (GDestroyNotify
) unref_stream_class
);
709 di_trace
->packet_map
= g_hash_table_new_full(g_direct_hash
,
710 g_direct_equal
, NULL
, (GDestroyNotify
) unref_packet
);
711 di_trace
->trace_debug_map
= g_hash_table_new_full(g_direct_hash
,
712 g_direct_equal
, NULL
, (GDestroyNotify
) unref_debug_info
);
713 di_trace
->stream_states
= g_hash_table_new_full(g_direct_hash
,
714 g_direct_equal
, NULL
, destroy_stream_state_key
);
715 g_hash_table_insert(debug_it
->trace_map
, (gpointer
) trace
, di_trace
);
717 /* Set all the existing streams in the unknown state. */
718 nr_stream
= bt_trace_get_stream_count(trace
);
719 for (i
= 0; i
< nr_stream
; i
++) {
720 stream
= bt_trace_get_stream_by_index(trace
, i
);
723 insert_new_stream_state(debug_it
, di_trace
, stream
);
724 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
725 if (!writer_stream
) {
726 BT_LOGE_STR("Failed to insert new stream.");
729 bt_stream_get_ref(writer_stream
);
730 ret
= sync_event_classes(debug_it
, stream
, writer_stream
);
732 BT_LOGE_STR("Failed to synchronize event classes.");
735 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
736 BT_STREAM_PUT_REF_AND_RESET(stream
);
739 /* Check if the trace is already static or register a listener. */
740 if (bt_trace_is_static(trace
)) {
741 di_trace
->trace_static
= 1;
742 di_trace
->static_listener_id
= -1;
743 bt_trace_set_is_static(writer_trace
);
745 ret
= bt_trace_add_is_static_listener(trace
,
746 trace_is_static_listener
, NULL
, di_trace
);
748 di_trace
->static_listener_id
= ret
;
755 BT_TRACE_PUT_REF_AND_RESET(writer_trace
);
759 bt_stream_put_ref(stream
);
760 bt_stream_put_ref(writer_stream
);
761 bt_stream_class_put_ref(stream_class
);
762 bt_trace_put_ref(trace
);
767 const bt_packet
*lookup_packet(struct debug_info_iterator
*debug_it
,
768 const bt_packet
*packet
,
769 struct debug_info_trace
*di_trace
)
771 return (const bt_packet
*) g_hash_table_lookup(
772 di_trace
->packet_map
,
777 const bt_packet
*insert_new_packet(struct debug_info_iterator
*debug_it
,
778 const bt_packet
*packet
,
779 const bt_stream
*writer_stream
,
780 struct debug_info_trace
*di_trace
)
782 const bt_packet
*writer_packet
;
785 writer_packet
= bt_packet_create(writer_stream
);
786 if (!writer_packet
) {
787 BT_LOGE_STR("Failed to create new packet.");
791 ret
= ctf_packet_copy_header(debug_it
->err
, packet
, writer_packet
);
793 BT_LOGE_STR("Failed to copy packet header.");
797 g_hash_table_insert(di_trace
->packet_map
, (gpointer
) packet
,
802 BT_PACKET_PUT_REF_AND_RESET(writer_packet
);
804 return writer_packet
;
808 int add_debug_info_fields(FILE *err
,
809 const bt_field_class
*writer_event_context_class
,
810 struct debug_info_component
*component
)
812 const bt_field_class
*ip_field
= NULL
, *debug_field_class
= NULL
,
813 *bin_field_class
= NULL
, *func_field_class
= NULL
,
814 *src_field_class
= NULL
;
817 ip_field
= bt_field_class_structure_get_field_class_by_name(
818 writer_event_context_class
, IP_FIELD_NAME
);
819 /* No ip field, so no debug info. */
823 BT_FIELD_CLASS_PUT_REF_AND_RESET(ip_field
);
825 debug_field_class
= bt_field_class_structure_get_field_class_by_name(
826 writer_event_context_class
,
827 component
->arg_debug_info_field_name
);
828 /* Already existing debug_info field, no need to add it. */
829 if (debug_field_class
) {
833 debug_field_class
= bt_field_class_structure_create();
834 if (!debug_field_class
) {
835 BT_LOGE_STR("Failed to create debug_info structure.");
839 bin_field_class
= bt_field_class_string_create();
840 if (!bin_field_class
) {
841 BT_LOGE_STR("Failed to create string for field=bin.");
845 func_field_class
= bt_field_class_string_create();
846 if (!func_field_class
) {
847 BT_LOGE_STR("Failed to create string for field=func.");
851 src_field_class
= bt_field_class_string_create();
852 if (!src_field_class
) {
853 BT_LOGE_STR("Failed to create string for field=src.");
857 ret
= bt_field_class_structure_add_field(debug_field_class
,
858 bin_field_class
, "bin");
860 BT_LOGE_STR("Failed to add a field to debug_info struct: field=bin.");
864 ret
= bt_field_class_structure_add_field(debug_field_class
,
865 func_field_class
, "func");
867 BT_LOGE_STR("Failed to add a field to debug_info struct: field=func.");
871 ret
= bt_field_class_structure_add_field(debug_field_class
,
872 src_field_class
, "src");
874 BT_LOGE_STR("Failed to add a field to debug_info struct: field=src.");
878 ret
= bt_field_class_structure_add_field(writer_event_context_class
,
879 debug_field_class
, component
->arg_debug_info_field_name
);
881 BT_LOGE_STR("Failed to add debug_info field to event_context.");
889 BT_FIELD_CLASS_PUT_REF_AND_RESET(debug_field_class
);
892 bt_field_class_put_ref(src_field_class
);
893 bt_field_class_put_ref(func_field_class
);
894 bt_field_class_put_ref(bin_field_class
);
895 bt_field_class_put_ref(debug_field_class
);
900 int create_debug_info_event_context_class(FILE *err
,
901 const bt_field_class
*event_context_class
,
902 const bt_field_class
*writer_event_context_class
,
903 struct debug_info_component
*component
)
905 int ret
, nr_fields
, i
;
907 nr_fields
= bt_field_class_structure_get_field_count(event_context_class
);
908 for (i
= 0; i
< nr_fields
; i
++) {
909 const bt_field_class
*field_class
= NULL
;
910 const char *field_name
;
912 if (bt_field_class_structure_get_field_by_index(event_context_class
,
913 &field_name
, &field_class
, i
) < 0) {
914 BT_LOGE("Failed to get a field from the event-context: field-name=\"%s\"",
919 ret
= bt_field_class_structure_add_field(writer_event_context_class
,
920 field_class
, field_name
);
921 BT_FIELD_CLASS_PUT_REF_AND_RESET(field_class
);
923 BT_LOGE("Failed to add a field to the event-context: field-name=\"%s\"",
929 ret
= add_debug_info_fields(err
, writer_event_context_class
,
940 const bt_stream_class
*copy_stream_class_debug_info(FILE *err
,
941 const bt_stream_class
*stream_class
,
942 const bt_trace
*writer_trace
,
943 struct debug_info_component
*component
)
945 const bt_field_class
*cls
= NULL
;
946 const bt_stream_class
*writer_stream_class
= NULL
;
947 const bt_field_class
*writer_event_context_class
= NULL
;
949 const char *name
= bt_stream_class_get_name(stream_class
);
951 writer_stream_class
= bt_stream_class_create_empty(name
);
952 if (!writer_stream_class
) {
953 BT_LOGE_STR("Failed to create empty stream class.");
957 type
= bt_stream_class_get_packet_context_class(stream_class
);
959 ret_int
= bt_stream_class_set_packet_context_class(
960 writer_stream_class
, type
);
962 BT_LOGE_STR("Failed to set packet_context type.");
965 BT_OBJECT_PUT_REF_AND_RESET(type
);
968 type
= bt_stream_class_get_event_header_type(stream_class
);
970 ret_int
= bt_stream_class_set_event_header_type(
971 writer_stream_class
, type
);
973 BT_LOGE_STR("Failed to set event_header type.");
976 BT_OBJECT_PUT_REF_AND_RESET(type
);
979 type
= bt_stream_class_get_event_context_class(stream_class
);
981 writer_event_context_class
= bt_field_class_structure_create();
982 if (!writer_event_context_class
) {
983 BT_LOGE_STR("Failed to create writer_event_context struct type.");
986 ret_int
= create_debug_info_event_context_class(err
, type
,
987 writer_event_context_class
, component
);
989 BT_LOGE_STR("Failed to create debug_info event_context type.");
992 BT_OBJECT_PUT_REF_AND_RESET(type
);
994 ret_int
= bt_stream_class_set_event_context_class(
995 writer_stream_class
, writer_event_context_class
);
997 BT_LOGE_STR("Failed to set event_context type.");
1000 BT_FIELD_CLASS_PUT_REF_AND_RESET(writer_event_context_class
);
1006 BT_STREAM_CLASS_PUT_REF_AND_RESET(writer_stream_class
);
1008 bt_field_class_put_ref(writer_event_context_class
);
1009 bt_object_put_ref(type
);
1010 return writer_stream_class
;
1014 * Add the original clock classes to the new trace, we do not need to copy
1015 * them, and if we did, we would have to manually inspect the stream class
1016 * to update the integers mapping to a clock.
1019 int add_clock_classes(FILE *err
, const bt_trace
*writer_trace
,
1020 const bt_stream_class
*writer_stream_class
,
1021 const bt_trace
*trace
)
1023 int ret
, clock_class_count
, i
;
1025 clock_class_count
= bt_trace_get_clock_class_count(trace
);
1027 for (i
= 0; i
< clock_class_count
; i
++) {
1028 const bt_clock_class
*clock_class
=
1029 bt_trace_get_clock_class_by_index(trace
, i
);
1030 const bt_clock_class
*existing_clock_class
= NULL
;
1032 BT_ASSERT(clock_class
);
1034 existing_clock_class
= bt_trace_get_clock_class_by_name(
1035 writer_trace
, bt_clock_class_get_name(clock_class
));
1036 bt_clock_class_put_ref(existing_clock_class
);
1037 if (existing_clock_class
) {
1038 bt_clock_class_put_ref(clock_class
);
1042 ret
= bt_trace_add_clock_class(writer_trace
, clock_class
);
1043 BT_CLOCK_CLASS_PUT_REF_AND_RESET(clock_class
);
1045 BT_LOGE_STR("Failed to add clock_class.");
1061 const bt_stream_class
*insert_new_stream_class(
1062 struct debug_info_iterator
*debug_it
,
1063 const bt_stream_class
*stream_class
)
1065 const bt_stream_class
*writer_stream_class
= NULL
;
1066 const bt_trace
*trace
, *writer_trace
= NULL
;
1067 struct debug_info_trace
*di_trace
;
1068 bt_component_status ret
;
1071 trace
= bt_stream_class_get_trace(stream_class
);
1074 di_trace
= lookup_trace(debug_it
, trace
);
1076 BT_LOGE_STR("Failed to find existing trace.");
1077 ret
= BT_COMPONENT_STATUS_ERROR
;
1080 writer_trace
= di_trace
->writer_trace
;
1081 bt_trace_get_ref(writer_trace
);
1083 writer_stream_class
= copy_stream_class_debug_info(debug_it
->err
, stream_class
,
1084 writer_trace
, debug_it
->debug_info_component
);
1085 if (!writer_stream_class
) {
1086 BT_LOGE_STR("Failed to copy stream class.");
1090 int_ret
= bt_trace_add_stream_class(writer_trace
, writer_stream_class
);
1092 BT_LOGE_STR("Failed to add stream class.");
1096 ret
= add_clock_classes(debug_it
->err
, writer_trace
,
1097 writer_stream_class
, trace
);
1098 if (ret
!= BT_COMPONENT_STATUS_OK
) {
1099 BT_LOGE_STR("Failed to add clock classes.");
1103 g_hash_table_insert(di_trace
->stream_class_map
,
1104 (gpointer
) stream_class
, writer_stream_class
);
1109 BT_STREAM_CLASS_PUT_REF_AND_RESET(writer_stream_class
);
1111 bt_trace_put_ref(trace
);
1112 bt_trace_put_ref(writer_trace
);
1113 return writer_stream_class
;
1117 const bt_stream
*insert_new_stream(
1118 struct debug_info_iterator
*debug_it
,
1119 const bt_stream
*stream
,
1120 struct debug_info_trace
*di_trace
)
1122 const bt_stream
*writer_stream
= NULL
;
1123 const bt_stream_class
*stream_class
= NULL
;
1124 const bt_stream_class
*writer_stream_class
= NULL
;
1127 stream_class
= bt_stream_get_class(stream
);
1128 BT_ASSERT(stream_class
);
1130 writer_stream_class
= g_hash_table_lookup(
1131 di_trace
->stream_class_map
,
1132 (gpointer
) stream_class
);
1134 if (!writer_stream_class
) {
1135 writer_stream_class
= insert_new_stream_class(debug_it
,
1137 if (!writer_stream_class
) {
1138 BT_LOGE_STR("Failed to insert new stream class.");
1142 bt_stream_class_get_ref(writer_stream_class
);
1144 id
= bt_stream_get_id(stream
);
1146 writer_stream
= bt_stream_create(writer_stream_class
,
1147 bt_stream_get_name(stream
));
1149 writer_stream
= bt_stream_create_with_id(
1150 writer_stream_class
,
1151 bt_stream_get_name(stream
), id
);
1154 if (!writer_stream
) {
1155 BT_LOGE_STR("Failed to create writer_stream.");
1159 g_hash_table_insert(di_trace
->stream_map
, (gpointer
) stream
,
1165 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
1167 bt_stream_class_put_ref(stream_class
);
1168 bt_stream_class_put_ref(writer_stream_class
);
1169 return writer_stream
;
1173 const bt_stream
*lookup_stream(struct debug_info_iterator
*debug_it
,
1174 const bt_stream
*stream
,
1175 struct debug_info_trace
*di_trace
)
1177 return (const bt_stream
*) g_hash_table_lookup(
1178 di_trace
->stream_map
, (gpointer
) stream
);
1182 const bt_event_class
*get_event_class(struct debug_info_iterator
*debug_it
,
1183 const bt_stream_class
*writer_stream_class
,
1184 const bt_event_class
*event_class
)
1186 return bt_stream_class_get_event_class_by_id(writer_stream_class
,
1187 bt_event_class_get_id(event_class
));
1191 struct debug_info_trace
*lookup_di_trace_from_stream(
1192 struct debug_info_iterator
*debug_it
,
1193 const bt_stream
*stream
)
1195 const bt_stream_class
*stream_class
= NULL
;
1196 const bt_trace
*trace
= NULL
;
1197 struct debug_info_trace
*di_trace
= NULL
;
1199 stream_class
= bt_stream_get_class(stream
);
1200 BT_ASSERT(stream_class
);
1202 trace
= bt_stream_class_get_trace(stream_class
);
1205 di_trace
= (struct debug_info_trace
*) g_hash_table_lookup(
1206 debug_it
->trace_map
, (gpointer
) trace
);
1208 BT_STREAM_CLASS_PUT_REF_AND_RESET(stream_class
);
1209 BT_TRACE_PUT_REF_AND_RESET(trace
);
1214 const bt_stream
*get_writer_stream(
1215 struct debug_info_iterator
*debug_it
,
1216 const bt_packet
*packet
, const bt_stream
*stream
)
1218 const bt_stream_class
*stream_class
= NULL
;
1219 const bt_stream
*writer_stream
= NULL
;
1220 struct debug_info_trace
*di_trace
= NULL
;
1222 stream_class
= bt_stream_get_class(stream
);
1223 BT_ASSERT(stream_class
);
1225 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1227 BT_LOGE_STR("Failed to find existing trace from stream.");
1231 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1232 if (!writer_stream
) {
1233 BT_LOGE_STR("Failed to find existing stream.");
1236 bt_stream_get_ref(writer_stream
);
1241 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
1243 bt_stream_class_put_ref(stream_class
);
1244 return writer_stream
;
1248 const bt_packet
*debug_info_new_packet(
1249 struct debug_info_iterator
*debug_it
,
1250 const bt_packet
*packet
)
1252 const bt_stream
*stream
= NULL
, *writer_stream
= NULL
;
1253 const bt_packet
*writer_packet
= NULL
;
1254 const bt_field
*packet_context
= NULL
;
1255 struct debug_info_trace
*di_trace
;
1258 stream
= bt_packet_get_stream(packet
);
1261 writer_stream
= get_writer_stream(debug_it
, packet
, stream
);
1262 if (!writer_stream
) {
1263 BT_LOGE_STR("Failed to get writer stream.");
1267 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1269 BT_LOGE_STR("Failed to find existing trace from stream.");
1274 * If a packet was already opened, close it and remove it from
1277 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1278 if (writer_packet
) {
1279 g_hash_table_remove(di_trace
->packet_map
, packet
);
1280 BT_PACKET_PUT_REF_AND_RESET(writer_packet
);
1283 writer_packet
= insert_new_packet(debug_it
, packet
, writer_stream
,
1285 if (!writer_packet
) {
1286 BT_LOGE_STR("Failed to insert new packet.");
1290 packet_context
= bt_packet_get_context(packet
);
1291 if (packet_context
) {
1292 int_ret
= ctf_packet_copy_context(debug_it
->err
,
1293 packet
, writer_stream
, writer_packet
);
1295 BT_LOGE_STR("Failed to copy packet context.");
1298 BT_OBJECT_PUT_REF_AND_RESET(packet_context
);
1301 bt_packet_get_ref(writer_packet
);
1307 bt_object_put_ref(packet_context
);
1308 bt_stream_put_ref(writer_stream
);
1309 bt_stream_put_ref(stream
);
1310 return writer_packet
;
1314 const bt_packet
*debug_info_close_packet(
1315 struct debug_info_iterator
*debug_it
,
1316 const bt_packet
*packet
)
1318 const bt_packet
*writer_packet
= NULL
;
1319 const bt_stream
*stream
= NULL
;
1320 struct debug_info_trace
*di_trace
;
1322 stream
= bt_packet_get_stream(packet
);
1325 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1327 BT_LOGE_STR("Failed to find trace from stream.");
1331 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1332 if (!writer_packet
) {
1333 BT_LOGE_STR("Failed to find existing packet.");
1336 bt_packet_get_ref(writer_packet
);
1337 g_hash_table_remove(di_trace
->packet_map
, packet
);
1340 bt_stream_put_ref(stream
);
1341 return writer_packet
;
1345 const bt_stream
*debug_info_stream_begin(
1346 struct debug_info_iterator
*debug_it
,
1347 const bt_stream
*stream
)
1349 const bt_stream
*writer_stream
= NULL
;
1350 enum debug_info_stream_state
*state
;
1351 struct debug_info_trace
*di_trace
= NULL
;
1353 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1355 di_trace
= insert_new_trace(debug_it
, stream
);
1357 BT_LOGE_STR("Failed to insert new trace.");
1362 /* Set the stream as active */
1363 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1365 if (di_trace
->trace_static
) {
1366 BT_LOGE_STR("Failed to add a new stream, trace is static.");
1369 state
= insert_new_stream_state(debug_it
, di_trace
,
1372 BT_LOGE_STR("Failed to add new stream state.");
1376 if (*state
!= DEBUG_INFO_UNKNOWN_STREAM
) {
1377 BT_LOGE("Unexpected stream state: state=%d", *state
);
1380 *state
= DEBUG_INFO_ACTIVE_STREAM
;
1382 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1383 if (!writer_stream
) {
1384 writer_stream
= insert_new_stream(debug_it
, stream
, di_trace
);
1386 bt_stream_get_ref(writer_stream
);
1391 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
1393 return writer_stream
;
1397 const bt_stream
*debug_info_stream_end(struct debug_info_iterator
*debug_it
,
1398 const bt_stream
*stream
)
1400 const bt_stream
*writer_stream
= NULL
;
1401 struct debug_info_trace
*di_trace
= NULL
;
1402 enum debug_info_stream_state
*state
;
1404 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1406 BT_LOGE_STR("Failed to find existing trace from stream.");
1410 writer_stream
= lookup_stream(debug_it
, stream
, di_trace
);
1411 if (!writer_stream
) {
1412 BT_LOGE_STR("Failed to find existing stream.");
1416 * Take the ref on the stream and keep it until the message
1419 bt_stream_get_ref(writer_stream
);
1421 state
= g_hash_table_lookup(di_trace
->stream_states
, stream
);
1422 if (*state
!= DEBUG_INFO_ACTIVE_STREAM
) {
1423 BT_LOGE("Unexpected stream state: state=%d", *state
);
1426 *state
= DEBUG_INFO_COMPLETED_STREAM
;
1428 g_hash_table_remove(di_trace
->stream_map
, stream
);
1430 if (di_trace
->trace_static
) {
1431 int trace_completed
= 1;
1433 g_hash_table_foreach(di_trace
->stream_states
,
1434 check_completed_trace
, &trace_completed
);
1435 if (trace_completed
) {
1436 debug_info_close_trace(debug_it
, di_trace
);
1437 g_hash_table_remove(debug_it
->trace_map
,
1445 BT_STREAM_PUT_REF_AND_RESET(writer_stream
);
1448 return writer_stream
;
1452 struct debug_info_source
*lookup_debug_info(FILE *err
,
1453 const bt_event
*event
,
1454 struct debug_info
*debug_info
)
1458 struct debug_info_source
*dbg_info_src
= NULL
;
1461 ret
= get_stream_event_context_int_field_value(err
, event
,
1462 VPID_FIELD_NAME
, &vpid
);
1467 ret
= get_stream_event_context_unsigned_int_field_value(err
, event
,
1468 IP_FIELD_NAME
, &ip
);
1473 /* Get debug info for this context. */
1474 dbg_info_src
= debug_info_query(debug_info
, vpid
, ip
);
1477 return dbg_info_src
;
1481 int set_debug_info_field(FILE *err
, const bt_field
*debug_field
,
1482 struct debug_info_source
*dbg_info_src
,
1483 struct debug_info_component
*component
)
1485 int i
, nr_fields
, ret
= 0;
1486 const bt_field_class
*debug_field_class
= NULL
;
1487 const bt_field
*field
= NULL
;
1488 const bt_field_class
*field_class
= NULL
;
1490 debug_field_class
= bt_field_get_class(debug_field
);
1491 BT_ASSERT(debug_field_class
);
1493 nr_fields
= bt_field_class_structure_get_field_count(debug_field_class
);
1494 for (i
= 0; i
< nr_fields
; i
++) {
1495 const char *field_name
;
1497 if (bt_field_class_structure_get_field_by_index(debug_field_class
,
1498 &field_name
, &field_class
, i
) < 0) {
1499 BT_LOGE("Failed to get field from debug_info struct: field-name=\"%s\"",
1503 BT_FIELD_CLASS_PUT_REF_AND_RESET(field_class
);
1505 field
= bt_field_structure_get_field_by_index(debug_field
, i
);
1506 if (!strcmp(field_name
, "bin")) {
1507 if (dbg_info_src
&& dbg_info_src
->bin_path
) {
1508 GString
*tmp
= g_string_new(NULL
);
1510 if (component
->arg_full_path
) {
1511 g_string_printf(tmp
, "%s%s",
1512 dbg_info_src
->bin_path
,
1513 dbg_info_src
->bin_loc
);
1515 g_string_printf(tmp
, "%s%s",
1516 dbg_info_src
->short_bin_path
,
1517 dbg_info_src
->bin_loc
);
1519 ret
= bt_field_string_set_value(field
, tmp
->str
);
1520 g_string_free(tmp
, true);
1522 ret
= bt_field_string_set_value(field
, "");
1524 } else if (!strcmp(field_name
, "func")) {
1525 if (dbg_info_src
&& dbg_info_src
->func
) {
1526 ret
= bt_field_string_set_value(field
,
1527 dbg_info_src
->func
);
1529 ret
= bt_field_string_set_value(field
, "");
1531 } else if (!strcmp(field_name
, "src")) {
1532 if (dbg_info_src
&& dbg_info_src
->src_path
) {
1533 GString
*tmp
= g_string_new(NULL
);
1535 if (component
->arg_full_path
) {
1536 g_string_printf(tmp
, "%s:%" PRId64
,
1537 dbg_info_src
->src_path
,
1538 dbg_info_src
->line_no
);
1540 g_string_printf(tmp
, "%s:%" PRId64
,
1541 dbg_info_src
->short_src_path
,
1542 dbg_info_src
->line_no
);
1544 ret
= bt_field_string_set_value(field
, tmp
->str
);
1545 g_string_free(tmp
, true);
1547 ret
= bt_field_string_set_value(field
, "");
1550 BT_OBJECT_PUT_REF_AND_RESET(field
);
1552 BT_LOGE("Failed to set value in debug-info struct: field-name=\"%s\"",
1563 bt_field_class_put_ref(field_class
);
1564 bt_object_put_ref(field
);
1565 bt_field_class_put_ref(debug_field_class
);
1570 int copy_set_debug_info_stream_event_context(FILE *err
,
1571 const bt_field
*event_context
,
1572 const bt_event
*event
,
1573 const bt_event
*writer_event
,
1574 struct debug_info
*debug_info
,
1575 struct debug_info_component
*component
)
1577 const bt_field_class
*writer_event_context_class
= NULL
,
1578 *event_context_class
= NULL
;
1579 const bt_field
*writer_event_context
= NULL
;
1580 const bt_field
*field
= NULL
, *copy_field
= NULL
, *debug_field
= NULL
;
1581 const bt_field_class
*field_class
= NULL
;
1582 struct debug_info_source
*dbg_info_src
;
1583 int ret
, nr_fields
, i
;
1585 writer_event_context
= bt_event_get_stream_event_context(writer_event
);
1586 BT_ASSERT(writer_event_context
);
1588 writer_event_context_class
= bt_field_get_class(writer_event_context
);
1589 BT_ASSERT(writer_event_context_class
);
1591 event_context_class
= bt_field_get_class(event_context
);
1592 BT_ASSERT(event_context_class
);
1595 * If it is not a structure, we did not modify it to add the debug info
1596 * fields, so just assign it as is.
1598 if (bt_field_class_id(writer_event_context_class
) != BT_FIELD_CLASS_TYPE_STRUCT
) {
1599 ret
= bt_event_set_event_context(writer_event
, event_context
);
1603 dbg_info_src
= lookup_debug_info(err
, event
, debug_info
);
1605 nr_fields
= bt_field_class_structure_get_field_count(writer_event_context_class
);
1606 for (i
= 0; i
< nr_fields
; i
++) {
1607 const char *field_name
;
1609 if (bt_field_class_structure_get_field_by_index(writer_event_context_class
,
1610 &field_name
, &field_class
, i
) < 0) {
1611 BT_LOGE("Failed to get field from event-context: field-name=\"%s\"",
1617 * Prevent illegal access in the event_context.
1619 if (i
< bt_field_class_structure_get_field_count(event_context_class
)) {
1620 field
= bt_field_structure_get_field_by_index(event_context
, i
);
1623 * The debug_info field, only exists in the writer event or
1624 * if it was set by a earlier pass of the debug_info plugin.
1626 if (!strcmp(field_name
, component
->arg_debug_info_field_name
) &&
1628 debug_field
= bt_field_structure_get_field_by_index(
1629 writer_event_context
, i
);
1630 BT_ASSERT(debug_field
);
1632 ret
= set_debug_info_field(err
, debug_field
,
1633 dbg_info_src
, component
);
1635 BT_LOGE_STR("Failed to set debug_info field.");
1638 BT_OBJECT_PUT_REF_AND_RESET(debug_field
);
1640 copy_field
= bt_field_copy(field
);
1642 BT_LOGE("Failed to copy field: field-name=\"%s\"",
1647 ret
= bt_field_structure_set_field_by_name(
1648 writer_event_context
,
1649 field_name
, copy_field
);
1651 BT_LOGE("Failed to set field: field-name=\"%s\"",
1655 BT_OBJECT_PUT_REF_AND_RESET(copy_field
);
1657 BT_FIELD_CLASS_PUT_REF_AND_RESET(field_class
);
1658 BT_OBJECT_PUT_REF_AND_RESET(field
);
1667 bt_field_class_put_ref(event_context_class
);
1668 bt_field_class_put_ref(writer_event_context_class
);
1669 bt_object_put_ref(writer_event_context
);
1670 bt_object_put_ref(field
);
1671 bt_object_put_ref(copy_field
);
1672 bt_object_put_ref(debug_field
);
1673 bt_field_class_put_ref(field_class
);
1678 const bt_clock_class
*stream_class_get_clock_class(FILE *err
,
1679 const bt_stream_class
*stream_class
)
1681 const bt_trace
*trace
= NULL
;
1682 const bt_clock_class
*clock_class
= NULL
;
1684 trace
= bt_stream_class_get_trace(stream_class
);
1687 if (!bt_trace_get_clock_class_count(trace
)) {
1692 /* FIXME multi-clock? */
1693 clock_class
= bt_trace_get_clock_class_by_index(trace
, 0);
1695 bt_trace_put_ref(trace
);
1702 const bt_clock_class
*event_get_clock_class(FILE *err
, const bt_event
*event
)
1704 const bt_event_class
*event_class
= NULL
;
1705 const bt_stream_class
*stream_class
= NULL
;
1706 const bt_clock_class
*clock_class
= NULL
;
1708 event_class
= bt_event_get_class(event
);
1709 BT_ASSERT(event_class
);
1711 stream_class
= bt_event_class_get_stream_class(event_class
);
1712 BT_ASSERT(stream_class
);
1714 clock_class
= stream_class_get_clock_class(err
, stream_class
);
1718 bt_stream_class_put_ref(stream_class
);
1719 bt_event_class_put_ref(event_class
);
1724 int set_event_clock_snapshot(FILE *err
, const bt_event
*event
,
1725 const bt_event
*writer_event
)
1727 const bt_clock_class
*clock_class
= NULL
;
1728 bt_clock_snapshot
*clock_snapshot
= NULL
;
1731 clock_class
= event_get_clock_class(err
, event
);
1733 /* No clock on input trace. */
1737 clock_snapshot
= bt_event_get_clock_snapshot(event
, clock_class
);
1738 if (!clock_snapshot
) {
1744 * We share the same clocks, so we can assign the clock value to the
1747 ret
= bt_event_set_clock_snapshot(writer_event
, clock_snapshot
);
1749 BT_LOGE_STR("Failed to set clock value.");
1759 bt_clock_class_put_ref(clock_class
);
1760 bt_object_put_ref(clock_snapshot
);
1765 const bt_event
*debug_info_copy_event(FILE *err
, const bt_event
*event
,
1766 const bt_event_class
*writer_event_class
,
1767 struct debug_info
*debug_info
,
1768 struct debug_info_component
*component
)
1770 const bt_event
*writer_event
= NULL
;
1771 const bt_field
*field
= NULL
, *copy_field
= NULL
;
1774 writer_event
= bt_event_create(writer_event_class
);
1775 if (!writer_event
) {
1776 BT_LOGE_STR("Failed to create new event.");
1780 ret
= set_event_clock_snapshot(err
, event
, writer_event
);
1782 BT_LOGE_STR("Failed to set clock value.");
1786 /* Optional field, so it can fail silently. */
1787 field
= bt_event_get_header(event
);
1789 ret
= ctf_copy_event_header(err
, event
, writer_event_class
,
1790 writer_event
, field
);
1792 BT_LOGE_STR("Failed to copy event header.");
1795 BT_OBJECT_PUT_REF_AND_RESET(field
);
1798 /* Optional field, so it can fail silently. */
1799 field
= bt_event_get_stream_event_context(event
);
1801 ret
= copy_set_debug_info_stream_event_context(err
,
1802 field
, event
, writer_event
, debug_info
,
1805 BT_LOGE_STR("Failed to debug_info stream event context.");
1808 BT_OBJECT_PUT_REF_AND_RESET(field
);
1811 /* Optional field, so it can fail silently. */
1812 field
= bt_event_get_event_context(event
);
1814 copy_field
= bt_field_copy(field
);
1816 BT_LOGE_STR("Failed to copy field.");
1819 ret
= bt_event_set_event_context(writer_event
, copy_field
);
1821 BT_LOGE_STR("Failed to set event_context.");
1824 BT_OBJECT_PUT_REF_AND_RESET(copy_field
);
1825 BT_OBJECT_PUT_REF_AND_RESET(field
);
1828 field
= bt_event_get_event_payload(event
);
1831 copy_field
= bt_field_copy(field
);
1833 ret
= bt_event_set_event_payload(writer_event
, copy_field
);
1835 BT_LOGE_STR("Failed to set event payload.");
1838 BT_OBJECT_PUT_REF_AND_RESET(copy_field
);
1840 BT_OBJECT_PUT_REF_AND_RESET(field
);
1845 BT_OBJECT_PUT_REF_AND_RESET(writer_event
);
1847 bt_object_put_ref(copy_field
);
1848 bt_object_put_ref(field
);
1849 return writer_event
;
1853 const bt_event
*debug_info_output_event(
1854 struct debug_info_iterator
*debug_it
,
1855 const bt_event
*event
)
1857 const bt_event_class
*event_class
= NULL
, *writer_event_class
= NULL
;
1858 const bt_stream_class
*stream_class
= NULL
, *writer_stream_class
= NULL
;
1859 const bt_event
*writer_event
= NULL
;
1860 const bt_packet
*packet
= NULL
, *writer_packet
= NULL
;
1861 const bt_trace
*writer_trace
= NULL
;
1862 const bt_stream
*stream
= NULL
;
1863 struct debug_info_trace
*di_trace
;
1864 struct debug_info
*debug_info
;
1867 event_class
= bt_event_get_class(event
);
1868 BT_ASSERT(event_class
);
1870 stream_class
= bt_event_class_get_stream_class(event_class
);
1871 BT_ASSERT(stream_class
);
1873 stream
= bt_event_get_stream(event
);
1876 di_trace
= lookup_di_trace_from_stream(debug_it
, stream
);
1878 BT_LOGE_STR("Failed to find existing trace from stream.");
1882 writer_stream_class
= g_hash_table_lookup(
1883 di_trace
->stream_class_map
,
1884 (gpointer
) stream_class
);
1885 if (!writer_stream_class
) {
1886 BT_LOGE_STR("Failed to find existing stream_class.");
1889 bt_stream_class_get_ref(writer_stream_class
);
1890 writer_trace
= bt_stream_class_get_trace(writer_stream_class
);
1891 BT_ASSERT(writer_trace
);
1892 writer_event_class
= get_event_class(debug_it
,
1893 writer_stream_class
, event_class
);
1894 if (!writer_event_class
) {
1895 writer_event_class
= ctf_copy_event_class(debug_it
->err
,
1896 writer_trace
, event_class
);
1897 if (!writer_event_class
) {
1898 BT_LOGE_STR("Failed to copy event_class.");
1901 int_ret
= bt_stream_class_add_event_class(
1902 writer_stream_class
, writer_event_class
);
1904 BT_LOGE_STR("Failed to add event_class.");
1909 debug_info
= get_trace_debug_info(debug_it
, writer_trace
, di_trace
);
1911 debug_info_handle_event(debug_it
->err
, event
, debug_info
);
1914 writer_event
= debug_info_copy_event(debug_it
->err
, event
,
1915 writer_event_class
, debug_info
,
1916 debug_it
->debug_info_component
);
1917 if (!writer_event
) {
1918 BT_LOGE("Failed to copy event: event-class-name=\"%s\"",
1919 bt_event_class_get_name(writer_event_class
));
1923 packet
= bt_event_get_packet(event
);
1926 writer_packet
= lookup_packet(debug_it
, packet
, di_trace
);
1927 if (!writer_packet
) {
1928 BT_LOGE_STR("Failed to find existing packet.");
1931 bt_packet_get_ref(writer_packet
);
1933 int_ret
= bt_event_set_packet(writer_event
, writer_packet
);
1935 BT_LOGE("Failed to append event to event-class-name=\"%s\"",
1936 bt_event_class_get_name(writer_event_class
));
1940 /* Keep the reference on the writer event */
1944 BT_OBJECT_PUT_REF_AND_RESET(writer_event
);
1947 bt_stream_put_ref(stream
);
1948 bt_trace_put_ref(writer_trace
);
1949 bt_packet_put_ref(writer_packet
);
1950 bt_packet_put_ref(packet
);
1951 bt_event_class_put_ref(writer_event_class
);
1952 bt_stream_class_put_ref(writer_stream_class
);
1953 bt_stream_class_put_ref(stream_class
);
1954 bt_event_class_put_ref(event_class
);
1955 return writer_event
;