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