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