a2250c2c75f28a052878e15e29e5b83d7339a6f5
[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 goto end;
571 }
572 *v = DEBUG_INFO_UNKNOWN_STREAM;
573
574 g_hash_table_insert(di_trace->stream_states, stream, v);
575
576 end:
577 return v;
578 }
579
580 static
581 void 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
591 static
592 gboolean empty_ht(gpointer key, gpointer value, gpointer user_data)
593 {
594 return TRUE;
595 }
596
597 BT_HIDDEN
598 void debug_info_close_trace(struct debug_info_iterator *debug_it,
599 struct debug_info_trace *di_trace)
600 {
601 if (di_trace->static_listener_id >= 0) {
602 bt_ctf_trace_remove_is_static_listener(di_trace->trace,
603 di_trace->static_listener_id);
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
632 static
633 int 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
665 error:
666 int_ret = -1;
667 end:
668 bt_put(stream_class);
669 bt_put(writer_stream_class);
670 return int_ret;
671 }
672
673 static
674 void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
675 {
676 struct debug_info_trace *di_trace = data;
677 struct debug_info_iterator *debug_it = di_trace->debug_it;
678 int trace_completed = 1, ret, nr_stream, i;
679 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
680 struct bt_ctf_trace *writer_trace = di_trace->writer_trace;
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 }
713
714 bt_ctf_trace_set_is_static(di_trace->writer_trace);
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 }
724
725 error:
726 bt_put(writer_stream);
727 bt_put(stream);
728 }
729
730 static
731 struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
732 struct bt_ctf_stream *stream) {
733 struct bt_ctf_trace *writer_trace = NULL;
734 struct debug_info_trace *di_trace = NULL;
735 struct bt_ctf_trace *trace = NULL;
736 struct bt_ctf_stream_class *stream_class = NULL;
737 struct bt_ctf_stream *writer_stream = NULL;
738 int ret, nr_stream, i;
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 }
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 }
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
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;
778 di_trace->debug_it = debug_it;
779 di_trace->stream_map = g_hash_table_new_full(g_direct_hash,
780 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
781 di_trace->stream_class_map = g_hash_table_new_full(g_direct_hash,
782 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
783 di_trace->packet_map = g_hash_table_new_full(g_direct_hash,
784 g_direct_equal, NULL, (GDestroyNotify) unref_packet);
785 di_trace->trace_debug_map = g_hash_table_new_full(g_direct_hash,
786 g_direct_equal, NULL, (GDestroyNotify) unref_debug_info);
787 di_trace->stream_states = g_hash_table_new_full(g_direct_hash,
788 g_direct_equal, NULL, destroy_stream_state_key);
789 g_hash_table_insert(debug_it->trace_map, (gpointer) trace, di_trace);
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);
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);
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;
825 bt_ctf_trace_set_is_static(writer_trace);
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 }
837
838
839 goto end;
840
841 error:
842 BT_PUT(writer_trace);
843 g_free(di_trace);
844 di_trace = NULL;
845 end:
846 bt_put(stream);
847 bt_put(writer_stream);
848 bt_put(stream_class);
849 bt_put(trace);
850 return di_trace;
851 }
852
853 static
854 struct bt_ctf_packet *lookup_packet(struct debug_info_iterator *debug_it,
855 struct bt_ctf_packet *packet,
856 struct debug_info_trace *di_trace)
857 {
858 return (struct bt_ctf_packet *) g_hash_table_lookup(
859 di_trace->packet_map,
860 (gpointer) packet);
861 }
862
863 static
864 struct bt_ctf_packet *insert_new_packet(struct debug_info_iterator *debug_it,
865 struct bt_ctf_packet *packet,
866 struct bt_ctf_stream *writer_stream,
867 struct debug_info_trace *di_trace)
868 {
869 struct bt_ctf_packet *writer_packet;
870 int ret;
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__);
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;
884 }
885
886 g_hash_table_insert(di_trace->packet_map, (gpointer) packet,
887 writer_packet);
888 goto end;
889
890 error:
891 BT_PUT(writer_packet);
892 end:
893 return writer_packet;
894 }
895
896 static
897 int 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
985 error:
986 BT_PUT(debug_field_type);
987 ret = -1;
988 end:
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
996 static
997 int create_debug_info_event_context_type(FILE *err,
998 struct bt_ctf_field_type *event_context_type,
999 struct bt_ctf_field_type *writer_event_context_type,
1000 struct debug_info_component *component)
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
1030 error:
1031 ret = -1;
1032 end:
1033 return ret;
1034 }
1035
1036 static
1037 struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err,
1038 struct bt_ctf_stream_class *stream_class,
1039 struct bt_ctf_trace *writer_trace,
1040 struct debug_info_component *component)
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 writer_stream_class = bt_ctf_stream_class_create_empty(name);
1049 if (!writer_stream_class) {
1050 fprintf(err, "[error] %s in %s:%d\n",
1051 __func__, __FILE__, __LINE__);
1052 goto error;
1053 }
1054
1055 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
1056 if (type) {
1057 ret_int = bt_ctf_stream_class_set_packet_context_type(
1058 writer_stream_class, type);
1059 if (ret_int < 0) {
1060 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1061 __LINE__);
1062 goto error;
1063 }
1064 BT_PUT(type);
1065 }
1066
1067 type = bt_ctf_stream_class_get_event_header_type(stream_class);
1068 if (type) {
1069 ret_int = bt_ctf_stream_class_set_event_header_type(
1070 writer_stream_class, type);
1071 if (ret_int < 0) {
1072 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1073 __LINE__);
1074 goto error;
1075 }
1076 BT_PUT(type);
1077 }
1078
1079 type = bt_ctf_stream_class_get_event_context_type(stream_class);
1080 if (type) {
1081 writer_event_context_type = bt_ctf_field_type_structure_create();
1082 if (!writer_event_context_type) {
1083 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1084 __LINE__);
1085 goto error;
1086 }
1087 ret_int = create_debug_info_event_context_type(err, type,
1088 writer_event_context_type, component);
1089 if (ret_int) {
1090 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1091 __LINE__);
1092 goto error;
1093 }
1094 BT_PUT(type);
1095
1096 ret_int = bt_ctf_stream_class_set_event_context_type(
1097 writer_stream_class, writer_event_context_type);
1098 if (ret_int < 0) {
1099 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1100 __LINE__);
1101 goto error;
1102 }
1103 BT_PUT(writer_event_context_type);
1104 }
1105
1106 goto end;
1107
1108 error:
1109 BT_PUT(writer_stream_class);
1110 end:
1111 bt_put(writer_event_context_type);
1112 bt_put(type);
1113 return writer_stream_class;
1114 }
1115
1116 /*
1117 * Add the original clock classes to the new trace, we do not need to copy
1118 * them, and if we did, we would have to manually inspect the stream class
1119 * to update the integers mapping to a clock.
1120 */
1121 static
1122 int add_clock_classes(FILE *err, struct bt_ctf_trace *writer_trace,
1123 struct bt_ctf_stream_class *writer_stream_class,
1124 struct bt_ctf_trace *trace)
1125 {
1126 int ret, clock_class_count, i;
1127
1128 clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
1129
1130 for (i = 0; i < clock_class_count; i++) {
1131 struct bt_ctf_clock_class *clock_class =
1132 bt_ctf_trace_get_clock_class_by_index(trace, i);
1133 struct bt_ctf_clock_class *existing_clock_class = NULL;
1134
1135 if (!clock_class) {
1136 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1137 __LINE__);
1138 goto error;
1139 }
1140
1141 existing_clock_class = bt_ctf_trace_get_clock_class_by_name(
1142 writer_trace, bt_ctf_clock_class_get_name(clock_class));
1143 bt_put(existing_clock_class);
1144 if (existing_clock_class) {
1145 bt_put(clock_class);
1146 continue;
1147 }
1148
1149 ret = bt_ctf_trace_add_clock_class(writer_trace, clock_class);
1150 BT_PUT(clock_class);
1151 if (ret != 0) {
1152 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1153 __LINE__);
1154 goto error;
1155 }
1156 }
1157
1158 ret = 0;
1159 goto end;
1160
1161 error:
1162 ret = -1;
1163 end:
1164 return ret;
1165
1166 }
1167
1168 static
1169 struct bt_ctf_stream_class *insert_new_stream_class(
1170 struct debug_info_iterator *debug_it,
1171 struct bt_ctf_stream_class *stream_class)
1172 {
1173 struct bt_ctf_stream_class *writer_stream_class = NULL;
1174 struct bt_ctf_trace *trace, *writer_trace = NULL;
1175 struct debug_info_trace *di_trace;
1176 enum bt_component_status ret;
1177 int int_ret;
1178
1179 trace = bt_ctf_stream_class_get_trace(stream_class);
1180 if (!trace) {
1181 fprintf(debug_it->err,
1182 "[error] %s in %s:%d\n", __func__, __FILE__,
1183 __LINE__);
1184 goto error;
1185 }
1186
1187 di_trace = lookup_trace(debug_it, trace);
1188 if (!di_trace) {
1189 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1190 __FILE__, __LINE__);
1191 ret = BT_COMPONENT_STATUS_ERROR;
1192 goto error;
1193 }
1194 writer_trace = di_trace->writer_trace;
1195 bt_get(writer_trace);
1196
1197 writer_stream_class = copy_stream_class_debug_info(debug_it->err, stream_class,
1198 writer_trace, debug_it->debug_info_component);
1199 if (!writer_stream_class) {
1200 fprintf(debug_it->err, "[error] Failed to copy stream class\n");
1201 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1202 __func__, __FILE__, __LINE__);
1203 goto error;
1204 }
1205
1206 int_ret = bt_ctf_trace_add_stream_class(writer_trace, writer_stream_class);
1207 if (int_ret) {
1208 fprintf(debug_it->err,
1209 "[error] %s in %s:%d\n", __func__, __FILE__,
1210 __LINE__);
1211 goto error;
1212 }
1213
1214 ret = add_clock_classes(debug_it->err, writer_trace,
1215 writer_stream_class, trace);
1216 if (ret != BT_COMPONENT_STATUS_OK) {
1217 fprintf(debug_it->err,
1218 "[error] %s in %s:%d\n", __func__, __FILE__,
1219 __LINE__);
1220 goto error;
1221 }
1222
1223 g_hash_table_insert(di_trace->stream_class_map,
1224 (gpointer) stream_class, writer_stream_class);
1225
1226 goto end;
1227
1228 error:
1229 BT_PUT(writer_stream_class);
1230 end:
1231 bt_put(trace);
1232 bt_put(writer_trace);
1233 return writer_stream_class;
1234 }
1235
1236 static
1237 struct bt_ctf_stream *insert_new_stream(
1238 struct debug_info_iterator *debug_it,
1239 struct bt_ctf_stream *stream,
1240 struct debug_info_trace *di_trace)
1241 {
1242 struct bt_ctf_stream *writer_stream = NULL;
1243 struct bt_ctf_stream_class *stream_class = NULL;
1244 struct bt_ctf_stream_class *writer_stream_class = NULL;
1245 int64_t id;
1246
1247 stream_class = bt_ctf_stream_get_class(stream);
1248 if (!stream_class) {
1249 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1250 __func__, __FILE__, __LINE__);
1251 goto error;
1252 }
1253
1254 writer_stream_class = g_hash_table_lookup(
1255 di_trace->stream_class_map,
1256 (gpointer) stream_class);
1257
1258 if (!writer_stream_class) {
1259 writer_stream_class = insert_new_stream_class(debug_it,
1260 stream_class);
1261 if (!writer_stream_class) {
1262 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1263 __func__, __FILE__, __LINE__);
1264 goto error;
1265 }
1266 }
1267 bt_get(writer_stream_class);
1268
1269 id = bt_ctf_stream_get_id(stream);
1270 if (id < 0) {
1271 writer_stream = bt_ctf_stream_create(writer_stream_class,
1272 bt_ctf_stream_get_name(stream));
1273 } else {
1274 writer_stream = bt_ctf_stream_create_with_id(
1275 writer_stream_class,
1276 bt_ctf_stream_get_name(stream), id);
1277 }
1278
1279 if (!writer_stream) {
1280 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1281 __func__, __FILE__, __LINE__);
1282 goto error;
1283 }
1284
1285 g_hash_table_insert(di_trace->stream_map, (gpointer) stream,
1286 writer_stream);
1287
1288 goto end;
1289
1290 error:
1291 BT_PUT(writer_stream);
1292 end:
1293 bt_put(stream_class);
1294 bt_put(writer_stream_class);
1295 return writer_stream;
1296 }
1297
1298 static
1299 struct bt_ctf_stream *lookup_stream(struct debug_info_iterator *debug_it,
1300 struct bt_ctf_stream *stream,
1301 struct debug_info_trace *di_trace)
1302 {
1303 return (struct bt_ctf_stream *) g_hash_table_lookup(
1304 di_trace->stream_map, (gpointer) stream);
1305 }
1306
1307 static
1308 struct bt_ctf_event_class *get_event_class(struct debug_info_iterator *debug_it,
1309 struct bt_ctf_stream_class *writer_stream_class,
1310 struct bt_ctf_event_class *event_class)
1311 {
1312 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
1313 bt_ctf_event_class_get_id(event_class));
1314 }
1315
1316 static
1317 struct debug_info_trace *lookup_di_trace_from_stream(
1318 struct debug_info_iterator *debug_it,
1319 struct bt_ctf_stream *stream)
1320 {
1321 struct bt_ctf_stream_class *stream_class = NULL;
1322 struct bt_ctf_trace *trace = NULL;
1323 struct debug_info_trace *di_trace = NULL;
1324
1325 stream_class = bt_ctf_stream_get_class(stream);
1326 if (!stream_class) {
1327 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1328 __func__, __FILE__, __LINE__);
1329 goto end;
1330 }
1331
1332 trace = bt_ctf_stream_class_get_trace(stream_class);
1333 if (!trace) {
1334 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1335 __func__, __FILE__, __LINE__);
1336 goto end;
1337 }
1338
1339 di_trace = (struct debug_info_trace *) g_hash_table_lookup(
1340 debug_it->trace_map, (gpointer) trace);
1341
1342 end:
1343 BT_PUT(stream_class);
1344 BT_PUT(trace);
1345 return di_trace;
1346 }
1347
1348 static
1349 struct bt_ctf_stream *get_writer_stream(
1350 struct debug_info_iterator *debug_it,
1351 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
1352 {
1353 struct bt_ctf_stream_class *stream_class = NULL;
1354 struct bt_ctf_stream *writer_stream = NULL;
1355 struct debug_info_trace *di_trace = NULL;
1356
1357 stream_class = bt_ctf_stream_get_class(stream);
1358 if (!stream_class) {
1359 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1360 __func__, __FILE__, __LINE__);
1361 goto error;
1362 }
1363
1364 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1365 if (!di_trace) {
1366 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1367 __func__, __FILE__, __LINE__);
1368 goto error;
1369 }
1370
1371 writer_stream = lookup_stream(debug_it, stream, di_trace);
1372 if (!writer_stream) {
1373 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1374 __func__, __FILE__, __LINE__);
1375 goto error;
1376 }
1377 bt_get(writer_stream);
1378
1379 goto end;
1380
1381 error:
1382 BT_PUT(writer_stream);
1383 end:
1384 bt_put(stream_class);
1385 return writer_stream;
1386 }
1387
1388 BT_HIDDEN
1389 struct bt_ctf_packet *debug_info_new_packet(
1390 struct debug_info_iterator *debug_it,
1391 struct bt_ctf_packet *packet)
1392 {
1393 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
1394 struct bt_ctf_packet *writer_packet = NULL;
1395 struct bt_ctf_field *packet_context = NULL;
1396 struct debug_info_trace *di_trace;
1397 int int_ret;
1398
1399 stream = bt_ctf_packet_get_stream(packet);
1400 if (!stream) {
1401 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1402 __func__, __FILE__, __LINE__);
1403 goto error;
1404 }
1405
1406 writer_stream = get_writer_stream(debug_it, packet, stream);
1407 if (!writer_stream) {
1408 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1409 __func__, __FILE__, __LINE__);
1410 goto error;
1411 }
1412
1413 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1414 if (!di_trace) {
1415 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1416 __FILE__, __LINE__);
1417 goto error;
1418 }
1419
1420 /*
1421 * If a packet was already opened, close it and remove it from
1422 * the HT.
1423 */
1424 writer_packet = lookup_packet(debug_it, packet, di_trace);
1425 if (writer_packet) {
1426 g_hash_table_remove(di_trace->packet_map, packet);
1427 BT_PUT(writer_packet);
1428 }
1429
1430 writer_packet = insert_new_packet(debug_it, packet, writer_stream,
1431 di_trace);
1432 if (!writer_packet) {
1433 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1434 __func__, __FILE__, __LINE__);
1435 goto error;
1436 }
1437
1438 packet_context = bt_ctf_packet_get_context(packet);
1439 if (packet_context) {
1440 int_ret = ctf_packet_copy_context(debug_it->err,
1441 packet, writer_stream, writer_packet);
1442 if (int_ret < 0) {
1443 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1444 __func__, __FILE__, __LINE__);
1445 goto error;
1446 }
1447 BT_PUT(packet_context);
1448 }
1449
1450 bt_get(writer_packet);
1451 goto end;
1452
1453 error:
1454
1455 end:
1456 bt_put(packet_context);
1457 bt_put(writer_stream);
1458 bt_put(stream);
1459 return writer_packet;
1460 }
1461
1462 BT_HIDDEN
1463 struct bt_ctf_packet *debug_info_close_packet(
1464 struct debug_info_iterator *debug_it,
1465 struct bt_ctf_packet *packet)
1466 {
1467 struct bt_ctf_packet *writer_packet = NULL;
1468 struct bt_ctf_stream *stream = NULL;
1469 struct debug_info_trace *di_trace;
1470
1471 stream = bt_ctf_packet_get_stream(packet);
1472 if (!stream) {
1473 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1474 __FILE__, __LINE__);
1475 goto end;
1476 }
1477
1478 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1479 if (!di_trace) {
1480 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1481 __FILE__, __LINE__);
1482 goto end;
1483 }
1484
1485 writer_packet = lookup_packet(debug_it, packet, di_trace);
1486 if (!writer_packet) {
1487 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1488 __func__, __FILE__, __LINE__);
1489 goto end;
1490 }
1491 bt_get(writer_packet);
1492 g_hash_table_remove(di_trace->packet_map, packet);
1493
1494 end:
1495 bt_put(stream);
1496 return writer_packet;
1497 }
1498
1499 BT_HIDDEN
1500 struct bt_ctf_stream *debug_info_stream_begin(
1501 struct debug_info_iterator *debug_it,
1502 struct bt_ctf_stream *stream)
1503 {
1504 struct bt_ctf_stream *writer_stream = NULL;
1505 enum debug_info_stream_state *state;
1506 struct debug_info_trace *di_trace = NULL;
1507
1508 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1509 if (!di_trace) {
1510 di_trace = insert_new_trace(debug_it, stream);
1511 if (!di_trace) {
1512 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1513 __func__, __FILE__, __LINE__);
1514 goto error;
1515 }
1516 }
1517
1518 /* Set the stream as active */
1519 state = g_hash_table_lookup(di_trace->stream_states, stream);
1520 if (!state) {
1521 if (di_trace->trace_static) {
1522 fprintf(debug_it->err, "[error] Adding a new stream "
1523 "on a static trace\n");
1524 goto error;
1525 }
1526 state = insert_new_stream_state(debug_it, di_trace,
1527 stream);
1528 if (!state) {
1529 fprintf(debug_it->err, "[error] Adding a new stream "
1530 "on a static trace\n");
1531 goto error;
1532 }
1533 }
1534 if (*state != DEBUG_INFO_UNKNOWN_STREAM) {
1535 fprintf(debug_it->err, "[error] Unexpected stream state %d\n",
1536 *state);
1537 goto error;
1538 }
1539 *state = DEBUG_INFO_ACTIVE_STREAM;
1540
1541 writer_stream = lookup_stream(debug_it, stream, di_trace);
1542 if (!writer_stream) {
1543 writer_stream = insert_new_stream(debug_it, stream, di_trace);
1544 }
1545 bt_get(writer_stream);
1546
1547 goto end;
1548
1549 error:
1550 BT_PUT(writer_stream);
1551 end:
1552 return writer_stream;
1553 }
1554
1555 BT_HIDDEN
1556 struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it,
1557 struct bt_ctf_stream *stream)
1558 {
1559 struct bt_ctf_stream *writer_stream = NULL;
1560 struct debug_info_trace *di_trace = NULL;
1561 enum debug_info_stream_state *state;
1562
1563 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1564 if (!di_trace) {
1565 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1566 __func__, __FILE__, __LINE__);
1567 goto error;
1568 }
1569
1570 writer_stream = lookup_stream(debug_it, stream, di_trace);
1571 if (!writer_stream) {
1572 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1573 __func__, __FILE__, __LINE__);
1574 goto error;
1575 }
1576 /*
1577 * Take the ref on the stream and keep it until the notification
1578 * is created.
1579 */
1580 bt_get(writer_stream);
1581
1582 state = g_hash_table_lookup(di_trace->stream_states, stream);
1583 if (*state != DEBUG_INFO_ACTIVE_STREAM) {
1584 fprintf(debug_it->err, "[error] Unexpected stream "
1585 "state %d\n", *state);
1586 goto error;
1587 }
1588 *state = DEBUG_INFO_COMPLETED_STREAM;
1589
1590 g_hash_table_remove(di_trace->stream_map, stream);
1591
1592 if (di_trace->trace_static) {
1593 int trace_completed = 1;
1594
1595 g_hash_table_foreach(di_trace->stream_states,
1596 check_completed_trace, &trace_completed);
1597 if (trace_completed) {
1598 debug_info_close_trace(debug_it, di_trace);
1599 g_hash_table_remove(debug_it->trace_map,
1600 di_trace->trace);
1601 }
1602 }
1603
1604 goto end;
1605
1606 error:
1607 BT_PUT(writer_stream);
1608
1609 end:
1610 return writer_stream;
1611 }
1612
1613 static
1614 struct debug_info_source *lookup_debug_info(FILE *err,
1615 struct bt_ctf_event *event,
1616 struct debug_info *debug_info)
1617 {
1618 int64_t vpid;
1619 uint64_t ip;
1620 struct debug_info_source *dbg_info_src = NULL;
1621 int ret;
1622
1623 ret = get_stream_event_context_int_field_value(err, event,
1624 "_vpid", &vpid);
1625 if (ret) {
1626 goto end;
1627 }
1628
1629 ret = get_stream_event_context_unsigned_int_field_value(err, event,
1630 "_ip", &ip);
1631 if (ret) {
1632 goto end;
1633 }
1634
1635 /* Get debug info for this context. */
1636 dbg_info_src = debug_info_query(debug_info, vpid, ip);
1637
1638 end:
1639 return dbg_info_src;
1640 }
1641
1642 static
1643 int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field,
1644 struct debug_info_source *dbg_info_src,
1645 struct debug_info_component *component)
1646 {
1647 int i, nr_fields, ret = 0;
1648 struct bt_ctf_field_type *debug_field_type = NULL;
1649 struct bt_ctf_field *field = NULL;
1650 struct bt_ctf_field_type *field_type = NULL;
1651
1652 debug_field_type = bt_ctf_field_get_type(debug_field);
1653 if (!debug_field_type) {
1654 fprintf(err, "[error] %s in %s:%d\n", __func__,
1655 __FILE__, __LINE__);
1656 goto error;
1657 }
1658
1659 nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type);
1660 for (i = 0; i < nr_fields; i++) {
1661 const char *field_name;
1662
1663 if (bt_ctf_field_type_structure_get_field(debug_field_type,
1664 &field_name, &field_type, i) < 0) {
1665 fprintf(err, "[error] %s in %s:%d\n", __func__,
1666 __FILE__, __LINE__);
1667 goto error;
1668 }
1669 BT_PUT(field_type);
1670
1671 field = bt_ctf_field_structure_get_field_by_index(debug_field, i);
1672 if (!strcmp(field_name, "bin")) {
1673 if (dbg_info_src && dbg_info_src->bin_path) {
1674 GString *tmp = g_string_new(NULL);
1675
1676 if (component->arg_full_path) {
1677 g_string_printf(tmp, "%s%s",
1678 dbg_info_src->bin_path,
1679 dbg_info_src->bin_loc);
1680 } else {
1681 g_string_printf(tmp, "%s%s",
1682 dbg_info_src->short_bin_path,
1683 dbg_info_src->bin_loc);
1684 }
1685 ret = bt_ctf_field_string_set_value(field, tmp->str);
1686 g_string_free(tmp, true);
1687 } else {
1688 ret = bt_ctf_field_string_set_value(field, "");
1689 }
1690 } else if (!strcmp(field_name, "func")) {
1691 if (dbg_info_src && dbg_info_src->func) {
1692 ret = bt_ctf_field_string_set_value(field,
1693 dbg_info_src->func);
1694 } else {
1695 ret = bt_ctf_field_string_set_value(field, "");
1696 }
1697 } else if (!strcmp(field_name, "src")) {
1698 if (dbg_info_src && dbg_info_src->src_path) {
1699 GString *tmp = g_string_new(NULL);
1700
1701 if (component->arg_full_path) {
1702 g_string_printf(tmp, "%s:%" PRId64,
1703 dbg_info_src->src_path,
1704 dbg_info_src->line_no);
1705 } else {
1706 g_string_printf(tmp, "%s:%" PRId64,
1707 dbg_info_src->short_src_path,
1708 dbg_info_src->line_no);
1709 }
1710 ret = bt_ctf_field_string_set_value(field, tmp->str);
1711 g_string_free(tmp, true);
1712 } else {
1713 ret = bt_ctf_field_string_set_value(field, "");
1714 }
1715 }
1716 BT_PUT(field);
1717 if (ret) {
1718 fprintf(err, "[error] %s in %s:%d\n", __func__,
1719 __FILE__, __LINE__);
1720 goto error;
1721 }
1722 }
1723 ret = 0;
1724 goto end;
1725
1726 error:
1727 ret = -1;
1728 end:
1729 bt_put(field_type);
1730 bt_put(field);
1731 bt_put(debug_field_type);
1732 return ret;
1733 }
1734
1735 static
1736 int copy_set_debug_info_stream_event_context(FILE *err,
1737 struct bt_ctf_field *event_context,
1738 struct bt_ctf_event *event,
1739 struct bt_ctf_event *writer_event,
1740 struct debug_info *debug_info,
1741 struct debug_info_component *component)
1742 {
1743 struct bt_ctf_field_type *writer_event_context_type = NULL,
1744 *event_context_type = NULL;
1745 struct bt_ctf_field *writer_event_context = NULL;
1746 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1747 struct bt_ctf_field_type *field_type = NULL;
1748 struct debug_info_source *dbg_info_src;
1749 int ret, nr_fields, i;
1750
1751 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1752 if (!writer_event_context) {
1753 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1754 goto error;
1755 }
1756
1757 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1758 if (!writer_event_context_type) {
1759 fprintf(err, "[error] %s in %s:%d\n", __func__,
1760 __FILE__, __LINE__);
1761 goto error;
1762 }
1763
1764 event_context_type = bt_ctf_field_get_type(event_context);
1765 if (!event_context_type) {
1766 fprintf(err, "[error] %s in %s:%d\n", __func__,
1767 __FILE__, __LINE__);
1768 goto error;
1769 }
1770
1771 /*
1772 * If it is not a structure, we did not modify it to add the debug info
1773 * fields, so just assign it as is.
1774 */
1775 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
1776 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1777 goto end;
1778 }
1779
1780 dbg_info_src = lookup_debug_info(err, event, debug_info);
1781
1782 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1783 for (i = 0; i < nr_fields; i++) {
1784 const char *field_name;
1785
1786 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1787 &field_name, &field_type, i) < 0) {
1788 fprintf(err, "[error] %s in %s:%d\n", __func__,
1789 __FILE__, __LINE__);
1790 goto error;
1791 }
1792
1793 /*
1794 * Prevent illegal access in the event_context.
1795 */
1796 if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) {
1797 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1798 }
1799 /*
1800 * The debug_info field, only exists in the writer event or
1801 * if it was set by a earlier pass of the debug_info plugin.
1802 */
1803 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1804 !field) {
1805 debug_field = bt_ctf_field_structure_get_field_by_index(
1806 writer_event_context, i);
1807 if (!debug_field) {
1808 fprintf(err, "[error] %s in %s:%d\n", __func__,
1809 __FILE__, __LINE__);
1810 goto error;
1811 }
1812 ret = set_debug_info_field(err, debug_field,
1813 dbg_info_src, component);
1814 if (ret) {
1815 fprintf(err, "[error] %s in %s:%d\n", __func__,
1816 __FILE__, __LINE__);
1817 goto error;
1818 }
1819 BT_PUT(debug_field);
1820 } else {
1821 copy_field = bt_ctf_field_copy(field);
1822 if (!copy_field) {
1823 fprintf(err, "[error] %s in %s:%d\n", __func__,
1824 __FILE__, __LINE__);
1825 goto error;
1826 }
1827
1828 ret = bt_ctf_field_structure_set_field_by_name(
1829 writer_event_context,
1830 field_name, copy_field);
1831 if (ret) {
1832 fprintf(err, "[error] %s in %s:%d\n", __func__,
1833 __FILE__, __LINE__);
1834 goto error;
1835 }
1836 BT_PUT(copy_field);
1837 }
1838 BT_PUT(field_type);
1839 BT_PUT(field);
1840 }
1841
1842 ret = 0;
1843 goto end;
1844
1845 error:
1846 ret = -1;
1847 end:
1848 bt_put(event_context_type);
1849 bt_put(writer_event_context_type);
1850 bt_put(writer_event_context);
1851 bt_put(field);
1852 bt_put(copy_field);
1853 bt_put(debug_field);
1854 bt_put(field_type);
1855 return ret;
1856 }
1857
1858 static
1859 struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1860 struct bt_ctf_stream_class *stream_class)
1861 {
1862 struct bt_ctf_trace *trace = NULL;
1863 struct bt_ctf_clock_class *clock_class = NULL;
1864
1865 trace = bt_ctf_stream_class_get_trace(stream_class);
1866 if (!trace) {
1867 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1868 __LINE__);
1869 goto end;
1870 }
1871
1872 if (!bt_ctf_trace_get_clock_class_count(trace)) {
1873 /* No clock. */
1874 goto end;
1875 }
1876
1877 /* FIXME multi-clock? */
1878 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
1879
1880 bt_put(trace);
1881
1882 end:
1883 return clock_class;
1884 }
1885
1886 static
1887 struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1888 {
1889 struct bt_ctf_event_class *event_class = NULL;
1890 struct bt_ctf_stream_class *stream_class = NULL;
1891 struct bt_ctf_clock_class *clock_class = NULL;
1892
1893 event_class = bt_ctf_event_get_class(event);
1894 if (!event_class) {
1895 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1896 __LINE__);
1897 goto error;
1898 }
1899
1900 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1901 if (!stream_class) {
1902 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1903 __LINE__);
1904 goto error;
1905 }
1906
1907 clock_class = stream_class_get_clock_class(err, stream_class);
1908 goto end;
1909
1910 error:
1911 BT_PUT(clock_class);
1912 end:
1913 bt_put(stream_class);
1914 bt_put(event_class);
1915 return clock_class;
1916 }
1917
1918 static
1919 int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1920 struct bt_ctf_event *writer_event)
1921 {
1922 struct bt_ctf_clock_class *clock_class = NULL;
1923 struct bt_ctf_clock_value *clock_value = NULL;
1924 int ret = 0;
1925
1926 clock_class = event_get_clock_class(err, event);
1927 if (!clock_class) {
1928 /* No clock on input trace. */
1929 goto end;
1930 }
1931
1932 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1933 if (!clock_value) {
1934 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1935 __LINE__);
1936 goto error;
1937 }
1938
1939 /*
1940 * We share the same clocks, so we can assign the clock value to the
1941 * writer event.
1942 */
1943 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1944 if (ret) {
1945 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1946 __LINE__);
1947 goto error;
1948 }
1949
1950 ret = 0;
1951 goto end;
1952
1953 error:
1954 ret = -1;
1955 end:
1956 bt_put(clock_class);
1957 bt_put(clock_value);
1958 return ret;
1959 }
1960
1961 static
1962 struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1963 struct bt_ctf_event_class *writer_event_class,
1964 struct debug_info *debug_info,
1965 struct debug_info_component *component)
1966 {
1967 struct bt_ctf_event *writer_event = NULL;
1968 struct bt_ctf_field *field = NULL, *copy_field = NULL;
1969 int ret;
1970
1971 writer_event = bt_ctf_event_create(writer_event_class);
1972 if (!writer_event) {
1973 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1974 __LINE__);
1975 goto error;
1976 }
1977
1978 ret = set_event_clock_value(err, event, writer_event);
1979 if (ret) {
1980 fprintf(err, "[error] %s in %s:%d\n", __func__,
1981 __FILE__, __LINE__);
1982 goto error;
1983 }
1984
1985 /* Optional field, so it can fail silently. */
1986 field = bt_ctf_event_get_header(event);
1987 if (field) {
1988 ret = ctf_copy_event_header(err, event, writer_event_class,
1989 writer_event, field);
1990 if (ret) {
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_stream_event_context(event);
2000 if (field) {
2001 ret = copy_set_debug_info_stream_event_context(err,
2002 field, event, writer_event, debug_info,
2003 component);
2004 if (ret < 0) {
2005 fprintf(err, "[error] %s in %s:%d\n", __func__,
2006 __FILE__, __LINE__);
2007 goto error;
2008 }
2009 BT_PUT(field);
2010 }
2011
2012 /* Optional field, so it can fail silently. */
2013 field = bt_ctf_event_get_event_context(event);
2014 if (field) {
2015 copy_field = bt_ctf_field_copy(field);
2016 if (!copy_field) {
2017 fprintf(err, "[error] %s in %s:%d\n", __func__,
2018 __FILE__, __LINE__);
2019 goto error;
2020 }
2021 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
2022 if (ret < 0) {
2023 fprintf(err, "[error] %s in %s:%d\n", __func__,
2024 __FILE__, __LINE__);
2025 goto error;
2026 }
2027 BT_PUT(copy_field);
2028 BT_PUT(field);
2029 }
2030
2031 field = bt_ctf_event_get_event_payload(event);
2032 if (!field) {
2033 fprintf(err, "[error] %s in %s:%d\n", __func__,
2034 __FILE__, __LINE__);
2035 goto error;
2036 }
2037 copy_field = bt_ctf_field_copy(field);
2038 if (copy_field) {
2039 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
2040 if (ret < 0) {
2041 fprintf(err, "[error] %s in %s:%d\n", __func__,
2042 __FILE__, __LINE__);
2043 goto error;
2044 }
2045 BT_PUT(copy_field);
2046 }
2047 BT_PUT(field);
2048
2049 goto end;
2050
2051 error:
2052 BT_PUT(writer_event);
2053 end:
2054 bt_put(copy_field);
2055 bt_put(field);
2056 return writer_event;
2057 }
2058
2059 BT_HIDDEN
2060 struct bt_ctf_event *debug_info_output_event(
2061 struct debug_info_iterator *debug_it,
2062 struct bt_ctf_event *event)
2063 {
2064 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
2065 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
2066 struct bt_ctf_event *writer_event = NULL;
2067 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
2068 struct bt_ctf_trace *writer_trace = NULL;
2069 struct bt_ctf_stream *stream = NULL;
2070 struct debug_info_trace *di_trace;
2071 struct debug_info *debug_info;
2072 const char *event_name;
2073 int int_ret;
2074
2075 event_class = bt_ctf_event_get_class(event);
2076 if (!event_class) {
2077 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2078 __FILE__, __LINE__);
2079 goto error;
2080 }
2081
2082 event_name = bt_ctf_event_class_get_name(event_class);
2083 if (!event_name) {
2084 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2085 __FILE__, __LINE__);
2086 goto error;
2087 }
2088
2089 stream_class = bt_ctf_event_class_get_stream_class(event_class);
2090 if (!stream_class) {
2091 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2092 __FILE__, __LINE__);
2093 goto error;
2094 }
2095 stream = bt_ctf_event_get_stream(event);
2096 if (!stream) {
2097 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2098 __FILE__, __LINE__);
2099 goto error;
2100 }
2101 di_trace = lookup_di_trace_from_stream(debug_it, stream);
2102 if (!di_trace) {
2103 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2104 __FILE__, __LINE__);
2105 goto error;
2106 }
2107
2108 writer_stream_class = g_hash_table_lookup(
2109 di_trace->stream_class_map,
2110 (gpointer) stream_class);
2111 if (!writer_stream_class) {
2112 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2113 __FILE__, __LINE__);
2114 goto error;
2115 }
2116 bt_get(writer_stream_class);
2117
2118 writer_event_class = get_event_class(debug_it,
2119 writer_stream_class, event_class);
2120 if (!writer_event_class) {
2121 writer_event_class = ctf_copy_event_class(debug_it->err,
2122 event_class);
2123 if (!writer_event_class) {
2124 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2125 __func__, __FILE__, __LINE__);
2126 goto error;
2127 }
2128 int_ret = bt_ctf_stream_class_add_event_class(
2129 writer_stream_class, writer_event_class);
2130 if (int_ret) {
2131 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2132 __func__, __FILE__, __LINE__);
2133 goto error;
2134 }
2135 }
2136
2137 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
2138 if (!writer_trace) {
2139 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2140 __FILE__, __LINE__);
2141 goto error;
2142 }
2143
2144 debug_info = get_trace_debug_info(debug_it, writer_trace, di_trace);
2145 if (debug_info) {
2146 debug_info_handle_event(debug_it->err, event, debug_info);
2147 }
2148
2149 writer_event = debug_info_copy_event(debug_it->err, event,
2150 writer_event_class, debug_info,
2151 debug_it->debug_info_component);
2152 if (!writer_event) {
2153 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2154 __FILE__, __LINE__);
2155 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
2156 bt_ctf_event_class_get_name(writer_event_class));
2157 goto error;
2158 }
2159
2160 packet = bt_ctf_event_get_packet(event);
2161 if (!packet) {
2162 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2163 __FILE__, __LINE__);
2164 goto error;
2165 }
2166
2167 writer_packet = lookup_packet(debug_it, packet, di_trace);
2168 if (!writer_packet) {
2169 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2170 __FILE__, __LINE__);
2171 goto error;
2172 }
2173 bt_get(writer_packet);
2174
2175 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
2176 if (int_ret < 0) {
2177 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2178 __FILE__, __LINE__);
2179 fprintf(debug_it->err, "[error] Failed to append event %s\n",
2180 bt_ctf_event_class_get_name(writer_event_class));
2181 goto error;
2182 }
2183
2184 /* Keep the reference on the writer event */
2185 goto end;
2186
2187 error:
2188 BT_PUT(writer_event);
2189
2190 end:
2191 bt_put(stream);
2192 bt_put(writer_trace);
2193 bt_put(writer_packet);
2194 bt_put(packet);
2195 bt_put(writer_event_class);
2196 bt_put(writer_stream_class);
2197 bt_put(stream_class);
2198 bt_put(event_class);
2199 return writer_event;
2200 }
This page took 0.078036 seconds and 3 git commands to generate.