Copy the packet_header in the plugins
[babeltrace.git] / plugins / lttng-utils / copy.c
CommitLineData
4f45f9bb
JD
1/*
2 * copy.c
3 *
4 * Babeltrace Copy Trace Structure
5 *
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
7 *
8 * Author: Julien Desfossez <jdesfossez@efficios.com>
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
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
26 * SOFTWARE.
27 */
28
29#include <inttypes.h>
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>
39
40#include <ctfcopytrace.h>
41#include "debug-info.h"
42
cb0a5cf8
JD
43static
44struct 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);
48
504db471
JD
49static
50void unref_stream(struct bt_ctf_stream *stream)
51{
52 bt_put(stream);
53}
54
55static
56void unref_packet(struct bt_ctf_packet *packet)
57{
58 bt_put(packet);
59}
60
61static
62void unref_stream_class(struct bt_ctf_stream_class *stream_class)
63{
64 bt_put(stream_class);
65}
66
67static
68void unref_debug_info(struct debug_info *debug_info)
69{
70 debug_info_destroy(debug_info);
71}
72
1c78e839
JD
73static
74void destroy_stream_state_key(gpointer key)
75{
76 g_free((enum fs_writer_stream_state *) key);
77}
78
4f45f9bb
JD
79static
80struct bt_ctf_field *get_payload_field(FILE *err,
81 struct bt_ctf_event *event, const char *field_name)
82{
83 struct bt_ctf_field *field = NULL, *sec = NULL;
84 struct bt_ctf_field_type *sec_type = NULL;
85
86 sec = bt_ctf_event_get_payload(event, NULL);
87 if (!sec) {
88 fprintf(err, "[error] %s in %s:%d\n", __func__,
89 __FILE__, __LINE__);
90 goto end;
91 }
92
93 sec_type = bt_ctf_field_get_type(sec);
94 if (!sec_type) {
95 fprintf(err, "[error] %s in %s:%d\n", __func__,
96 __FILE__, __LINE__);
97 goto end;
98 }
99
1487a16a 100 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
101 fprintf(err, "[error] %s in %s:%d\n", __func__,
102 __FILE__, __LINE__);
103 goto end;
104 }
105
106 field = bt_ctf_field_structure_get_field(sec, field_name);
107
108end:
109 bt_put(sec_type);
110 bt_put(sec);
111 return field;
112}
113
114static
115struct bt_ctf_field *get_stream_event_context_field(FILE *err,
116 struct bt_ctf_event *event, const char *field_name)
117{
118 struct bt_ctf_field *field = NULL, *sec = NULL;
119 struct bt_ctf_field_type *sec_type = NULL;
120
121 sec = bt_ctf_event_get_stream_event_context(event);
122 if (!sec) {
4f45f9bb
JD
123 goto end;
124 }
125
126 sec_type = bt_ctf_field_get_type(sec);
127 if (!sec_type) {
128 fprintf(err, "[error] %s in %s:%d\n", __func__,
129 __FILE__, __LINE__);
130 goto end;
131 }
132
1487a16a 133 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
134 fprintf(err, "[error] %s in %s:%d\n", __func__,
135 __FILE__, __LINE__);
136 goto end;
137 }
138
139 field = bt_ctf_field_structure_get_field(sec, field_name);
140
141end:
142 bt_put(sec_type);
143 bt_put(sec);
144 return field;
145}
146
147BT_HIDDEN
148int get_stream_event_context_unsigned_int_field_value(FILE *err,
149 struct bt_ctf_event *event, const char *field_name,
150 uint64_t *value)
151{
152 int ret;
153 struct bt_ctf_field *field = NULL;
154 struct bt_ctf_field_type *field_type = NULL;
155
156 field = get_stream_event_context_field(err, event, field_name);
157 if (!field) {
4f45f9bb
JD
158 goto error;
159 }
160
161 field_type = bt_ctf_field_get_type(field);
162 if (!field_type) {
163 fprintf(err, "[error] %s in %s:%d\n", __func__,
164 __FILE__, __LINE__);
165 goto error;
166 }
167
1487a16a 168 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
169 fprintf(err, "[error] %s in %s:%d\n", __func__,
170 __FILE__, __LINE__);
171 goto error;
172 }
173
174 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
175 fprintf(err, "[error] %s in %s:%d\n", __func__,
176 __FILE__, __LINE__);
177 goto error;
178 }
179
180 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
181 goto end;
182
183error:
184 ret = -1;
185end:
186 bt_put(field_type);
187 bt_put(field);
188 return ret;
189}
190
191BT_HIDDEN
192int get_stream_event_context_int_field_value(FILE *err, struct bt_ctf_event *event,
193 const char *field_name, int64_t *value)
194{
195 struct bt_ctf_field *field = NULL;
196 struct bt_ctf_field_type *field_type = NULL;
197 int ret;
198
199 field = get_stream_event_context_field(err, event, field_name);
200 if (!field) {
201 goto error;
202 }
203
204 field_type = bt_ctf_field_get_type(field);
205 if (!field_type) {
206 fprintf(err, "[error] %s in %s:%d\n", __func__,
207 __FILE__, __LINE__);
208 goto error;
209 }
210
1487a16a 211 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
212 fprintf(err, "[error] %s in %s:%d\n", __func__,
213 __FILE__, __LINE__);
214 goto error;
215 }
216
217 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
218 fprintf(err, "[error] %s in %s:%d\n", __func__,
219 __FILE__, __LINE__);
220 goto error;
221 }
222
223 ret = bt_ctf_field_signed_integer_get_value(field, value);
224 goto end;
225
226error:
227 ret = -1;
228end:
229 bt_put(field_type);
230 bt_put(field);
231 return ret;
232}
233
234BT_HIDDEN
235int get_payload_unsigned_int_field_value(FILE *err,
236 struct bt_ctf_event *event, const char *field_name,
237 uint64_t *value)
238{
239 struct bt_ctf_field *field = NULL;
240 struct bt_ctf_field_type *field_type = NULL;
241 int ret;
242
243 field = get_payload_field(err, event, field_name);
244 if (!field) {
245 fprintf(err, "[error] %s in %s:%d\n", __func__,
246 __FILE__, __LINE__);
247 goto error;
248 }
249
250 field_type = bt_ctf_field_get_type(field);
251 if (!field_type) {
252 fprintf(err, "[error] %s in %s:%d\n", __func__,
253 __FILE__, __LINE__);
254 goto error;
255 }
256
1487a16a 257 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
258 fprintf(err, "[error] %s in %s:%d\n", __func__,
259 __FILE__, __LINE__);
260 goto error;
261 }
262
263 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
264 fprintf(err, "[error] %s in %s:%d\n", __func__,
265 __FILE__, __LINE__);
266 goto error;
267 }
268
269 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
270 goto end;
271
272error:
273 ret = -1;
274end:
275 bt_put(field_type);
276 bt_put(field);
277 return ret;
278}
279
280BT_HIDDEN
281int get_payload_int_field_value(FILE *err, struct bt_ctf_event *event,
282 const char *field_name, int64_t *value)
283{
284 struct bt_ctf_field *field = NULL;
285 struct bt_ctf_field_type *field_type = NULL;
286 int ret;
287
288 field = get_payload_field(err, event, field_name);
289 if (!field) {
290 fprintf(err, "[error] %s in %s:%d\n", __func__,
291 __FILE__, __LINE__);
292 goto error;
293 }
294
295 field_type = bt_ctf_field_get_type(field);
296 if (!field_type) {
297 fprintf(err, "[error] %s in %s:%d\n", __func__,
298 __FILE__, __LINE__);
299 goto error;
300 }
301
1487a16a 302 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
303 fprintf(err, "[error] %s in %s:%d\n", __func__,
304 __FILE__, __LINE__);
305 goto error;
306 }
307
308 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
309 fprintf(err, "[error] %s in %s:%d\n", __func__,
310 __FILE__, __LINE__);
311 goto error;
312 }
313
314 ret = bt_ctf_field_signed_integer_get_value(field, value);
315 goto end;
316
317error:
318 ret = -1;
319end:
320 bt_put(field_type);
321 bt_put(field);
322 return ret;
323}
324
325BT_HIDDEN
326int get_payload_string_field_value(FILE *err,
327 struct bt_ctf_event *event, const char *field_name,
328 const char **value)
329{
330 struct bt_ctf_field *field = NULL;
331 struct bt_ctf_field_type *field_type = NULL;
332 int ret;
333
65db8b88
JD
334 /*
335 * The field might not exist, no error here.
336 */
4f45f9bb
JD
337 field = get_payload_field(err, event, field_name);
338 if (!field) {
4f45f9bb
JD
339 goto error;
340 }
341
342 field_type = bt_ctf_field_get_type(field);
343 if (!field_type) {
344 fprintf(err, "[error] %s in %s:%d\n", __func__,
345 __FILE__, __LINE__);
346 goto error;
347 }
348
1487a16a 349 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) {
4f45f9bb
JD
350 fprintf(err, "[error] %s in %s:%d\n", __func__,
351 __FILE__, __LINE__);
352 goto error;
353 }
354
355 *value = bt_ctf_field_string_get_value(field);
356 if (!*value) {
357 fprintf(err, "[error] %s in %s:%d\n", __func__,
358 __FILE__, __LINE__);
359 goto error;
360 }
361
362 ret = 0;
363 goto end;
364
365error:
366 ret = -1;
367end:
368 bt_put(field_type);
369 bt_put(field);
370 return ret;
371}
372
373BT_HIDDEN
374int 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)
377{
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;
381 uint64_t i;
382 int ret;
383
384 *build_id = NULL;
385
386 field = get_payload_field(err, event, field_name);
387 if (!field) {
388 fprintf(err, "[error] %s in %s:%d\n", __func__,
389 __FILE__, __LINE__);
390 goto error;
391 }
392
393 field_type = bt_ctf_field_get_type(field);
394 if (!field_type) {
395 fprintf(err, "[error] %s in %s:%d\n", __func__,
396 __FILE__, __LINE__);
397 goto error;
398 }
399
1487a16a 400 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
4f45f9bb
JD
401 fprintf(err, "[error] %s in %s:%d\n", __func__,
402 __FILE__, __LINE__);
403 goto error;
404 }
405 BT_PUT(field_type);
406
407 seq_len = bt_ctf_field_sequence_get_length(field);
408 if (!seq_len) {
409 fprintf(err, "[error] %s in %s:%d\n", __func__,
410 __FILE__, __LINE__);
411 goto error;
412 }
413
414 ret = bt_ctf_field_unsigned_integer_get_value(seq_len, build_id_len);
415 if (ret) {
416 fprintf(err, "[error] %s in %s:%d\n", __func__,
417 __FILE__, __LINE__);
418 goto error;
419 }
420 BT_PUT(seq_len);
421
422 *build_id = g_new0(uint8_t, *build_id_len);
423 if (!*build_id) {
424 fprintf(err, "[error] %s in %s:%d\n", __func__,
425 __FILE__, __LINE__);
426 goto error;
427 }
428
429 for (i = 0; i < *build_id_len; i++) {
430 uint64_t tmp;
431
432 seq_field = bt_ctf_field_sequence_get_field(field, i);
433 if (!seq_field) {
434 fprintf(err, "[error] %s in %s:%d\n", __func__,
435 __FILE__, __LINE__);
436 goto error;
437 }
438
439 ret = bt_ctf_field_unsigned_integer_get_value(seq_field, &tmp);
440 if (ret) {
441 fprintf(err, "[error] %s in %s:%d\n", __func__,
442 __FILE__, __LINE__);
443 goto error;
444 }
445 BT_PUT(seq_field);
446 (*build_id)[i] = (uint8_t) tmp;
447 }
448 ret = 0;
449 goto end;
450
451error:
452 g_free(*build_id);
453 ret = -1;
454end:
455 bt_put(field_type);
456 bt_put(field);
457 return ret;
458}
459
460static
461struct debug_info *lookup_trace_debug_info(struct debug_info_iterator *debug_it,
504db471
JD
462 struct bt_ctf_trace *writer_trace,
463 struct debug_info_trace *di_trace)
4f45f9bb
JD
464{
465 return (struct debug_info *) g_hash_table_lookup(
504db471 466 di_trace->trace_debug_map,
4f45f9bb
JD
467 (gpointer) writer_trace);
468}
469
470static
471struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it,
504db471
JD
472 struct bt_ctf_trace *writer_trace,
473 struct debug_info_trace *di_trace)
4f45f9bb
JD
474{
475 struct debug_info *debug_info = NULL;
476 struct bt_value *field = NULL;
477 const char *str_value;
478 enum bt_value_status ret;
479
480 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
481 "domain");
482 /* No domain field, no debug info */
483 if (!field) {
484 goto end;
485 }
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__,
489 __FILE__, __LINE__);
490 goto end;
491 }
492 /* Domain not ust, no debug info */
493 if (strcmp(str_value, "ust") != 0) {
494 goto end;
495 }
496 BT_PUT(field);
497
498 /* No tracer_name, no debug info */
499 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
500 "tracer_name");
501 /* No tracer_name, no debug info */
502 if (!field) {
503 goto end;
504 }
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__,
508 __FILE__, __LINE__);
509 goto end;
510 }
511 /* Tracer_name not lttng-ust, no debug info */
512 if (strcmp(str_value, "lttng-ust") != 0) {
513 goto end;
514 }
515 BT_PUT(field);
516
9d325e17 517 debug_info = debug_info_create(debug_it->debug_info_component);
4f45f9bb
JD
518 if (!debug_info) {
519 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
520 __FILE__, __LINE__);
521 goto end;
522 }
523
504db471 524 g_hash_table_insert(di_trace->trace_debug_map, (gpointer) writer_trace,
4f45f9bb
JD
525 debug_info);
526
527end:
528 bt_put(field);
529 return debug_info;
530}
531
532static
533struct debug_info *get_trace_debug_info(struct debug_info_iterator *debug_it,
504db471
JD
534 struct bt_ctf_trace *writer_trace,
535 struct debug_info_trace *di_trace)
4f45f9bb
JD
536{
537 struct debug_info *debug_info;
538
504db471 539 debug_info = lookup_trace_debug_info(debug_it, writer_trace, di_trace);
4f45f9bb
JD
540 if (debug_info) {
541 goto end;
542 }
543
504db471 544 debug_info = insert_new_debug_info(debug_it, writer_trace, di_trace);
4f45f9bb
JD
545
546end:
547 return debug_info;
548}
549
550static
504db471 551struct debug_info_trace *lookup_trace(struct debug_info_iterator *debug_it,
4f45f9bb
JD
552 struct bt_ctf_trace *trace)
553{
504db471 554 return (struct debug_info_trace *) g_hash_table_lookup(
4f45f9bb
JD
555 debug_it->trace_map,
556 (gpointer) trace);
557}
558
1c78e839
JD
559static
560enum 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)
563{
564 enum debug_info_stream_state *v = NULL;
565
566 v = g_new0(enum debug_info_stream_state, 1);
567 if (!v) {
568 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
569 __FILE__, __LINE__);
ec273a88 570 goto end;
1c78e839
JD
571 }
572 *v = DEBUG_INFO_UNKNOWN_STREAM;
573
574 g_hash_table_insert(di_trace->stream_states, stream, v);
575
ec273a88 576end:
1c78e839
JD
577 return v;
578}
579
580static
581void check_completed_trace(gpointer key, gpointer value, gpointer user_data)
582{
583 enum debug_info_stream_state *state = value;
584 int *trace_completed = user_data;
585
586 if (*state != DEBUG_INFO_COMPLETED_STREAM) {
587 *trace_completed = 0;
588 }
589}
590
591static
592gboolean empty_ht(gpointer key, gpointer value, gpointer user_data)
593{
594 return TRUE;
595}
596
597BT_HIDDEN
598void debug_info_close_trace(struct debug_info_iterator *debug_it,
599 struct debug_info_trace *di_trace)
600{
ec273a88 601 if (di_trace->static_listener_id >= 0) {
1c78e839
JD
602 bt_ctf_trace_remove_is_static_listener(di_trace->trace,
603 di_trace->static_listener_id);
604 }
605
606 /* Empty the stream class HT. */
607 g_hash_table_foreach_remove(di_trace->stream_class_map,
608 empty_ht, NULL);
609 g_hash_table_destroy(di_trace->stream_class_map);
610
611 /* Empty the stream HT. */
612 g_hash_table_foreach_remove(di_trace->stream_map,
613 empty_ht, NULL);
614 g_hash_table_destroy(di_trace->stream_map);
615
616 /* Empty the stream state HT. */
617 g_hash_table_foreach_remove(di_trace->stream_states,
618 empty_ht, NULL);
619 g_hash_table_destroy(di_trace->stream_states);
620
621 /* Empty the packet HT. */
622 g_hash_table_foreach_remove(di_trace->packet_map,
623 empty_ht, NULL);
624 g_hash_table_destroy(di_trace->packet_map);
625
626 /* Empty the trace_debug HT. */
627 g_hash_table_foreach_remove(di_trace->trace_debug_map,
628 empty_ht, NULL);
629 g_hash_table_destroy(di_trace->trace_debug_map);
630}
631
cb0a5cf8
JD
632static
633int sync_event_classes(struct debug_info_iterator *debug_it,
634 struct bt_ctf_stream *stream,
635 struct bt_ctf_stream *writer_stream)
636{
637 int int_ret;
638 struct bt_ctf_stream_class *stream_class = NULL,
639 *writer_stream_class = NULL;
640 enum bt_component_status ret;
641
642 stream_class = bt_ctf_stream_get_class(stream);
643 if (!stream_class) {
644 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
645 __FILE__, __LINE__);
646 goto error;
647 }
648
649 writer_stream_class = bt_ctf_stream_get_class(writer_stream);
650 if (!writer_stream_class) {
651 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
652 __FILE__, __LINE__);
653 goto error;
654 }
655
656 ret = ctf_copy_event_classes(debug_it->err, stream_class,
657 writer_stream_class);
658 if (ret != BT_COMPONENT_STATUS_OK) {
659 goto error;
660 }
661
662 int_ret = 0;
663 goto end;
664
665error:
666 int_ret = -1;
667end:
668 bt_put(stream_class);
669 bt_put(writer_stream_class);
670 return int_ret;
671}
672
1c78e839
JD
673static
674void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
675{
676 struct debug_info_trace *di_trace = data;
cb0a5cf8
JD
677 struct debug_info_iterator *debug_it = di_trace->debug_it;
678 int trace_completed = 1, ret, nr_stream, i;
679 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
680 struct bt_ctf_trace *writer_trace = di_trace->writer_trace;
681
682 /*
683 * When the trace becomes static, make sure that we have all
684 * the event classes in our stream_class copies before setting it
685 * static as well.
686 */
687 nr_stream = bt_ctf_trace_get_stream_count(trace);
688 for (i = 0; i < nr_stream; i++) {
689 stream = bt_ctf_trace_get_stream_by_index(trace, i);
690 if (!stream) {
691 fprintf(debug_it->err,
692 "[error] %s in %s:%d\n", __func__,
693 __FILE__, __LINE__);
694 goto error;
695 }
696 writer_stream = bt_ctf_trace_get_stream_by_index(writer_trace, i);
697 if (!writer_stream) {
698 fprintf(debug_it->err,
699 "[error] %s in %s:%d\n", __func__,
700 __FILE__, __LINE__);
701 goto error;
702 }
703 ret = sync_event_classes(di_trace->debug_it, stream, writer_stream);
704 if (ret) {
705 fprintf(debug_it->err,
706 "[error] %s in %s:%d\n", __func__,
707 __FILE__, __LINE__);
708 goto error;
709 }
710 BT_PUT(stream);
711 BT_PUT(writer_stream);
712 }
1c78e839 713
cb0a5cf8 714 bt_ctf_trace_set_is_static(di_trace->writer_trace);
1c78e839
JD
715 di_trace->trace_static = 1;
716
717 g_hash_table_foreach(di_trace->stream_states,
718 check_completed_trace, &trace_completed);
719 if (trace_completed) {
720 debug_info_close_trace(di_trace->debug_it, di_trace);
721 g_hash_table_remove(di_trace->debug_it->trace_map,
722 di_trace->trace);
723 }
cb0a5cf8
JD
724
725error:
726 bt_put(writer_stream);
727 bt_put(stream);
1c78e839
JD
728}
729
4f45f9bb 730static
504db471
JD
731struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
732 struct bt_ctf_stream *stream) {
4f45f9bb 733 struct bt_ctf_trace *writer_trace = NULL;
504db471
JD
734 struct debug_info_trace *di_trace = NULL;
735 struct bt_ctf_trace *trace = NULL;
736 struct bt_ctf_stream_class *stream_class = NULL;
cb0a5cf8 737 struct bt_ctf_stream *writer_stream = NULL;
1c78e839 738 int ret, nr_stream, i;
4f45f9bb
JD
739
740 writer_trace = bt_ctf_trace_create();
741 if (!writer_trace) {
742 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
743 __FILE__, __LINE__);
744 goto error;
745 }
504db471
JD
746
747 stream_class = bt_ctf_stream_get_class(stream);
748 if (!stream_class) {
749 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
750 __FILE__, __LINE__);
751 goto error;
752 }
753
754 trace = bt_ctf_stream_class_get_trace(stream_class);
755 if (!trace) {
756 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
757 __FILE__, __LINE__);
758 goto error;
759 }
4f45f9bb
JD
760
761 ret = ctf_copy_trace(debug_it->err, trace, writer_trace);
762 if (ret != BT_COMPONENT_STATUS_OK) {
763 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
764 __FILE__, __LINE__);
765 goto error;
766 }
767
504db471
JD
768 di_trace = g_new0(struct debug_info_trace, 1);
769 if (!di_trace) {
770 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
771 __FILE__, __LINE__);
772 goto error;
773 }
774
775 di_trace->trace = trace;
776 di_trace->writer_trace = writer_trace;
777 di_trace->debug_info_component = debug_it->debug_info_component;
1c78e839 778 di_trace->debug_it = debug_it;
504db471
JD
779 di_trace->stream_map = g_hash_table_new_full(g_direct_hash,
780 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
781 di_trace->stream_class_map = g_hash_table_new_full(g_direct_hash,
782 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
783 di_trace->packet_map = g_hash_table_new_full(g_direct_hash,
784 g_direct_equal, NULL, (GDestroyNotify) unref_packet);
785 di_trace->trace_debug_map = g_hash_table_new_full(g_direct_hash,
786 g_direct_equal, NULL, (GDestroyNotify) unref_debug_info);
1c78e839
JD
787 di_trace->stream_states = g_hash_table_new_full(g_direct_hash,
788 g_direct_equal, NULL, destroy_stream_state_key);
cb0a5cf8 789 g_hash_table_insert(debug_it->trace_map, (gpointer) trace, di_trace);
1c78e839
JD
790
791 /* Set all the existing streams in the unknown state. */
792 nr_stream = bt_ctf_trace_get_stream_count(trace);
793 for (i = 0; i < nr_stream; i++) {
794 stream = bt_ctf_trace_get_stream_by_index(trace, i);
795 if (!stream) {
796 fprintf(debug_it->err,
797 "[error] %s in %s:%d\n", __func__,
798 __FILE__, __LINE__);
799 goto error;
800 }
801 insert_new_stream_state(debug_it, di_trace, stream);
cb0a5cf8
JD
802 writer_stream = insert_new_stream(debug_it, stream, di_trace);
803 if (!writer_stream) {
804 fprintf(debug_it->err,
805 "[error] %s in %s:%d\n", __func__,
806 __FILE__, __LINE__);
807 goto error;
808 }
809 bt_get(writer_stream);
810 ret = sync_event_classes(debug_it, stream, writer_stream);
811 if (ret) {
812 fprintf(debug_it->err,
813 "[error] %s in %s:%d\n", __func__,
814 __FILE__, __LINE__);
815 goto error;
816 }
817 BT_PUT(writer_stream);
1c78e839
JD
818 BT_PUT(stream);
819 }
820
821 /* Check if the trace is already static or register a listener. */
822 if (bt_ctf_trace_is_static(trace)) {
823 di_trace->trace_static = 1;
824 di_trace->static_listener_id = -1;
cb0a5cf8 825 bt_ctf_trace_set_is_static(writer_trace);
1c78e839
JD
826 } else {
827 ret = bt_ctf_trace_add_is_static_listener(trace,
828 trace_is_static_listener, di_trace);
829 if (ret < 0) {
830 fprintf(debug_it->err,
831 "[error] %s in %s:%d\n", __func__, __FILE__,
832 __LINE__);
833 goto error;
834 }
835 di_trace->static_listener_id = ret;
836 }
504db471 837
504db471 838
4f45f9bb
JD
839 goto end;
840
841error:
842 BT_PUT(writer_trace);
504db471
JD
843 g_free(di_trace);
844 di_trace = NULL;
4f45f9bb 845end:
cb0a5cf8
JD
846 bt_put(stream);
847 bt_put(writer_stream);
504db471
JD
848 bt_put(stream_class);
849 bt_put(trace);
850 return di_trace;
4f45f9bb
JD
851}
852
853static
854struct bt_ctf_packet *lookup_packet(struct debug_info_iterator *debug_it,
504db471
JD
855 struct bt_ctf_packet *packet,
856 struct debug_info_trace *di_trace)
4f45f9bb
JD
857{
858 return (struct bt_ctf_packet *) g_hash_table_lookup(
504db471 859 di_trace->packet_map,
4f45f9bb
JD
860 (gpointer) packet);
861}
862
863static
864struct bt_ctf_packet *insert_new_packet(struct debug_info_iterator *debug_it,
865 struct bt_ctf_packet *packet,
504db471
JD
866 struct bt_ctf_stream *writer_stream,
867 struct debug_info_trace *di_trace)
4f45f9bb
JD
868{
869 struct bt_ctf_packet *writer_packet;
387483fc 870 int ret;
4f45f9bb
JD
871
872 writer_packet = bt_ctf_packet_create(writer_stream);
873 if (!writer_packet) {
874 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
875 __FILE__, __LINE__);
387483fc
JD
876 goto error;
877 }
878
879 ret = ctf_packet_copy_header(debug_it->err, packet, writer_packet);
880 if (ret) {
881 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
882 __FILE__, __LINE__);
883 goto error;
4f45f9bb 884 }
4f45f9bb 885
387483fc
JD
886 g_hash_table_insert(di_trace->packet_map, (gpointer) packet,
887 writer_packet);
888 goto end;
889
890error:
891 BT_PUT(writer_packet);
4f45f9bb
JD
892end:
893 return writer_packet;
894}
895
896static
897int add_debug_info_fields(FILE *err,
898 struct bt_ctf_field_type *writer_event_context_type,
899 struct debug_info_component *component)
900{
901 struct bt_ctf_field_type *ip_field = NULL, *debug_field_type = NULL,
902 *bin_field_type = NULL, *func_field_type = NULL,
903 *src_field_type = NULL;
904 int ret = 0;
905
906 ip_field = bt_ctf_field_type_structure_get_field_type_by_name(
907 writer_event_context_type, "_ip");
908 /* No ip field, so no debug info. */
909 if (!ip_field) {
910 goto end;
911 }
912 BT_PUT(ip_field);
913
914 debug_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
915 writer_event_context_type,
916 component->arg_debug_info_field_name);
917 /* Already existing debug_info field, no need to add it. */
918 if (debug_field_type) {
919 goto end;
920 }
921
922 debug_field_type = bt_ctf_field_type_structure_create();
923 if (!debug_field_type) {
924 fprintf(err, "[error] %s in %s:%d\n", __func__,
925 __FILE__, __LINE__);
926 goto error;
927 }
928
929 bin_field_type = bt_ctf_field_type_string_create();
930 if (!bin_field_type) {
931 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
932 __LINE__);
933 goto error;
934 }
935
936 func_field_type = bt_ctf_field_type_string_create();
937 if (!func_field_type) {
938 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
939 __LINE__);
940 goto error;
941 }
942
943 src_field_type = bt_ctf_field_type_string_create();
944 if (!src_field_type) {
945 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
946 __LINE__);
947 goto error;
948 }
949
950 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
951 bin_field_type, "bin");
952 if (ret) {
953 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
954 __LINE__);
955 goto error;
956 }
957
958 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
959 func_field_type, "func");
960 if (ret) {
961 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
962 __LINE__);
963 goto error;
964 }
965
966 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
967 src_field_type, "src");
968 if (ret) {
969 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
970 __LINE__);
971 goto error;
972 }
973
974 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
975 debug_field_type, component->arg_debug_info_field_name);
976 if (ret) {
977 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
978 __LINE__);
979 goto error;
980 }
981
982 ret = 0;
983 goto end;
984
985error:
986 BT_PUT(debug_field_type);
987 ret = -1;
988end:
989 bt_put(src_field_type);
990 bt_put(func_field_type);
991 bt_put(bin_field_type);
992 bt_put(debug_field_type);
993 return ret;
994}
995
996static
997int create_debug_info_event_context_type(FILE *err,
998 struct bt_ctf_field_type *event_context_type,
999 struct bt_ctf_field_type *writer_event_context_type,
1000 struct debug_info_component *component)
1001{
1002 int ret, nr_fields, i;
1003
1004 nr_fields = bt_ctf_field_type_structure_get_field_count(event_context_type);
1005 for (i = 0; i < nr_fields; i++) {
1006 struct bt_ctf_field_type *field_type = NULL;
1007 const char *field_name;
1008
1009 if (bt_ctf_field_type_structure_get_field(event_context_type,
1010 &field_name, &field_type, i) < 0) {
1011 fprintf(err, "[error] %s in %s:%d\n", __func__,
1012 __FILE__, __LINE__);
1013 goto error;
1014 }
1015
1016 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
1017 field_type, field_name);
1018 BT_PUT(field_type);
1019 if (ret) {
1020 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1021 __LINE__);
1022 goto error;
1023 }
1024 }
1025
1026 ret = add_debug_info_fields(err, writer_event_context_type,
1027 component);
1028 goto end;
1029
1030error:
1031 ret = -1;
1032end:
1033 return ret;
1034}
1035
1036static
1037struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err,
1038 struct bt_ctf_stream_class *stream_class,
1039 struct bt_ctf_trace *writer_trace,
1040 struct debug_info_component *component)
1041{
1042 struct bt_ctf_field_type *type = NULL;
1043 struct bt_ctf_stream_class *writer_stream_class = NULL;
1044 struct bt_ctf_field_type *writer_event_context_type = NULL;
1045 int ret_int;
1046 const char *name = bt_ctf_stream_class_get_name(stream_class);
1047
1048 if (strlen(name) == 0) {
1049 name = NULL;
1050 }
1051
2d64a1eb 1052 writer_stream_class = bt_ctf_stream_class_create_empty(name);
4f45f9bb
JD
1053 if (!writer_stream_class) {
1054 fprintf(err, "[error] %s in %s:%d\n",
1055 __func__, __FILE__, __LINE__);
1056 goto error;
1057 }
1058
1059 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
2d64a1eb
JD
1060 if (type) {
1061 ret_int = bt_ctf_stream_class_set_packet_context_type(
1062 writer_stream_class, type);
1063 if (ret_int < 0) {
1064 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1065 __LINE__);
1066 goto error;
1067 }
1068 BT_PUT(type);
4f45f9bb 1069 }
4f45f9bb
JD
1070
1071 type = bt_ctf_stream_class_get_event_header_type(stream_class);
290b95cc
MD
1072 if (type) {
1073 ret_int = bt_ctf_stream_class_set_event_header_type(
1074 writer_stream_class, type);
1075 if (ret_int < 0) {
1076 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1077 __LINE__);
1078 goto error;
1079 }
1080 BT_PUT(type);
4f45f9bb 1081 }
4f45f9bb
JD
1082
1083 type = bt_ctf_stream_class_get_event_context_type(stream_class);
1084 if (type) {
1085 writer_event_context_type = bt_ctf_field_type_structure_create();
1086 if (!writer_event_context_type) {
1087 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1088 __LINE__);
1089 goto error;
1090 }
1091 ret_int = create_debug_info_event_context_type(err, type,
1092 writer_event_context_type, component);
1093 if (ret_int) {
1094 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1095 __LINE__);
1096 goto error;
1097 }
1098 BT_PUT(type);
1099
1100 ret_int = bt_ctf_stream_class_set_event_context_type(
1101 writer_stream_class, writer_event_context_type);
1102 if (ret_int < 0) {
1103 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1104 __LINE__);
1105 goto error;
1106 }
1107 BT_PUT(writer_event_context_type);
1108 }
1109
1110 goto end;
1111
1112error:
1113 BT_PUT(writer_stream_class);
1114end:
1115 bt_put(writer_event_context_type);
1116 bt_put(type);
1117 return writer_stream_class;
1118}
1119
1120/*
1121 * Add the original clock classes to the new trace, we do not need to copy
1122 * them, and if we did, we would have to manually inspect the stream class
1123 * to update the integers mapping to a clock.
1124 */
1125static
1126int add_clock_classes(FILE *err, struct bt_ctf_trace *writer_trace,
1127 struct bt_ctf_stream_class *writer_stream_class,
1128 struct bt_ctf_trace *trace)
1129{
1130 int ret, clock_class_count, i;
1131
1132 clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
1133
1134 for (i = 0; i < clock_class_count; i++) {
1135 struct bt_ctf_clock_class *clock_class =
9ac68eb1 1136 bt_ctf_trace_get_clock_class_by_index(trace, i);
4f45f9bb
JD
1137
1138 if (!clock_class) {
1139 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1140 __LINE__);
1141 goto error;
1142 }
1143
1144 ret = bt_ctf_trace_add_clock_class(writer_trace, clock_class);
1145 BT_PUT(clock_class);
1146 if (ret != 0) {
1147 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1148 __LINE__);
1149 goto error;
1150 }
1151 }
1152
1153 ret = 0;
1154 goto end;
1155
1156error:
1157 ret = -1;
1158end:
1159 return ret;
1160
1161}
1162
1163static
1164struct bt_ctf_stream_class *insert_new_stream_class(
1165 struct debug_info_iterator *debug_it,
1166 struct bt_ctf_stream_class *stream_class)
1167{
1168 struct bt_ctf_stream_class *writer_stream_class = NULL;
1169 struct bt_ctf_trace *trace, *writer_trace = NULL;
504db471 1170 struct debug_info_trace *di_trace;
4f45f9bb
JD
1171 enum bt_component_status ret;
1172 int int_ret;
1173
1174 trace = bt_ctf_stream_class_get_trace(stream_class);
1175 if (!trace) {
1176 fprintf(debug_it->err,
1177 "[error] %s in %s:%d\n", __func__, __FILE__,
1178 __LINE__);
1179 goto error;
1180 }
1181
504db471
JD
1182 di_trace = lookup_trace(debug_it, trace);
1183 if (!di_trace) {
1184 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1185 __FILE__, __LINE__);
1186 ret = BT_COMPONENT_STATUS_ERROR;
1187 goto error;
4f45f9bb 1188 }
504db471 1189 writer_trace = di_trace->writer_trace;
4f45f9bb
JD
1190 bt_get(writer_trace);
1191
1192 writer_stream_class = copy_stream_class_debug_info(debug_it->err, stream_class,
1193 writer_trace, debug_it->debug_info_component);
1194 if (!writer_stream_class) {
1195 fprintf(debug_it->err, "[error] Failed to copy stream class\n");
1196 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1197 __func__, __FILE__, __LINE__);
1198 goto error;
1199 }
1200
1201 int_ret = bt_ctf_trace_add_stream_class(writer_trace, writer_stream_class);
1202 if (int_ret) {
1203 fprintf(debug_it->err,
1204 "[error] %s in %s:%d\n", __func__, __FILE__,
1205 __LINE__);
1206 goto error;
1207 }
1208
1209 ret = add_clock_classes(debug_it->err, writer_trace,
1210 writer_stream_class, trace);
1211 if (ret != BT_COMPONENT_STATUS_OK) {
1212 fprintf(debug_it->err,
1213 "[error] %s in %s:%d\n", __func__, __FILE__,
1214 __LINE__);
1215 goto error;
1216 }
4f45f9bb 1217
504db471 1218 g_hash_table_insert(di_trace->stream_class_map,
4f45f9bb
JD
1219 (gpointer) stream_class, writer_stream_class);
1220
1221 goto end;
1222
1223error:
1224 BT_PUT(writer_stream_class);
1225end:
1226 bt_put(trace);
1227 bt_put(writer_trace);
1228 return writer_stream_class;
1229}
1230
1231static
1232struct bt_ctf_stream *insert_new_stream(
1233 struct debug_info_iterator *debug_it,
504db471
JD
1234 struct bt_ctf_stream *stream,
1235 struct debug_info_trace *di_trace)
4f45f9bb
JD
1236{
1237 struct bt_ctf_stream *writer_stream = NULL;
504db471 1238 struct bt_ctf_stream_class *stream_class = NULL;
4f45f9bb
JD
1239 struct bt_ctf_stream_class *writer_stream_class = NULL;
1240
504db471
JD
1241 stream_class = bt_ctf_stream_get_class(stream);
1242 if (!stream_class) {
1243 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1244 __func__, __FILE__, __LINE__);
1245 goto error;
1246 }
1247
4f45f9bb 1248 writer_stream_class = g_hash_table_lookup(
504db471 1249 di_trace->stream_class_map,
4f45f9bb
JD
1250 (gpointer) stream_class);
1251
1252 if (!writer_stream_class) {
1253 writer_stream_class = insert_new_stream_class(debug_it,
1254 stream_class);
1255 if (!writer_stream_class) {
1256 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1257 __func__, __FILE__, __LINE__);
1258 goto error;
1259 }
1260 }
1261 bt_get(writer_stream_class);
1262
1263 writer_stream = bt_ctf_stream_create(writer_stream_class,
1264 bt_ctf_stream_get_name(stream));
1265 if (!writer_stream) {
1266 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1267 __func__, __FILE__, __LINE__);
1268 goto error;
1269 }
1270
504db471 1271 g_hash_table_insert(di_trace->stream_map, (gpointer) stream,
4f45f9bb
JD
1272 writer_stream);
1273
1274 goto end;
1275
1276error:
1277 BT_PUT(writer_stream);
1278end:
504db471 1279 bt_put(stream_class);
4f45f9bb
JD
1280 bt_put(writer_stream_class);
1281 return writer_stream;
1282}
1283
1284static
1285struct bt_ctf_stream *lookup_stream(struct debug_info_iterator *debug_it,
504db471
JD
1286 struct bt_ctf_stream *stream,
1287 struct debug_info_trace *di_trace)
4f45f9bb
JD
1288{
1289 return (struct bt_ctf_stream *) g_hash_table_lookup(
504db471 1290 di_trace->stream_map, (gpointer) stream);
4f45f9bb
JD
1291}
1292
1293static
1294struct bt_ctf_event_class *get_event_class(struct debug_info_iterator *debug_it,
1295 struct bt_ctf_stream_class *writer_stream_class,
1296 struct bt_ctf_event_class *event_class)
1297{
a9f0d01b
PP
1298 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
1299 bt_ctf_event_class_get_id(event_class));
4f45f9bb
JD
1300}
1301
504db471
JD
1302static
1303struct debug_info_trace *lookup_di_trace_from_stream(
1304 struct debug_info_iterator *debug_it,
1305 struct bt_ctf_stream *stream)
1306{
1307 struct bt_ctf_stream_class *stream_class = NULL;
1308 struct bt_ctf_trace *trace = NULL;
1309 struct debug_info_trace *di_trace = NULL;
1310
1311 stream_class = bt_ctf_stream_get_class(stream);
1312 if (!stream_class) {
1313 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1314 __func__, __FILE__, __LINE__);
1315 goto end;
1316 }
1317
1318 trace = bt_ctf_stream_class_get_trace(stream_class);
1319 if (!trace) {
1320 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1321 __func__, __FILE__, __LINE__);
1322 goto end;
1323 }
1324
1325 di_trace = (struct debug_info_trace *) g_hash_table_lookup(
1326 debug_it->trace_map, (gpointer) trace);
1327
1328end:
1329 BT_PUT(stream_class);
1330 BT_PUT(trace);
1331 return di_trace;
1332}
1333
4f45f9bb
JD
1334static
1335struct bt_ctf_stream *get_writer_stream(
1336 struct debug_info_iterator *debug_it,
1337 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
1338{
1339 struct bt_ctf_stream_class *stream_class = NULL;
1340 struct bt_ctf_stream *writer_stream = NULL;
504db471 1341 struct debug_info_trace *di_trace = NULL;
4f45f9bb
JD
1342
1343 stream_class = bt_ctf_stream_get_class(stream);
1344 if (!stream_class) {
1345 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1346 __func__, __FILE__, __LINE__);
1347 goto error;
1348 }
1349
504db471
JD
1350 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1351 if (!di_trace) {
1352 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1353 __func__, __FILE__, __LINE__);
1354 goto error;
1355 }
1356
1357 writer_stream = lookup_stream(debug_it, stream, di_trace);
4f45f9bb 1358 if (!writer_stream) {
504db471
JD
1359 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1360 __func__, __FILE__, __LINE__);
1361 goto error;
4f45f9bb
JD
1362 }
1363 bt_get(writer_stream);
1364
1365 goto end;
1366
1367error:
1368 BT_PUT(writer_stream);
1369end:
1370 bt_put(stream_class);
1371 return writer_stream;
1372}
1373
1374BT_HIDDEN
1375struct bt_ctf_packet *debug_info_new_packet(
1376 struct debug_info_iterator *debug_it,
1377 struct bt_ctf_packet *packet)
1378{
1379 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
4f45f9bb 1380 struct bt_ctf_packet *writer_packet = NULL;
2d64a1eb 1381 struct bt_ctf_field *packet_context = NULL;
504db471 1382 struct debug_info_trace *di_trace;
4f45f9bb
JD
1383 int int_ret;
1384
1385 stream = bt_ctf_packet_get_stream(packet);
1386 if (!stream) {
1387 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1388 __func__, __FILE__, __LINE__);
1389 goto error;
1390 }
1391
1392 writer_stream = get_writer_stream(debug_it, packet, stream);
1393 if (!writer_stream) {
1394 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1395 __func__, __FILE__, __LINE__);
1396 goto error;
1397 }
1398
504db471
JD
1399 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1400 if (!di_trace) {
1401 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1402 __FILE__, __LINE__);
1403 goto error;
1404 }
1405
4f45f9bb
JD
1406 /*
1407 * If a packet was already opened, close it and remove it from
1408 * the HT.
1409 */
504db471 1410 writer_packet = lookup_packet(debug_it, packet, di_trace);
4f45f9bb 1411 if (writer_packet) {
504db471 1412 g_hash_table_remove(di_trace->packet_map, packet);
4f45f9bb
JD
1413 BT_PUT(writer_packet);
1414 }
1415
504db471
JD
1416 writer_packet = insert_new_packet(debug_it, packet, writer_stream,
1417 di_trace);
4f45f9bb
JD
1418 if (!writer_packet) {
1419 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1420 __func__, __FILE__, __LINE__);
1421 goto error;
1422 }
4f45f9bb 1423
2d64a1eb
JD
1424 packet_context = bt_ctf_packet_get_context(packet);
1425 if (packet_context) {
9877e1aa
JD
1426 int_ret = ctf_packet_copy_context(debug_it->err,
1427 packet, writer_stream, writer_packet);
1428 if (int_ret < 0) {
2d64a1eb
JD
1429 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1430 __func__, __FILE__, __LINE__);
1431 goto error;
1432 }
1433 BT_PUT(packet_context);
4f45f9bb
JD
1434 }
1435
1c78e839 1436 bt_get(writer_packet);
4f45f9bb
JD
1437 goto end;
1438
1439error:
1440
1441end:
2d64a1eb 1442 bt_put(packet_context);
4f45f9bb
JD
1443 bt_put(writer_stream);
1444 bt_put(stream);
1445 return writer_packet;
1446}
1447
1448BT_HIDDEN
1449struct bt_ctf_packet *debug_info_close_packet(
1450 struct debug_info_iterator *debug_it,
1451 struct bt_ctf_packet *packet)
1452{
1453 struct bt_ctf_packet *writer_packet = NULL;
504db471
JD
1454 struct bt_ctf_stream *stream = NULL;
1455 struct debug_info_trace *di_trace;
1456
1457 stream = bt_ctf_packet_get_stream(packet);
1458 if (!stream) {
1459 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1460 __FILE__, __LINE__);
1461 goto end;
1462 }
1463
1464 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1465 if (!di_trace) {
1466 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1467 __FILE__, __LINE__);
1468 goto end;
1469 }
4f45f9bb 1470
504db471 1471 writer_packet = lookup_packet(debug_it, packet, di_trace);
4f45f9bb
JD
1472 if (!writer_packet) {
1473 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1474 __func__, __FILE__, __LINE__);
1475 goto end;
1476 }
1c78e839 1477 bt_get(writer_packet);
504db471 1478 g_hash_table_remove(di_trace->packet_map, packet);
4f45f9bb
JD
1479
1480end:
504db471 1481 bt_put(stream);
4f45f9bb
JD
1482 return writer_packet;
1483}
1484
504db471
JD
1485BT_HIDDEN
1486struct bt_ctf_stream *debug_info_stream_begin(
1487 struct debug_info_iterator *debug_it,
1488 struct bt_ctf_stream *stream)
1489{
cb0a5cf8 1490 struct bt_ctf_stream *writer_stream = NULL;
1c78e839 1491 enum debug_info_stream_state *state;
504db471
JD
1492 struct debug_info_trace *di_trace = NULL;
1493
1494 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1495 if (!di_trace) {
1496 di_trace = insert_new_trace(debug_it, stream);
1497 if (!di_trace) {
1498 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1499 __func__, __FILE__, __LINE__);
1c78e839 1500 goto error;
504db471
JD
1501 }
1502 }
1503
1c78e839
JD
1504 /* Set the stream as active */
1505 state = g_hash_table_lookup(di_trace->stream_states, stream);
1506 if (!state) {
1507 if (di_trace->trace_static) {
1508 fprintf(debug_it->err, "[error] Adding a new stream "
1509 "on a static trace\n");
1510 goto error;
1511 }
1512 state = insert_new_stream_state(debug_it, di_trace,
1513 stream);
ec273a88
JD
1514 if (!state) {
1515 fprintf(debug_it->err, "[error] Adding a new stream "
1516 "on a static trace\n");
1517 goto error;
1518 }
1c78e839
JD
1519 }
1520 if (*state != DEBUG_INFO_UNKNOWN_STREAM) {
1521 fprintf(debug_it->err, "[error] Unexpected stream state %d\n",
1522 *state);
1523 goto error;
1524 }
1525 *state = DEBUG_INFO_ACTIVE_STREAM;
1526
cb0a5cf8
JD
1527 writer_stream = lookup_stream(debug_it, stream, di_trace);
1528 if (!writer_stream) {
1529 writer_stream = insert_new_stream(debug_it, stream, di_trace);
1530 }
1c78e839 1531 bt_get(writer_stream);
504db471 1532
1c78e839
JD
1533 goto end;
1534
1535error:
1536 BT_PUT(writer_stream);
504db471
JD
1537end:
1538 return writer_stream;
1539}
1540
4f45f9bb
JD
1541BT_HIDDEN
1542struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it,
1543 struct bt_ctf_stream *stream)
1544{
0bb3da02 1545 struct bt_ctf_stream *writer_stream = NULL;
504db471 1546 struct debug_info_trace *di_trace = NULL;
1c78e839 1547 enum debug_info_stream_state *state;
504db471
JD
1548
1549 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1550 if (!di_trace) {
1551 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1552 __func__, __FILE__, __LINE__);
1c78e839 1553 goto error;
504db471 1554 }
4f45f9bb 1555
504db471 1556 writer_stream = lookup_stream(debug_it, stream, di_trace);
4f45f9bb
JD
1557 if (!writer_stream) {
1558 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1559 __func__, __FILE__, __LINE__);
1c78e839 1560 goto error;
4f45f9bb 1561 }
1c78e839
JD
1562 /*
1563 * Take the ref on the stream and keep it until the notification
1564 * is created.
1565 */
34101229 1566 bt_get(writer_stream);
1c78e839
JD
1567
1568 state = g_hash_table_lookup(di_trace->stream_states, stream);
1569 if (*state != DEBUG_INFO_ACTIVE_STREAM) {
1570 fprintf(debug_it->err, "[error] Unexpected stream "
1571 "state %d\n", *state);
1572 goto error;
1573 }
1574 *state = DEBUG_INFO_COMPLETED_STREAM;
1575
504db471 1576 g_hash_table_remove(di_trace->stream_map, stream);
4f45f9bb 1577
1c78e839
JD
1578 if (di_trace->trace_static) {
1579 int trace_completed = 1;
1580
1581 g_hash_table_foreach(di_trace->stream_states,
1582 check_completed_trace, &trace_completed);
1583 if (trace_completed) {
1584 debug_info_close_trace(debug_it, di_trace);
1585 g_hash_table_remove(debug_it->trace_map,
1586 di_trace->trace);
1587 }
1588 }
1589
1590 goto end;
1591
1592error:
1593 BT_PUT(writer_stream);
1594
4f45f9bb
JD
1595end:
1596 return writer_stream;
1597}
1598
1599static
1600struct debug_info_source *lookup_debug_info(FILE *err,
1601 struct bt_ctf_event *event,
1602 struct debug_info *debug_info)
1603{
1604 int64_t vpid;
1605 uint64_t ip;
1606 struct debug_info_source *dbg_info_src = NULL;
1607 int ret;
1608
1609 ret = get_stream_event_context_int_field_value(err, event,
1610 "_vpid", &vpid);
1611 if (ret) {
1612 goto end;
1613 }
1614
1615 ret = get_stream_event_context_unsigned_int_field_value(err, event,
1616 "_ip", &ip);
1617 if (ret) {
1618 goto end;
1619 }
1620
1621 /* Get debug info for this context. */
1622 dbg_info_src = debug_info_query(debug_info, vpid, ip);
1623
1624end:
1625 return dbg_info_src;
1626}
1627
1628static
1629int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field,
1630 struct debug_info_source *dbg_info_src,
1631 struct debug_info_component *component)
1632{
2afcfbfb 1633 int i, nr_fields, ret = 0;
4f45f9bb
JD
1634 struct bt_ctf_field_type *debug_field_type = NULL;
1635 struct bt_ctf_field *field = NULL;
1636 struct bt_ctf_field_type *field_type = NULL;
1637
1638 debug_field_type = bt_ctf_field_get_type(debug_field);
1639 if (!debug_field_type) {
1640 fprintf(err, "[error] %s in %s:%d\n", __func__,
1641 __FILE__, __LINE__);
1642 goto error;
1643 }
1644
1645 nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type);
1646 for (i = 0; i < nr_fields; i++) {
1647 const char *field_name;
1648
1649 if (bt_ctf_field_type_structure_get_field(debug_field_type,
1650 &field_name, &field_type, i) < 0) {
1651 fprintf(err, "[error] %s in %s:%d\n", __func__,
1652 __FILE__, __LINE__);
1653 goto error;
1654 }
1655 BT_PUT(field_type);
1656
1657 field = bt_ctf_field_structure_get_field_by_index(debug_field, i);
1658 if (!strcmp(field_name, "bin")) {
1659 if (dbg_info_src && dbg_info_src->bin_path) {
1660 GString *tmp = g_string_new(NULL);
1661
1662 if (component->arg_full_path) {
1663 g_string_printf(tmp, "%s%s",
1664 dbg_info_src->bin_path,
1665 dbg_info_src->bin_loc);
1666 } else {
1667 g_string_printf(tmp, "%s%s",
1668 dbg_info_src->short_bin_path,
1669 dbg_info_src->bin_loc);
1670 }
1671 ret = bt_ctf_field_string_set_value(field, tmp->str);
1672 g_string_free(tmp, true);
1673 } else {
1674 ret = bt_ctf_field_string_set_value(field, "");
1675 }
1676 } else if (!strcmp(field_name, "func")) {
1677 if (dbg_info_src && dbg_info_src->func) {
1678 ret = bt_ctf_field_string_set_value(field,
1679 dbg_info_src->func);
1680 } else {
1681 ret = bt_ctf_field_string_set_value(field, "");
1682 }
1683 } else if (!strcmp(field_name, "src")) {
1684 if (dbg_info_src && dbg_info_src->src_path) {
1685 GString *tmp = g_string_new(NULL);
1686
1687 if (component->arg_full_path) {
1688 g_string_printf(tmp, "%s:%" PRId64,
1689 dbg_info_src->src_path,
1690 dbg_info_src->line_no);
1691 } else {
1692 g_string_printf(tmp, "%s:%" PRId64,
1693 dbg_info_src->short_src_path,
1694 dbg_info_src->line_no);
1695 }
1696 ret = bt_ctf_field_string_set_value(field, tmp->str);
1697 g_string_free(tmp, true);
1698 } else {
1699 ret = bt_ctf_field_string_set_value(field, "");
1700 }
1701 }
1702 BT_PUT(field);
1703 if (ret) {
1704 fprintf(err, "[error] %s in %s:%d\n", __func__,
1705 __FILE__, __LINE__);
1706 goto error;
1707 }
1708 }
1709 ret = 0;
1710 goto end;
1711
1712error:
1713 ret = -1;
1714end:
1715 bt_put(field_type);
1716 bt_put(field);
1717 bt_put(debug_field_type);
1718 return ret;
1719}
1720
1721static
1722int copy_set_debug_info_stream_event_context(FILE *err,
1723 struct bt_ctf_field *event_context,
1724 struct bt_ctf_event *event,
1725 struct bt_ctf_event *writer_event,
1726 struct debug_info *debug_info,
1727 struct debug_info_component *component)
1728{
08b6e8e8
JD
1729 struct bt_ctf_field_type *writer_event_context_type = NULL,
1730 *event_context_type = NULL;
4f45f9bb
JD
1731 struct bt_ctf_field *writer_event_context = NULL;
1732 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1733 struct bt_ctf_field_type *field_type = NULL;
1734 struct debug_info_source *dbg_info_src;
1735 int ret, nr_fields, i;
1736
1737 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1738 if (!writer_event_context) {
1739 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1740 goto error;
1741 }
1742
1743 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1744 if (!writer_event_context_type) {
1745 fprintf(err, "[error] %s in %s:%d\n", __func__,
1746 __FILE__, __LINE__);
1747 goto error;
1748 }
1749
08b6e8e8
JD
1750 event_context_type = bt_ctf_field_get_type(event_context);
1751 if (!event_context_type) {
1752 fprintf(err, "[error] %s in %s:%d\n", __func__,
1753 __FILE__, __LINE__);
1754 goto error;
1755 }
1756
4f45f9bb
JD
1757 /*
1758 * If it is not a structure, we did not modify it to add the debug info
1759 * fields, so just assign it as is.
1760 */
1487a16a 1761 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
1762 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1763 goto end;
1764 }
1765
1766 dbg_info_src = lookup_debug_info(err, event, debug_info);
1767
1768 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1769 for (i = 0; i < nr_fields; i++) {
1770 const char *field_name;
1771
1772 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1773 &field_name, &field_type, i) < 0) {
1774 fprintf(err, "[error] %s in %s:%d\n", __func__,
1775 __FILE__, __LINE__);
1776 goto error;
1777 }
1778
08b6e8e8
JD
1779 /*
1780 * Prevent illegal access in the event_context.
1781 */
1782 if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) {
1783 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1784 }
4f45f9bb
JD
1785 /*
1786 * The debug_info field, only exists in the writer event or
1787 * if it was set by a earlier pass of the debug_info plugin.
4f45f9bb
JD
1788 */
1789 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1790 !field) {
1791 debug_field = bt_ctf_field_structure_get_field_by_index(
1792 writer_event_context, i);
1793 if (!debug_field) {
1794 fprintf(err, "[error] %s in %s:%d\n", __func__,
1795 __FILE__, __LINE__);
1796 goto error;
1797 }
1798 ret = set_debug_info_field(err, debug_field,
1799 dbg_info_src, component);
1800 if (ret) {
1801 fprintf(err, "[error] %s in %s:%d\n", __func__,
1802 __FILE__, __LINE__);
1803 goto error;
1804 }
1805 BT_PUT(debug_field);
1806 } else {
1807 copy_field = bt_ctf_field_copy(field);
1808 if (!copy_field) {
1809 fprintf(err, "[error] %s in %s:%d\n", __func__,
1810 __FILE__, __LINE__);
1811 goto error;
1812 }
1813
2225de6b
PP
1814 ret = bt_ctf_field_structure_set_field_by_name(
1815 writer_event_context,
4f45f9bb
JD
1816 field_name, copy_field);
1817 if (ret) {
1818 fprintf(err, "[error] %s in %s:%d\n", __func__,
1819 __FILE__, __LINE__);
1820 goto error;
1821 }
1822 BT_PUT(copy_field);
1823 }
1824 BT_PUT(field_type);
1825 BT_PUT(field);
1826 }
1827
1828 ret = 0;
1829 goto end;
1830
1831error:
1832 ret = -1;
1833end:
08b6e8e8 1834 bt_put(event_context_type);
4f45f9bb
JD
1835 bt_put(writer_event_context_type);
1836 bt_put(writer_event_context);
1837 bt_put(field);
1838 bt_put(copy_field);
1839 bt_put(debug_field);
1840 bt_put(field_type);
1841 return ret;
1842}
1843
1844static
1845struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1846 struct bt_ctf_stream_class *stream_class)
1847{
1848 struct bt_ctf_trace *trace = NULL;
1849 struct bt_ctf_clock_class *clock_class = NULL;
1850
1851 trace = bt_ctf_stream_class_get_trace(stream_class);
1852 if (!trace) {
1853 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1854 __LINE__);
1855 goto end;
1856 }
1857
290b95cc
MD
1858 if (!bt_ctf_trace_get_clock_class_count(trace)) {
1859 /* No clock. */
1860 goto end;
1861 }
1862
4f45f9bb 1863 /* FIXME multi-clock? */
9ac68eb1 1864 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
4f45f9bb
JD
1865
1866 bt_put(trace);
1867
1868end:
1869 return clock_class;
1870}
1871
1872static
1873struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1874{
1875 struct bt_ctf_event_class *event_class = NULL;
1876 struct bt_ctf_stream_class *stream_class = NULL;
1877 struct bt_ctf_clock_class *clock_class = NULL;
1878
1879 event_class = bt_ctf_event_get_class(event);
1880 if (!event_class) {
1881 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1882 __LINE__);
1883 goto error;
1884 }
1885
1886 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1887 if (!stream_class) {
1888 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1889 __LINE__);
1890 goto error;
1891 }
1892
1893 clock_class = stream_class_get_clock_class(err, stream_class);
1894 goto end;
1895
1896error:
1897 BT_PUT(clock_class);
1898end:
1899 bt_put(stream_class);
1900 bt_put(event_class);
1901 return clock_class;
1902}
1903
1904static
1905int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1906 struct bt_ctf_event *writer_event)
1907{
1908 struct bt_ctf_clock_class *clock_class = NULL;
1909 struct bt_ctf_clock_value *clock_value = NULL;
1081db08 1910 int ret = 0;
4f45f9bb
JD
1911
1912 clock_class = event_get_clock_class(err, event);
1913 if (!clock_class) {
290b95cc
MD
1914 /* No clock on input trace. */
1915 goto end;
4f45f9bb
JD
1916 }
1917
1918 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1919 if (!clock_value) {
1920 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1921 __LINE__);
1922 goto error;
1923 }
1924
1925 /*
1926 * We share the same clocks, so we can assign the clock value to the
1927 * writer event.
1928 */
1929 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1930 if (ret) {
1931 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1932 __LINE__);
1933 goto error;
1934 }
1935
1936 ret = 0;
1937 goto end;
1938
1939error:
1940 ret = -1;
1941end:
1942 bt_put(clock_class);
1943 bt_put(clock_value);
1944 return ret;
1945}
1946
1947static
1948struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1949 struct bt_ctf_event_class *writer_event_class,
1950 struct debug_info *debug_info,
1951 struct debug_info_component *component)
1952{
1953 struct bt_ctf_event *writer_event = NULL;
f6f999a3 1954 struct bt_ctf_field *field = NULL, *copy_field = NULL;
4f45f9bb
JD
1955 int ret;
1956
1957 writer_event = bt_ctf_event_create(writer_event_class);
1958 if (!writer_event) {
1959 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1960 __LINE__);
1961 goto error;
1962 }
1963
1964 ret = set_event_clock_value(err, event, writer_event);
1965 if (ret) {
1966 fprintf(err, "[error] %s in %s:%d\n", __func__,
1967 __FILE__, __LINE__);
1968 goto error;
1969 }
1970
60ef553b 1971 /* Optional field, so it can fail silently. */
4f45f9bb 1972 field = bt_ctf_event_get_header(event);
60ef553b
JD
1973 if (field) {
1974 ret = ctf_copy_event_header(err, event, writer_event_class,
1975 writer_event, field);
1976 if (ret) {
1977 fprintf(err, "[error] %s in %s:%d\n", __func__,
1978 __FILE__, __LINE__);
1979 goto error;
1980 }
1981 BT_PUT(field);
4f45f9bb 1982 }
4f45f9bb
JD
1983
1984 /* Optional field, so it can fail silently. */
1985 field = bt_ctf_event_get_stream_event_context(event);
1986 if (field) {
1987 ret = copy_set_debug_info_stream_event_context(err,
1988 field, event, writer_event, debug_info,
1989 component);
1990 if (ret < 0) {
1991 fprintf(err, "[error] %s in %s:%d\n", __func__,
1992 __FILE__, __LINE__);
1993 goto error;
1994 }
1995 BT_PUT(field);
1996 }
1997
1998 /* Optional field, so it can fail silently. */
1999 field = bt_ctf_event_get_event_context(event);
60ef553b
JD
2000 if (field) {
2001 copy_field = bt_ctf_field_copy(field);
2002 if (!copy_field) {
2003 fprintf(err, "[error] %s in %s:%d\n", __func__,
2004 __FILE__, __LINE__);
2005 goto error;
2006 }
4f45f9bb
JD
2007 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
2008 if (ret < 0) {
2009 fprintf(err, "[error] %s in %s:%d\n", __func__,
2010 __FILE__, __LINE__);
2011 goto error;
2012 }
2013 BT_PUT(copy_field);
60ef553b 2014 BT_PUT(field);
4f45f9bb 2015 }
4f45f9bb 2016
9ac68eb1 2017 field = bt_ctf_event_get_event_payload(event);
4f45f9bb
JD
2018 if (!field) {
2019 fprintf(err, "[error] %s in %s:%d\n", __func__,
2020 __FILE__, __LINE__);
2021 goto error;
2022 }
2023 copy_field = bt_ctf_field_copy(field);
2024 if (copy_field) {
9ac68eb1 2025 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
4f45f9bb
JD
2026 if (ret < 0) {
2027 fprintf(err, "[error] %s in %s:%d\n", __func__,
2028 __FILE__, __LINE__);
2029 goto error;
2030 }
2031 BT_PUT(copy_field);
2032 }
2033 BT_PUT(field);
2034
2035 goto end;
2036
2037error:
2038 BT_PUT(writer_event);
2039end:
2040 bt_put(copy_field);
2041 bt_put(field);
2042 return writer_event;
2043}
2044
2045BT_HIDDEN
2046struct bt_ctf_event *debug_info_output_event(
2047 struct debug_info_iterator *debug_it,
2048 struct bt_ctf_event *event)
2049{
2050 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
2051 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
2052 struct bt_ctf_event *writer_event = NULL;
f6f999a3 2053 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
4f45f9bb 2054 struct bt_ctf_trace *writer_trace = NULL;
504db471
JD
2055 struct bt_ctf_stream *stream = NULL;
2056 struct debug_info_trace *di_trace;
4f45f9bb
JD
2057 struct debug_info *debug_info;
2058 const char *event_name;
2059 int int_ret;
2060
2061 event_class = bt_ctf_event_get_class(event);
2062 if (!event_class) {
2063 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2064 __FILE__, __LINE__);
2065 goto error;
2066 }
2067
2068 event_name = bt_ctf_event_class_get_name(event_class);
2069 if (!event_name) {
2070 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2071 __FILE__, __LINE__);
2072 goto error;
2073 }
2074
2075 stream_class = bt_ctf_event_class_get_stream_class(event_class);
2076 if (!stream_class) {
2077 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2078 __FILE__, __LINE__);
2079 goto error;
2080 }
504db471
JD
2081 stream = bt_ctf_event_get_stream(event);
2082 if (!stream) {
2083 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2084 __FILE__, __LINE__);
2085 goto error;
2086 }
2087 di_trace = lookup_di_trace_from_stream(debug_it, stream);
2088 if (!di_trace) {
2089 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2090 __FILE__, __LINE__);
2091 goto error;
2092 }
4f45f9bb
JD
2093
2094 writer_stream_class = g_hash_table_lookup(
504db471 2095 di_trace->stream_class_map,
4f45f9bb 2096 (gpointer) stream_class);
504db471 2097 if (!writer_stream_class) {
4f45f9bb
JD
2098 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2099 __FILE__, __LINE__);
2100 goto error;
2101 }
504db471 2102 bt_get(writer_stream_class);
4f45f9bb
JD
2103
2104 writer_event_class = get_event_class(debug_it,
2105 writer_stream_class, event_class);
2106 if (!writer_event_class) {
2107 writer_event_class = ctf_copy_event_class(debug_it->err,
2108 event_class);
2109 if (!writer_event_class) {
2110 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2111 __func__, __FILE__, __LINE__);
2112 goto error;
2113 }
2114 int_ret = bt_ctf_stream_class_add_event_class(
2115 writer_stream_class, writer_event_class);
2116 if (int_ret) {
2117 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2118 __func__, __FILE__, __LINE__);
2119 goto error;
2120 }
2121 }
2122
2123 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
2124 if (!writer_trace) {
2125 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2126 __FILE__, __LINE__);
2127 goto error;
2128 }
2129
504db471 2130 debug_info = get_trace_debug_info(debug_it, writer_trace, di_trace);
4f45f9bb
JD
2131 if (debug_info) {
2132 debug_info_handle_event(debug_it->err, event, debug_info);
2133 }
2134
2135 writer_event = debug_info_copy_event(debug_it->err, event,
2136 writer_event_class, debug_info,
2137 debug_it->debug_info_component);
2138 if (!writer_event) {
2139 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2140 __FILE__, __LINE__);
2141 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
2142 bt_ctf_event_class_get_name(writer_event_class));
2143 goto error;
2144 }
2145
2146 packet = bt_ctf_event_get_packet(event);
2147 if (!packet) {
2148 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2149 __FILE__, __LINE__);
2150 goto error;
2151 }
2152
504db471 2153 writer_packet = lookup_packet(debug_it, packet, di_trace);
4f45f9bb
JD
2154 if (!writer_packet) {
2155 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2156 __FILE__, __LINE__);
2157 goto error;
2158 }
2159 bt_get(writer_packet);
2160
2161 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
2162 if (int_ret < 0) {
2163 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2164 __FILE__, __LINE__);
2165 fprintf(debug_it->err, "[error] Failed to append event %s\n",
2166 bt_ctf_event_class_get_name(writer_event_class));
2167 goto error;
2168 }
2169
2170 /* Keep the reference on the writer event */
2171 goto end;
2172
2173error:
2174 BT_PUT(writer_event);
2175
2176end:
504db471 2177 bt_put(stream);
4f45f9bb
JD
2178 bt_put(writer_trace);
2179 bt_put(writer_packet);
2180 bt_put(packet);
2181 bt_put(writer_event_class);
2182 bt_put(writer_stream_class);
2183 bt_put(stream_class);
2184 bt_put(event_class);
2185 return writer_event;
2186}
This page took 0.117113 seconds and 4 git commands to generate.