Fix debug-info: handle event layouts of lttng-ust traces prior to 2.9
[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_field *get_payload_field(FILE *err,
45 struct bt_ctf_event *event, const char *field_name)
46 {
47 struct bt_ctf_field *field = NULL, *sec = NULL;
48 struct bt_ctf_field_type *sec_type = NULL;
49
50 sec = bt_ctf_event_get_payload(event, NULL);
51 if (!sec) {
52 fprintf(err, "[error] %s in %s:%d\n", __func__,
53 __FILE__, __LINE__);
54 goto end;
55 }
56
57 sec_type = bt_ctf_field_get_type(sec);
58 if (!sec_type) {
59 fprintf(err, "[error] %s in %s:%d\n", __func__,
60 __FILE__, __LINE__);
61 goto end;
62 }
63
64 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
65 fprintf(err, "[error] %s in %s:%d\n", __func__,
66 __FILE__, __LINE__);
67 goto end;
68 }
69
70 field = bt_ctf_field_structure_get_field(sec, field_name);
71
72 end:
73 bt_put(sec_type);
74 bt_put(sec);
75 return field;
76 }
77
78 static
79 struct bt_ctf_field *get_stream_event_context_field(FILE *err,
80 struct bt_ctf_event *event, const char *field_name)
81 {
82 struct bt_ctf_field *field = NULL, *sec = NULL;
83 struct bt_ctf_field_type *sec_type = NULL;
84
85 sec = bt_ctf_event_get_stream_event_context(event);
86 if (!sec) {
87 goto end;
88 }
89
90 sec_type = bt_ctf_field_get_type(sec);
91 if (!sec_type) {
92 fprintf(err, "[error] %s in %s:%d\n", __func__,
93 __FILE__, __LINE__);
94 goto end;
95 }
96
97 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
98 fprintf(err, "[error] %s in %s:%d\n", __func__,
99 __FILE__, __LINE__);
100 goto end;
101 }
102
103 field = bt_ctf_field_structure_get_field(sec, field_name);
104
105 end:
106 bt_put(sec_type);
107 bt_put(sec);
108 return field;
109 }
110
111 BT_HIDDEN
112 int get_stream_event_context_unsigned_int_field_value(FILE *err,
113 struct bt_ctf_event *event, const char *field_name,
114 uint64_t *value)
115 {
116 int ret;
117 struct bt_ctf_field *field = NULL;
118 struct bt_ctf_field_type *field_type = NULL;
119
120 field = get_stream_event_context_field(err, event, field_name);
121 if (!field) {
122 goto error;
123 }
124
125 field_type = bt_ctf_field_get_type(field);
126 if (!field_type) {
127 fprintf(err, "[error] %s in %s:%d\n", __func__,
128 __FILE__, __LINE__);
129 goto error;
130 }
131
132 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
133 fprintf(err, "[error] %s in %s:%d\n", __func__,
134 __FILE__, __LINE__);
135 goto error;
136 }
137
138 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
139 fprintf(err, "[error] %s in %s:%d\n", __func__,
140 __FILE__, __LINE__);
141 goto error;
142 }
143
144 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
145 goto end;
146
147 error:
148 ret = -1;
149 end:
150 bt_put(field_type);
151 bt_put(field);
152 return ret;
153 }
154
155 BT_HIDDEN
156 int get_stream_event_context_int_field_value(FILE *err, struct bt_ctf_event *event,
157 const char *field_name, int64_t *value)
158 {
159 struct bt_ctf_field *field = NULL;
160 struct bt_ctf_field_type *field_type = NULL;
161 int ret;
162
163 field = get_stream_event_context_field(err, event, field_name);
164 if (!field) {
165 goto error;
166 }
167
168 field_type = bt_ctf_field_get_type(field);
169 if (!field_type) {
170 fprintf(err, "[error] %s in %s:%d\n", __func__,
171 __FILE__, __LINE__);
172 goto error;
173 }
174
175 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
176 fprintf(err, "[error] %s in %s:%d\n", __func__,
177 __FILE__, __LINE__);
178 goto error;
179 }
180
181 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
182 fprintf(err, "[error] %s in %s:%d\n", __func__,
183 __FILE__, __LINE__);
184 goto error;
185 }
186
187 ret = bt_ctf_field_signed_integer_get_value(field, value);
188 goto end;
189
190 error:
191 ret = -1;
192 end:
193 bt_put(field_type);
194 bt_put(field);
195 return ret;
196 }
197
198 BT_HIDDEN
199 int get_payload_unsigned_int_field_value(FILE *err,
200 struct bt_ctf_event *event, const char *field_name,
201 uint64_t *value)
202 {
203 struct bt_ctf_field *field = NULL;
204 struct bt_ctf_field_type *field_type = NULL;
205 int ret;
206
207 field = get_payload_field(err, event, field_name);
208 if (!field) {
209 fprintf(err, "[error] %s in %s:%d\n", __func__,
210 __FILE__, __LINE__);
211 goto error;
212 }
213
214 field_type = bt_ctf_field_get_type(field);
215 if (!field_type) {
216 fprintf(err, "[error] %s in %s:%d\n", __func__,
217 __FILE__, __LINE__);
218 goto error;
219 }
220
221 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
222 fprintf(err, "[error] %s in %s:%d\n", __func__,
223 __FILE__, __LINE__);
224 goto error;
225 }
226
227 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
228 fprintf(err, "[error] %s in %s:%d\n", __func__,
229 __FILE__, __LINE__);
230 goto error;
231 }
232
233 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
234 goto end;
235
236 error:
237 ret = -1;
238 end:
239 bt_put(field_type);
240 bt_put(field);
241 return ret;
242 }
243
244 BT_HIDDEN
245 int get_payload_int_field_value(FILE *err, struct bt_ctf_event *event,
246 const char *field_name, int64_t *value)
247 {
248 struct bt_ctf_field *field = NULL;
249 struct bt_ctf_field_type *field_type = NULL;
250 int ret;
251
252 field = get_payload_field(err, event, field_name);
253 if (!field) {
254 fprintf(err, "[error] %s in %s:%d\n", __func__,
255 __FILE__, __LINE__);
256 goto error;
257 }
258
259 field_type = bt_ctf_field_get_type(field);
260 if (!field_type) {
261 fprintf(err, "[error] %s in %s:%d\n", __func__,
262 __FILE__, __LINE__);
263 goto error;
264 }
265
266 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
267 fprintf(err, "[error] %s in %s:%d\n", __func__,
268 __FILE__, __LINE__);
269 goto error;
270 }
271
272 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
273 fprintf(err, "[error] %s in %s:%d\n", __func__,
274 __FILE__, __LINE__);
275 goto error;
276 }
277
278 ret = bt_ctf_field_signed_integer_get_value(field, value);
279 goto end;
280
281 error:
282 ret = -1;
283 end:
284 bt_put(field_type);
285 bt_put(field);
286 return ret;
287 }
288
289 BT_HIDDEN
290 int get_payload_string_field_value(FILE *err,
291 struct bt_ctf_event *event, const char *field_name,
292 const char **value)
293 {
294 struct bt_ctf_field *field = NULL;
295 struct bt_ctf_field_type *field_type = NULL;
296 int ret;
297
298 /*
299 * The field might not exist, no error here.
300 */
301 field = get_payload_field(err, event, field_name);
302 if (!field) {
303 goto error;
304 }
305
306 field_type = bt_ctf_field_get_type(field);
307 if (!field_type) {
308 fprintf(err, "[error] %s in %s:%d\n", __func__,
309 __FILE__, __LINE__);
310 goto error;
311 }
312
313 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) {
314 fprintf(err, "[error] %s in %s:%d\n", __func__,
315 __FILE__, __LINE__);
316 goto error;
317 }
318
319 *value = bt_ctf_field_string_get_value(field);
320 if (!*value) {
321 fprintf(err, "[error] %s in %s:%d\n", __func__,
322 __FILE__, __LINE__);
323 goto error;
324 }
325
326 ret = 0;
327 goto end;
328
329 error:
330 ret = -1;
331 end:
332 bt_put(field_type);
333 bt_put(field);
334 return ret;
335 }
336
337 BT_HIDDEN
338 int get_payload_build_id_field_value(FILE *err,
339 struct bt_ctf_event *event, const char *field_name,
340 uint8_t **build_id, uint64_t *build_id_len)
341 {
342 struct bt_ctf_field *field = NULL, *seq_len = NULL;
343 struct bt_ctf_field_type *field_type = NULL;
344 struct bt_ctf_field *seq_field = NULL;
345 uint64_t i;
346 int ret;
347
348 *build_id = NULL;
349
350 field = get_payload_field(err, event, field_name);
351 if (!field) {
352 fprintf(err, "[error] %s in %s:%d\n", __func__,
353 __FILE__, __LINE__);
354 goto error;
355 }
356
357 field_type = bt_ctf_field_get_type(field);
358 if (!field_type) {
359 fprintf(err, "[error] %s in %s:%d\n", __func__,
360 __FILE__, __LINE__);
361 goto error;
362 }
363
364 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
365 fprintf(err, "[error] %s in %s:%d\n", __func__,
366 __FILE__, __LINE__);
367 goto error;
368 }
369 BT_PUT(field_type);
370
371 seq_len = bt_ctf_field_sequence_get_length(field);
372 if (!seq_len) {
373 fprintf(err, "[error] %s in %s:%d\n", __func__,
374 __FILE__, __LINE__);
375 goto error;
376 }
377
378 ret = bt_ctf_field_unsigned_integer_get_value(seq_len, build_id_len);
379 if (ret) {
380 fprintf(err, "[error] %s in %s:%d\n", __func__,
381 __FILE__, __LINE__);
382 goto error;
383 }
384 BT_PUT(seq_len);
385
386 *build_id = g_new0(uint8_t, *build_id_len);
387 if (!*build_id) {
388 fprintf(err, "[error] %s in %s:%d\n", __func__,
389 __FILE__, __LINE__);
390 goto error;
391 }
392
393 for (i = 0; i < *build_id_len; i++) {
394 uint64_t tmp;
395
396 seq_field = bt_ctf_field_sequence_get_field(field, i);
397 if (!seq_field) {
398 fprintf(err, "[error] %s in %s:%d\n", __func__,
399 __FILE__, __LINE__);
400 goto error;
401 }
402
403 ret = bt_ctf_field_unsigned_integer_get_value(seq_field, &tmp);
404 if (ret) {
405 fprintf(err, "[error] %s in %s:%d\n", __func__,
406 __FILE__, __LINE__);
407 goto error;
408 }
409 BT_PUT(seq_field);
410 (*build_id)[i] = (uint8_t) tmp;
411 }
412 ret = 0;
413 goto end;
414
415 error:
416 g_free(*build_id);
417 ret = -1;
418 end:
419 bt_put(field_type);
420 bt_put(field);
421 return ret;
422 }
423
424 static
425 struct debug_info *lookup_trace_debug_info(struct debug_info_iterator *debug_it,
426 struct bt_ctf_trace *writer_trace)
427 {
428 return (struct debug_info *) g_hash_table_lookup(
429 debug_it->trace_debug_map,
430 (gpointer) writer_trace);
431 }
432
433 static
434 struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it,
435 struct bt_ctf_trace *writer_trace)
436 {
437 struct debug_info *debug_info = NULL;
438 struct bt_value *field = NULL;
439 const char *str_value;
440 enum bt_value_status ret;
441
442 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
443 "domain");
444 /* No domain field, no debug info */
445 if (!field) {
446 goto end;
447 }
448 ret = bt_value_string_get(field, &str_value);
449 if (ret != BT_VALUE_STATUS_OK) {
450 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
451 __FILE__, __LINE__);
452 goto end;
453 }
454 /* Domain not ust, no debug info */
455 if (strcmp(str_value, "ust") != 0) {
456 goto end;
457 }
458 BT_PUT(field);
459
460 /* No tracer_name, no debug info */
461 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
462 "tracer_name");
463 /* No tracer_name, no debug info */
464 if (!field) {
465 goto end;
466 }
467 ret = bt_value_string_get(field, &str_value);
468 if (ret != BT_VALUE_STATUS_OK) {
469 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
470 __FILE__, __LINE__);
471 goto end;
472 }
473 /* Tracer_name not lttng-ust, no debug info */
474 if (strcmp(str_value, "lttng-ust") != 0) {
475 goto end;
476 }
477 BT_PUT(field);
478
479 debug_info = debug_info_create(debug_it->debug_info_component);
480 if (!debug_info) {
481 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
482 __FILE__, __LINE__);
483 goto end;
484 }
485
486 g_hash_table_insert(debug_it->trace_debug_map, (gpointer) writer_trace,
487 debug_info);
488
489 end:
490 bt_put(field);
491 return debug_info;
492 }
493
494 static
495 struct debug_info *get_trace_debug_info(struct debug_info_iterator *debug_it,
496 struct bt_ctf_trace *writer_trace)
497 {
498 struct debug_info *debug_info;
499
500 debug_info = lookup_trace_debug_info(debug_it, writer_trace);
501 if (debug_info) {
502 goto end;
503 }
504
505 debug_info = insert_new_debug_info(debug_it, writer_trace);
506
507 end:
508 return debug_info;
509 }
510
511 static
512 struct bt_ctf_trace *lookup_trace(struct debug_info_iterator *debug_it,
513 struct bt_ctf_trace *trace)
514 {
515 return (struct bt_ctf_trace *) g_hash_table_lookup(
516 debug_it->trace_map,
517 (gpointer) trace);
518 }
519
520 static
521 struct bt_ctf_trace *insert_new_trace(struct debug_info_iterator *debug_it,
522 struct bt_ctf_trace *trace) {
523 struct bt_ctf_trace *writer_trace = NULL;
524 int ret;
525
526 writer_trace = bt_ctf_trace_create();
527 if (!writer_trace) {
528 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
529 __FILE__, __LINE__);
530 goto error;
531 }
532 g_hash_table_insert(debug_it->trace_map, (gpointer) trace, writer_trace);
533
534 ret = ctf_copy_trace(debug_it->err, trace, writer_trace);
535 if (ret != BT_COMPONENT_STATUS_OK) {
536 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
537 __FILE__, __LINE__);
538 goto error;
539 }
540
541 goto end;
542
543 error:
544 BT_PUT(writer_trace);
545 end:
546 return writer_trace;
547 }
548
549 static
550 struct bt_ctf_packet *lookup_packet(struct debug_info_iterator *debug_it,
551 struct bt_ctf_packet *packet)
552 {
553 return (struct bt_ctf_packet *) g_hash_table_lookup(
554 debug_it->packet_map,
555 (gpointer) packet);
556 }
557
558 static
559 struct bt_ctf_packet *insert_new_packet(struct debug_info_iterator *debug_it,
560 struct bt_ctf_packet *packet,
561 struct bt_ctf_stream *writer_stream)
562 {
563 struct bt_ctf_packet *writer_packet;
564
565 writer_packet = bt_ctf_packet_create(writer_stream);
566 if (!writer_packet) {
567 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
568 __FILE__, __LINE__);
569 goto end;
570 }
571 g_hash_table_insert(debug_it->packet_map, (gpointer) packet, writer_packet);
572
573 end:
574 return writer_packet;
575 }
576
577 static
578 int add_debug_info_fields(FILE *err,
579 struct bt_ctf_field_type *writer_event_context_type,
580 struct debug_info_component *component)
581 {
582 struct bt_ctf_field_type *ip_field = NULL, *debug_field_type = NULL,
583 *bin_field_type = NULL, *func_field_type = NULL,
584 *src_field_type = NULL;
585 int ret = 0;
586
587 ip_field = bt_ctf_field_type_structure_get_field_type_by_name(
588 writer_event_context_type, "_ip");
589 /* No ip field, so no debug info. */
590 if (!ip_field) {
591 goto end;
592 }
593 BT_PUT(ip_field);
594
595 debug_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
596 writer_event_context_type,
597 component->arg_debug_info_field_name);
598 /* Already existing debug_info field, no need to add it. */
599 if (debug_field_type) {
600 goto end;
601 }
602
603 debug_field_type = bt_ctf_field_type_structure_create();
604 if (!debug_field_type) {
605 fprintf(err, "[error] %s in %s:%d\n", __func__,
606 __FILE__, __LINE__);
607 goto error;
608 }
609
610 bin_field_type = bt_ctf_field_type_string_create();
611 if (!bin_field_type) {
612 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
613 __LINE__);
614 goto error;
615 }
616
617 func_field_type = bt_ctf_field_type_string_create();
618 if (!func_field_type) {
619 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
620 __LINE__);
621 goto error;
622 }
623
624 src_field_type = bt_ctf_field_type_string_create();
625 if (!src_field_type) {
626 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
627 __LINE__);
628 goto error;
629 }
630
631 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
632 bin_field_type, "bin");
633 if (ret) {
634 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
635 __LINE__);
636 goto error;
637 }
638
639 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
640 func_field_type, "func");
641 if (ret) {
642 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
643 __LINE__);
644 goto error;
645 }
646
647 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
648 src_field_type, "src");
649 if (ret) {
650 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
651 __LINE__);
652 goto error;
653 }
654
655 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
656 debug_field_type, component->arg_debug_info_field_name);
657 if (ret) {
658 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
659 __LINE__);
660 goto error;
661 }
662
663 ret = 0;
664 goto end;
665
666 error:
667 BT_PUT(debug_field_type);
668 ret = -1;
669 end:
670 bt_put(src_field_type);
671 bt_put(func_field_type);
672 bt_put(bin_field_type);
673 bt_put(debug_field_type);
674 return ret;
675 }
676
677 static
678 int create_debug_info_event_context_type(FILE *err,
679 struct bt_ctf_field_type *event_context_type,
680 struct bt_ctf_field_type *writer_event_context_type,
681 struct debug_info_component *component)
682 {
683 int ret, nr_fields, i;
684
685 nr_fields = bt_ctf_field_type_structure_get_field_count(event_context_type);
686 for (i = 0; i < nr_fields; i++) {
687 struct bt_ctf_field_type *field_type = NULL;
688 const char *field_name;
689
690 if (bt_ctf_field_type_structure_get_field(event_context_type,
691 &field_name, &field_type, i) < 0) {
692 fprintf(err, "[error] %s in %s:%d\n", __func__,
693 __FILE__, __LINE__);
694 goto error;
695 }
696
697 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
698 field_type, field_name);
699 BT_PUT(field_type);
700 if (ret) {
701 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
702 __LINE__);
703 goto error;
704 }
705 }
706
707 ret = add_debug_info_fields(err, writer_event_context_type,
708 component);
709 goto end;
710
711 error:
712 ret = -1;
713 end:
714 return ret;
715 }
716
717 static
718 struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err,
719 struct bt_ctf_stream_class *stream_class,
720 struct bt_ctf_trace *writer_trace,
721 struct debug_info_component *component)
722 {
723 struct bt_ctf_field_type *type = NULL;
724 struct bt_ctf_stream_class *writer_stream_class = NULL;
725 struct bt_ctf_field_type *writer_event_context_type = NULL;
726 int ret_int;
727 const char *name = bt_ctf_stream_class_get_name(stream_class);
728
729 if (strlen(name) == 0) {
730 name = NULL;
731 }
732
733 writer_stream_class = bt_ctf_stream_class_create(name);
734 if (!writer_stream_class) {
735 fprintf(err, "[error] %s in %s:%d\n",
736 __func__, __FILE__, __LINE__);
737 goto error;
738 }
739
740 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
741 if (!type) {
742 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
743 __LINE__);
744 goto error;
745 }
746
747 ret_int = bt_ctf_stream_class_set_packet_context_type(
748 writer_stream_class, type);
749 if (ret_int < 0) {
750 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
751 __LINE__);
752 goto error;
753 }
754 BT_PUT(type);
755
756 type = bt_ctf_stream_class_get_event_header_type(stream_class);
757 if (!type) {
758 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
759 __LINE__);
760 goto error;
761 }
762
763 ret_int = bt_ctf_stream_class_set_event_header_type(
764 writer_stream_class, type);
765 if (ret_int < 0) {
766 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
767 __LINE__);
768 goto error;
769 }
770 BT_PUT(type);
771
772 type = bt_ctf_stream_class_get_event_context_type(stream_class);
773 if (type) {
774 writer_event_context_type = bt_ctf_field_type_structure_create();
775 if (!writer_event_context_type) {
776 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
777 __LINE__);
778 goto error;
779 }
780 ret_int = create_debug_info_event_context_type(err, type,
781 writer_event_context_type, component);
782 if (ret_int) {
783 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
784 __LINE__);
785 goto error;
786 }
787 BT_PUT(type);
788
789 ret_int = bt_ctf_stream_class_set_event_context_type(
790 writer_stream_class, writer_event_context_type);
791 if (ret_int < 0) {
792 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
793 __LINE__);
794 goto error;
795 }
796 BT_PUT(writer_event_context_type);
797 }
798
799 goto end;
800
801 error:
802 BT_PUT(writer_stream_class);
803 end:
804 bt_put(writer_event_context_type);
805 bt_put(type);
806 return writer_stream_class;
807 }
808
809 /*
810 * Add the original clock classes to the new trace, we do not need to copy
811 * them, and if we did, we would have to manually inspect the stream class
812 * to update the integers mapping to a clock.
813 */
814 static
815 int add_clock_classes(FILE *err, struct bt_ctf_trace *writer_trace,
816 struct bt_ctf_stream_class *writer_stream_class,
817 struct bt_ctf_trace *trace)
818 {
819 int ret, clock_class_count, i;
820
821 clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
822
823 for (i = 0; i < clock_class_count; i++) {
824 struct bt_ctf_clock_class *clock_class =
825 bt_ctf_trace_get_clock_class_by_index(trace, i);
826
827 if (!clock_class) {
828 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
829 __LINE__);
830 goto error;
831 }
832
833 ret = bt_ctf_trace_add_clock_class(writer_trace, clock_class);
834 BT_PUT(clock_class);
835 if (ret != 0) {
836 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
837 __LINE__);
838 goto error;
839 }
840 }
841
842 ret = 0;
843 goto end;
844
845 error:
846 ret = -1;
847 end:
848 return ret;
849
850 }
851
852 static
853 struct bt_ctf_stream_class *insert_new_stream_class(
854 struct debug_info_iterator *debug_it,
855 struct bt_ctf_stream_class *stream_class)
856 {
857 struct bt_ctf_stream_class *writer_stream_class = NULL;
858 struct bt_ctf_trace *trace, *writer_trace = NULL;
859 enum bt_component_status ret;
860 int int_ret;
861
862 trace = bt_ctf_stream_class_get_trace(stream_class);
863 if (!trace) {
864 fprintf(debug_it->err,
865 "[error] %s in %s:%d\n", __func__, __FILE__,
866 __LINE__);
867 goto error;
868 }
869
870 writer_trace = lookup_trace(debug_it, trace);
871 if (!writer_trace) {
872 writer_trace = insert_new_trace(debug_it, trace);
873 if (!writer_trace) {
874 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
875 __FILE__, __LINE__);
876 ret = BT_COMPONENT_STATUS_ERROR;
877 goto error;
878 }
879 }
880 bt_get(writer_trace);
881
882 writer_stream_class = copy_stream_class_debug_info(debug_it->err, stream_class,
883 writer_trace, debug_it->debug_info_component);
884 if (!writer_stream_class) {
885 fprintf(debug_it->err, "[error] Failed to copy stream class\n");
886 fprintf(debug_it->err, "[error] %s in %s:%d\n",
887 __func__, __FILE__, __LINE__);
888 goto error;
889 }
890
891 int_ret = bt_ctf_trace_add_stream_class(writer_trace, writer_stream_class);
892 if (int_ret) {
893 fprintf(debug_it->err,
894 "[error] %s in %s:%d\n", __func__, __FILE__,
895 __LINE__);
896 goto error;
897 }
898
899 ret = add_clock_classes(debug_it->err, writer_trace,
900 writer_stream_class, trace);
901 if (ret != BT_COMPONENT_STATUS_OK) {
902 fprintf(debug_it->err,
903 "[error] %s in %s:%d\n", __func__, __FILE__,
904 __LINE__);
905 goto error;
906 }
907 BT_PUT(writer_trace);
908 BT_PUT(trace);
909
910 g_hash_table_insert(debug_it->stream_class_map,
911 (gpointer) stream_class, writer_stream_class);
912
913 goto end;
914
915 error:
916 BT_PUT(writer_stream_class);
917 end:
918 bt_put(trace);
919 bt_put(writer_trace);
920 return writer_stream_class;
921 }
922
923 static
924 struct bt_ctf_stream *insert_new_stream(
925 struct debug_info_iterator *debug_it,
926 struct bt_ctf_stream_class *stream_class,
927 struct bt_ctf_stream *stream)
928 {
929 struct bt_ctf_stream *writer_stream = NULL;
930 struct bt_ctf_stream_class *writer_stream_class = NULL;
931
932 writer_stream_class = g_hash_table_lookup(
933 debug_it->stream_class_map,
934 (gpointer) stream_class);
935
936 if (!writer_stream_class) {
937 writer_stream_class = insert_new_stream_class(debug_it,
938 stream_class);
939 if (!writer_stream_class) {
940 fprintf(debug_it->err, "[error] %s in %s:%d\n",
941 __func__, __FILE__, __LINE__);
942 goto error;
943 }
944 }
945 bt_get(writer_stream_class);
946
947 writer_stream = bt_ctf_stream_create(writer_stream_class,
948 bt_ctf_stream_get_name(stream));
949 if (!writer_stream) {
950 fprintf(debug_it->err, "[error] %s in %s:%d\n",
951 __func__, __FILE__, __LINE__);
952 goto error;
953 }
954
955 g_hash_table_insert(debug_it->stream_map, (gpointer) stream,
956 writer_stream);
957
958 goto end;
959
960 error:
961 BT_PUT(writer_stream);
962 end:
963 bt_put(writer_stream_class);
964 return writer_stream;
965 }
966
967 static
968 struct bt_ctf_stream *lookup_stream(struct debug_info_iterator *debug_it,
969 struct bt_ctf_stream *stream)
970 {
971 return (struct bt_ctf_stream *) g_hash_table_lookup(
972 debug_it->stream_map,
973 (gpointer) stream);
974 }
975
976 static
977 struct bt_ctf_event_class *get_event_class(struct debug_info_iterator *debug_it,
978 struct bt_ctf_stream_class *writer_stream_class,
979 struct bt_ctf_event_class *event_class)
980 {
981 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
982 bt_ctf_event_class_get_id(event_class));
983 }
984
985 static
986 struct bt_ctf_stream *get_writer_stream(
987 struct debug_info_iterator *debug_it,
988 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
989 {
990 struct bt_ctf_stream_class *stream_class = NULL;
991 struct bt_ctf_stream *writer_stream = NULL;
992
993 stream_class = bt_ctf_stream_get_class(stream);
994 if (!stream_class) {
995 fprintf(debug_it->err, "[error] %s in %s:%d\n",
996 __func__, __FILE__, __LINE__);
997 goto error;
998 }
999
1000 writer_stream = lookup_stream(debug_it, stream);
1001 if (!writer_stream) {
1002 writer_stream = insert_new_stream(debug_it, stream_class, stream);
1003 }
1004 bt_get(writer_stream);
1005
1006 goto end;
1007
1008 error:
1009 BT_PUT(writer_stream);
1010 end:
1011 bt_put(stream_class);
1012 return writer_stream;
1013 }
1014
1015 BT_HIDDEN
1016 struct bt_ctf_packet *debug_info_new_packet(
1017 struct debug_info_iterator *debug_it,
1018 struct bt_ctf_packet *packet)
1019 {
1020 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
1021 struct bt_ctf_field *writer_packet_context = NULL;
1022 struct bt_ctf_packet *writer_packet = NULL;
1023 int int_ret;
1024
1025 stream = bt_ctf_packet_get_stream(packet);
1026 if (!stream) {
1027 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1028 __func__, __FILE__, __LINE__);
1029 goto error;
1030 }
1031
1032 writer_stream = get_writer_stream(debug_it, packet, stream);
1033 if (!writer_stream) {
1034 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1035 __func__, __FILE__, __LINE__);
1036 goto error;
1037 }
1038
1039 /*
1040 * If a packet was already opened, close it and remove it from
1041 * the HT.
1042 */
1043 writer_packet = lookup_packet(debug_it, packet);
1044 if (writer_packet) {
1045 g_hash_table_remove(debug_it->packet_map, packet);
1046 BT_PUT(writer_packet);
1047 }
1048
1049 writer_packet = insert_new_packet(debug_it, packet, writer_stream);
1050 if (!writer_packet) {
1051 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1052 __func__, __FILE__, __LINE__);
1053 goto error;
1054 }
1055
1056 writer_packet_context = ctf_copy_packet_context(debug_it->err, packet,
1057 writer_stream, 0);
1058 if (!writer_packet_context) {
1059 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1060 __func__, __FILE__, __LINE__);
1061 goto error;
1062 }
1063
1064 int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context);
1065 if (int_ret) {
1066 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1067 __func__, __FILE__, __LINE__);
1068 goto error;
1069 }
1070 goto end;
1071
1072 error:
1073
1074 end:
1075 bt_put(writer_packet_context);
1076 bt_put(writer_stream);
1077 bt_put(stream);
1078 return writer_packet;
1079 }
1080
1081 BT_HIDDEN
1082 struct bt_ctf_packet *debug_info_close_packet(
1083 struct debug_info_iterator *debug_it,
1084 struct bt_ctf_packet *packet)
1085 {
1086 struct bt_ctf_packet *writer_packet = NULL;
1087
1088 writer_packet = lookup_packet(debug_it, packet);
1089 if (!writer_packet) {
1090 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1091 __func__, __FILE__, __LINE__);
1092 goto end;
1093 }
1094 g_hash_table_remove(debug_it->packet_map, packet);
1095
1096 end:
1097 return writer_packet;
1098 }
1099
1100 BT_HIDDEN
1101 struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it,
1102 struct bt_ctf_stream *stream)
1103 {
1104 struct bt_ctf_stream *writer_stream;
1105
1106 writer_stream = lookup_stream(debug_it, stream);
1107 if (!writer_stream) {
1108 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1109 __func__, __FILE__, __LINE__);
1110 goto end;
1111 }
1112 bt_get(writer_stream);
1113 g_hash_table_remove(debug_it->stream_map, stream);
1114
1115 end:
1116 return writer_stream;
1117 }
1118
1119 static
1120 struct debug_info_source *lookup_debug_info(FILE *err,
1121 struct bt_ctf_event *event,
1122 struct debug_info *debug_info)
1123 {
1124 int64_t vpid;
1125 uint64_t ip;
1126 struct debug_info_source *dbg_info_src = NULL;
1127 int ret;
1128
1129 ret = get_stream_event_context_int_field_value(err, event,
1130 "_vpid", &vpid);
1131 if (ret) {
1132 goto end;
1133 }
1134
1135 ret = get_stream_event_context_unsigned_int_field_value(err, event,
1136 "_ip", &ip);
1137 if (ret) {
1138 goto end;
1139 }
1140
1141 /* Get debug info for this context. */
1142 dbg_info_src = debug_info_query(debug_info, vpid, ip);
1143
1144 end:
1145 return dbg_info_src;
1146 }
1147
1148 static
1149 int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field,
1150 struct debug_info_source *dbg_info_src,
1151 struct debug_info_component *component)
1152 {
1153 int i, nr_fields, ret = 0;
1154 struct bt_ctf_field_type *debug_field_type = NULL;
1155 struct bt_ctf_field *field = NULL;
1156 struct bt_ctf_field_type *field_type = NULL;
1157
1158 debug_field_type = bt_ctf_field_get_type(debug_field);
1159 if (!debug_field_type) {
1160 fprintf(err, "[error] %s in %s:%d\n", __func__,
1161 __FILE__, __LINE__);
1162 goto error;
1163 }
1164
1165 nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type);
1166 for (i = 0; i < nr_fields; i++) {
1167 const char *field_name;
1168
1169 if (bt_ctf_field_type_structure_get_field(debug_field_type,
1170 &field_name, &field_type, i) < 0) {
1171 fprintf(err, "[error] %s in %s:%d\n", __func__,
1172 __FILE__, __LINE__);
1173 goto error;
1174 }
1175 BT_PUT(field_type);
1176
1177 field = bt_ctf_field_structure_get_field_by_index(debug_field, i);
1178 if (!strcmp(field_name, "bin")) {
1179 if (dbg_info_src && dbg_info_src->bin_path) {
1180 GString *tmp = g_string_new(NULL);
1181
1182 if (component->arg_full_path) {
1183 g_string_printf(tmp, "%s%s",
1184 dbg_info_src->bin_path,
1185 dbg_info_src->bin_loc);
1186 } else {
1187 g_string_printf(tmp, "%s%s",
1188 dbg_info_src->short_bin_path,
1189 dbg_info_src->bin_loc);
1190 }
1191 ret = bt_ctf_field_string_set_value(field, tmp->str);
1192 g_string_free(tmp, true);
1193 } else {
1194 ret = bt_ctf_field_string_set_value(field, "");
1195 }
1196 } else if (!strcmp(field_name, "func")) {
1197 if (dbg_info_src && dbg_info_src->func) {
1198 ret = bt_ctf_field_string_set_value(field,
1199 dbg_info_src->func);
1200 } else {
1201 ret = bt_ctf_field_string_set_value(field, "");
1202 }
1203 } else if (!strcmp(field_name, "src")) {
1204 if (dbg_info_src && dbg_info_src->src_path) {
1205 GString *tmp = g_string_new(NULL);
1206
1207 if (component->arg_full_path) {
1208 g_string_printf(tmp, "%s:%" PRId64,
1209 dbg_info_src->src_path,
1210 dbg_info_src->line_no);
1211 } else {
1212 g_string_printf(tmp, "%s:%" PRId64,
1213 dbg_info_src->short_src_path,
1214 dbg_info_src->line_no);
1215 }
1216 ret = bt_ctf_field_string_set_value(field, tmp->str);
1217 g_string_free(tmp, true);
1218 } else {
1219 ret = bt_ctf_field_string_set_value(field, "");
1220 }
1221 }
1222 BT_PUT(field);
1223 if (ret) {
1224 fprintf(err, "[error] %s in %s:%d\n", __func__,
1225 __FILE__, __LINE__);
1226 goto error;
1227 }
1228 }
1229 ret = 0;
1230 goto end;
1231
1232 error:
1233 ret = -1;
1234 end:
1235 bt_put(field_type);
1236 bt_put(field);
1237 bt_put(debug_field_type);
1238 return ret;
1239 }
1240
1241 static
1242 int copy_set_debug_info_stream_event_context(FILE *err,
1243 struct bt_ctf_field *event_context,
1244 struct bt_ctf_event *event,
1245 struct bt_ctf_event *writer_event,
1246 struct debug_info *debug_info,
1247 struct debug_info_component *component)
1248 {
1249 struct bt_ctf_field_type *writer_event_context_type = NULL,
1250 *event_context_type = NULL;
1251 struct bt_ctf_field *writer_event_context = NULL;
1252 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1253 struct bt_ctf_field_type *field_type = NULL;
1254 struct debug_info_source *dbg_info_src;
1255 int ret, nr_fields, i;
1256
1257 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1258 if (!writer_event_context) {
1259 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1260 goto error;
1261 }
1262
1263 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1264 if (!writer_event_context_type) {
1265 fprintf(err, "[error] %s in %s:%d\n", __func__,
1266 __FILE__, __LINE__);
1267 goto error;
1268 }
1269
1270 event_context_type = bt_ctf_field_get_type(event_context);
1271 if (!event_context_type) {
1272 fprintf(err, "[error] %s in %s:%d\n", __func__,
1273 __FILE__, __LINE__);
1274 goto error;
1275 }
1276
1277 /*
1278 * If it is not a structure, we did not modify it to add the debug info
1279 * fields, so just assign it as is.
1280 */
1281 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
1282 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1283 goto end;
1284 }
1285
1286 dbg_info_src = lookup_debug_info(err, event, debug_info);
1287
1288 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1289 for (i = 0; i < nr_fields; i++) {
1290 const char *field_name;
1291
1292 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1293 &field_name, &field_type, i) < 0) {
1294 fprintf(err, "[error] %s in %s:%d\n", __func__,
1295 __FILE__, __LINE__);
1296 goto error;
1297 }
1298
1299 /*
1300 * Prevent illegal access in the event_context.
1301 */
1302 if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) {
1303 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1304 }
1305 /*
1306 * The debug_info field, only exists in the writer event or
1307 * if it was set by a earlier pass of the debug_info plugin.
1308 */
1309 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1310 !field) {
1311 debug_field = bt_ctf_field_structure_get_field_by_index(
1312 writer_event_context, i);
1313 if (!debug_field) {
1314 fprintf(err, "[error] %s in %s:%d\n", __func__,
1315 __FILE__, __LINE__);
1316 goto error;
1317 }
1318 ret = set_debug_info_field(err, debug_field,
1319 dbg_info_src, component);
1320 if (ret) {
1321 fprintf(err, "[error] %s in %s:%d\n", __func__,
1322 __FILE__, __LINE__);
1323 goto error;
1324 }
1325 BT_PUT(debug_field);
1326 } else {
1327 copy_field = bt_ctf_field_copy(field);
1328 if (!copy_field) {
1329 fprintf(err, "[error] %s in %s:%d\n", __func__,
1330 __FILE__, __LINE__);
1331 goto error;
1332 }
1333
1334 ret = bt_ctf_field_structure_set_field(writer_event_context,
1335 field_name, copy_field);
1336 if (ret) {
1337 fprintf(err, "[error] %s in %s:%d\n", __func__,
1338 __FILE__, __LINE__);
1339 goto error;
1340 }
1341 BT_PUT(copy_field);
1342 }
1343 BT_PUT(field_type);
1344 BT_PUT(field);
1345 }
1346
1347 ret = 0;
1348 goto end;
1349
1350 error:
1351 ret = -1;
1352 end:
1353 bt_put(event_context_type);
1354 bt_put(writer_event_context_type);
1355 bt_put(writer_event_context);
1356 bt_put(field);
1357 bt_put(copy_field);
1358 bt_put(debug_field);
1359 bt_put(field_type);
1360 return ret;
1361 }
1362
1363 static
1364 struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1365 struct bt_ctf_stream_class *stream_class)
1366 {
1367 struct bt_ctf_trace *trace = NULL;
1368 struct bt_ctf_clock_class *clock_class = NULL;
1369
1370 trace = bt_ctf_stream_class_get_trace(stream_class);
1371 if (!trace) {
1372 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1373 __LINE__);
1374 goto end;
1375 }
1376
1377 /* FIXME multi-clock? */
1378 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
1379
1380 bt_put(trace);
1381
1382 end:
1383 return clock_class;
1384 }
1385
1386 static
1387 struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1388 {
1389 struct bt_ctf_event_class *event_class = NULL;
1390 struct bt_ctf_stream_class *stream_class = NULL;
1391 struct bt_ctf_clock_class *clock_class = NULL;
1392
1393 event_class = bt_ctf_event_get_class(event);
1394 if (!event_class) {
1395 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1396 __LINE__);
1397 goto error;
1398 }
1399
1400 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1401 if (!stream_class) {
1402 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1403 __LINE__);
1404 goto error;
1405 }
1406
1407 clock_class = stream_class_get_clock_class(err, stream_class);
1408 goto end;
1409
1410 error:
1411 BT_PUT(clock_class);
1412 end:
1413 bt_put(stream_class);
1414 bt_put(event_class);
1415 return clock_class;
1416 }
1417
1418 static
1419 int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1420 struct bt_ctf_event *writer_event)
1421 {
1422 struct bt_ctf_clock_class *clock_class = NULL;
1423 struct bt_ctf_clock_value *clock_value = NULL;
1424 int ret;
1425
1426 clock_class = event_get_clock_class(err, event);
1427 if (!clock_class) {
1428 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1429 __LINE__);
1430 goto error;
1431 }
1432
1433 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1434 if (!clock_value) {
1435 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1436 __LINE__);
1437 goto error;
1438 }
1439
1440 /*
1441 * We share the same clocks, so we can assign the clock value to the
1442 * writer event.
1443 */
1444 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1445 if (ret) {
1446 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1447 __LINE__);
1448 goto error;
1449 }
1450
1451 ret = 0;
1452 goto end;
1453
1454 error:
1455 ret = -1;
1456 end:
1457 bt_put(clock_class);
1458 bt_put(clock_value);
1459 return ret;
1460 }
1461
1462 static
1463 struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1464 struct bt_ctf_event_class *writer_event_class,
1465 struct debug_info *debug_info,
1466 struct debug_info_component *component)
1467 {
1468 struct bt_ctf_event *writer_event = NULL;
1469 struct bt_ctf_field *field = NULL, *copy_field = NULL;
1470 int ret;
1471
1472 writer_event = bt_ctf_event_create(writer_event_class);
1473 if (!writer_event) {
1474 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1475 __LINE__);
1476 goto error;
1477 }
1478
1479 ret = set_event_clock_value(err, event, writer_event);
1480 if (ret) {
1481 fprintf(err, "[error] %s in %s:%d\n", __func__,
1482 __FILE__, __LINE__);
1483 goto error;
1484 }
1485
1486 /* Optional field, so it can fail silently. */
1487 field = bt_ctf_event_get_header(event);
1488 if (field) {
1489 ret = ctf_copy_event_header(err, event, writer_event_class,
1490 writer_event, field);
1491 if (ret) {
1492 fprintf(err, "[error] %s in %s:%d\n", __func__,
1493 __FILE__, __LINE__);
1494 goto error;
1495 }
1496 BT_PUT(field);
1497 }
1498
1499 /* Optional field, so it can fail silently. */
1500 field = bt_ctf_event_get_stream_event_context(event);
1501 if (field) {
1502 ret = copy_set_debug_info_stream_event_context(err,
1503 field, event, writer_event, debug_info,
1504 component);
1505 if (ret < 0) {
1506 fprintf(err, "[error] %s in %s:%d\n", __func__,
1507 __FILE__, __LINE__);
1508 goto error;
1509 }
1510 BT_PUT(field);
1511 }
1512
1513 /* Optional field, so it can fail silently. */
1514 field = bt_ctf_event_get_event_context(event);
1515 if (field) {
1516 copy_field = bt_ctf_field_copy(field);
1517 if (!copy_field) {
1518 fprintf(err, "[error] %s in %s:%d\n", __func__,
1519 __FILE__, __LINE__);
1520 goto error;
1521 }
1522 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
1523 if (ret < 0) {
1524 fprintf(err, "[error] %s in %s:%d\n", __func__,
1525 __FILE__, __LINE__);
1526 goto error;
1527 }
1528 BT_PUT(copy_field);
1529 BT_PUT(field);
1530 }
1531
1532 field = bt_ctf_event_get_event_payload(event);
1533 if (!field) {
1534 fprintf(err, "[error] %s in %s:%d\n", __func__,
1535 __FILE__, __LINE__);
1536 goto error;
1537 }
1538 copy_field = bt_ctf_field_copy(field);
1539 if (copy_field) {
1540 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
1541 if (ret < 0) {
1542 fprintf(err, "[error] %s in %s:%d\n", __func__,
1543 __FILE__, __LINE__);
1544 goto error;
1545 }
1546 BT_PUT(copy_field);
1547 }
1548 BT_PUT(field);
1549
1550 goto end;
1551
1552 error:
1553 BT_PUT(writer_event);
1554 end:
1555 bt_put(copy_field);
1556 bt_put(field);
1557 return writer_event;
1558 }
1559
1560 BT_HIDDEN
1561 struct bt_ctf_event *debug_info_output_event(
1562 struct debug_info_iterator *debug_it,
1563 struct bt_ctf_event *event)
1564 {
1565 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
1566 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
1567 struct bt_ctf_event *writer_event = NULL;
1568 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
1569 struct bt_ctf_trace *writer_trace = NULL;
1570 struct debug_info *debug_info;
1571 const char *event_name;
1572 int int_ret;
1573
1574 event_class = bt_ctf_event_get_class(event);
1575 if (!event_class) {
1576 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1577 __FILE__, __LINE__);
1578 goto error;
1579 }
1580
1581 event_name = bt_ctf_event_class_get_name(event_class);
1582 if (!event_name) {
1583 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1584 __FILE__, __LINE__);
1585 goto error;
1586 }
1587
1588 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1589 if (!stream_class) {
1590 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1591 __FILE__, __LINE__);
1592 goto error;
1593 }
1594
1595 writer_stream_class = g_hash_table_lookup(
1596 debug_it->stream_class_map,
1597 (gpointer) stream_class);
1598 if (!writer_stream_class || !bt_get(writer_stream_class)) {
1599 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1600 __FILE__, __LINE__);
1601 goto error;
1602 }
1603
1604 writer_event_class = get_event_class(debug_it,
1605 writer_stream_class, event_class);
1606 if (!writer_event_class) {
1607 writer_event_class = ctf_copy_event_class(debug_it->err,
1608 event_class);
1609 if (!writer_event_class) {
1610 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1611 __func__, __FILE__, __LINE__);
1612 goto error;
1613 }
1614 int_ret = bt_ctf_stream_class_add_event_class(
1615 writer_stream_class, writer_event_class);
1616 if (int_ret) {
1617 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1618 __func__, __FILE__, __LINE__);
1619 goto error;
1620 }
1621 }
1622
1623 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
1624 if (!writer_trace) {
1625 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1626 __FILE__, __LINE__);
1627 goto error;
1628 }
1629
1630 debug_info = get_trace_debug_info(debug_it, writer_trace);
1631 if (debug_info) {
1632 debug_info_handle_event(debug_it->err, event, debug_info);
1633 }
1634
1635 writer_event = debug_info_copy_event(debug_it->err, event,
1636 writer_event_class, debug_info,
1637 debug_it->debug_info_component);
1638 if (!writer_event) {
1639 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1640 __FILE__, __LINE__);
1641 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
1642 bt_ctf_event_class_get_name(writer_event_class));
1643 goto error;
1644 }
1645
1646 packet = bt_ctf_event_get_packet(event);
1647 if (!packet) {
1648 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1649 __FILE__, __LINE__);
1650 goto error;
1651 }
1652
1653 writer_packet = lookup_packet(debug_it, packet);
1654 if (!writer_packet) {
1655 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1656 __FILE__, __LINE__);
1657 goto error;
1658 }
1659 bt_get(writer_packet);
1660
1661 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
1662 if (int_ret < 0) {
1663 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1664 __FILE__, __LINE__);
1665 fprintf(debug_it->err, "[error] Failed to append event %s\n",
1666 bt_ctf_event_class_get_name(writer_event_class));
1667 goto error;
1668 }
1669
1670 /* Keep the reference on the writer event */
1671 goto end;
1672
1673 error:
1674 BT_PUT(writer_event);
1675
1676 end:
1677 bt_put(writer_trace);
1678 bt_put(writer_packet);
1679 bt_put(packet);
1680 bt_put(writer_event_class);
1681 bt_put(writer_stream_class);
1682 bt_put(stream_class);
1683 bt_put(event_class);
1684 return writer_event;
1685 }
This page took 0.101316 seconds and 4 git commands to generate.