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