debug_info fix: useless reference
[babeltrace.git] / plugins / lttng-utils / copy.c
CommitLineData
4f45f9bb
JD
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
43static
44struct 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
1487a16a 64 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
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
72end:
73 bt_put(sec_type);
74 bt_put(sec);
75 return field;
76}
77
78static
79struct 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
1487a16a 99 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
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
107end:
108 bt_put(sec_type);
109 bt_put(sec);
110 return field;
111}
112
113BT_HIDDEN
114int 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
1487a16a 136 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
151error:
152 ret = -1;
153end:
154 bt_put(field_type);
155 bt_put(field);
156 return ret;
157}
158
159BT_HIDDEN
160int 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
1487a16a 179 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
194error:
195 ret = -1;
196end:
197 bt_put(field_type);
198 bt_put(field);
199 return ret;
200}
201
202BT_HIDDEN
203int 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
1487a16a 225 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
240error:
241 ret = -1;
242end:
243 bt_put(field_type);
244 bt_put(field);
245 return ret;
246}
247
248BT_HIDDEN
249int 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
1487a16a 270 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
285error:
286 ret = -1;
287end:
288 bt_put(field_type);
289 bt_put(field);
290 return ret;
291}
292
293BT_HIDDEN
294int 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
1487a16a 316 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) {
4f45f9bb
JD
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
332error:
333 ret = -1;
334end:
335 bt_put(field_type);
336 bt_put(field);
337 return ret;
338}
339
340BT_HIDDEN
341int 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
1487a16a 367 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
4f45f9bb
JD
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
418error:
419 g_free(*build_id);
420 ret = -1;
421end:
422 bt_put(field_type);
423 bt_put(field);
424 return ret;
425}
426
427static
428struct 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
436static
437struct 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
9d325e17 482 debug_info = debug_info_create(debug_it->debug_info_component);
4f45f9bb
JD
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
492end:
493 bt_put(field);
494 return debug_info;
495}
496
497static
498struct 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
510end:
511 return debug_info;
512}
513
514static
515struct 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
523static
524struct 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
546error:
547 BT_PUT(writer_trace);
548end:
549 return writer_trace;
550}
551
552static
553struct 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
561static
562struct 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
576end:
577 return writer_packet;
578}
579
580static
581int 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
669error:
670 BT_PUT(debug_field_type);
671 ret = -1;
672end:
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
680static
681int 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
714error:
715 ret = -1;
716end:
717 return ret;
718}
719
720static
721struct 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
804error:
805 BT_PUT(writer_stream_class);
806end:
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 */
817static
818int 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 =
9ac68eb1 828 bt_ctf_trace_get_clock_class_by_index(trace, i);
4f45f9bb
JD
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
848error:
849 ret = -1;
850end:
851 return ret;
852
853}
854
855static
856struct 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
918error:
919 BT_PUT(writer_stream_class);
920end:
921 bt_put(trace);
922 bt_put(writer_trace);
923 return writer_stream_class;
924}
925
926static
927struct 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
963error:
964 BT_PUT(writer_stream);
965end:
966 bt_put(writer_stream_class);
967 return writer_stream;
968}
969
970static
971struct 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
979static
980struct 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{
a9f0d01b
PP
984 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
985 bt_ctf_event_class_get_id(event_class));
4f45f9bb
JD
986}
987
988static
989struct 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
1011error:
1012 BT_PUT(writer_stream);
1013end:
1014 bt_put(stream_class);
1015 return writer_stream;
1016}
1017
1018BT_HIDDEN
1019struct 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 }
4f45f9bb
JD
1058
1059 writer_packet_context = ctf_copy_packet_context(debug_it->err, packet,
ab80adac 1060 writer_stream, 0);
4f45f9bb
JD
1061 if (!writer_packet_context) {
1062 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1063 __func__, __FILE__, __LINE__);
1064 goto error;
1065 }
1066
1067 int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context);
1068 if (int_ret) {
1069 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1070 __func__, __FILE__, __LINE__);
1071 goto error;
1072 }
1073 goto end;
1074
1075error:
1076
1077end:
1078 bt_put(writer_packet_context);
1079 bt_put(writer_stream);
1080 bt_put(stream);
1081 return writer_packet;
1082}
1083
1084BT_HIDDEN
1085struct bt_ctf_packet *debug_info_close_packet(
1086 struct debug_info_iterator *debug_it,
1087 struct bt_ctf_packet *packet)
1088{
1089 struct bt_ctf_packet *writer_packet = NULL;
1090
1091 writer_packet = lookup_packet(debug_it, packet);
1092 if (!writer_packet) {
1093 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1094 __func__, __FILE__, __LINE__);
1095 goto end;
1096 }
1097 g_hash_table_remove(debug_it->packet_map, packet);
1098
1099end:
1100 return writer_packet;
1101}
1102
1103BT_HIDDEN
1104struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it,
1105 struct bt_ctf_stream *stream)
1106{
1107 struct bt_ctf_stream *writer_stream;
1108
1109 writer_stream = lookup_stream(debug_it, stream);
1110 if (!writer_stream) {
1111 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1112 __func__, __FILE__, __LINE__);
1113 goto end;
1114 }
1115 g_hash_table_remove(debug_it->stream_map, stream);
1116
1117end:
1118 return writer_stream;
1119}
1120
1121static
1122struct debug_info_source *lookup_debug_info(FILE *err,
1123 struct bt_ctf_event *event,
1124 struct debug_info *debug_info)
1125{
1126 int64_t vpid;
1127 uint64_t ip;
1128 struct debug_info_source *dbg_info_src = NULL;
1129 int ret;
1130
1131 ret = get_stream_event_context_int_field_value(err, event,
1132 "_vpid", &vpid);
1133 if (ret) {
1134 goto end;
1135 }
1136
1137 ret = get_stream_event_context_unsigned_int_field_value(err, event,
1138 "_ip", &ip);
1139 if (ret) {
1140 goto end;
1141 }
1142
1143 /* Get debug info for this context. */
1144 dbg_info_src = debug_info_query(debug_info, vpid, ip);
1145
1146end:
1147 return dbg_info_src;
1148}
1149
1150static
1151int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field,
1152 struct debug_info_source *dbg_info_src,
1153 struct debug_info_component *component)
1154{
1155 int i, nr_fields, ret;
1156 struct bt_ctf_field_type *debug_field_type = NULL;
1157 struct bt_ctf_field *field = NULL;
1158 struct bt_ctf_field_type *field_type = NULL;
1159
1160 debug_field_type = bt_ctf_field_get_type(debug_field);
1161 if (!debug_field_type) {
1162 fprintf(err, "[error] %s in %s:%d\n", __func__,
1163 __FILE__, __LINE__);
1164 goto error;
1165 }
1166
1167 nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type);
1168 for (i = 0; i < nr_fields; i++) {
1169 const char *field_name;
1170
1171 if (bt_ctf_field_type_structure_get_field(debug_field_type,
1172 &field_name, &field_type, i) < 0) {
1173 fprintf(err, "[error] %s in %s:%d\n", __func__,
1174 __FILE__, __LINE__);
1175 goto error;
1176 }
1177 BT_PUT(field_type);
1178
1179 field = bt_ctf_field_structure_get_field_by_index(debug_field, i);
1180 if (!strcmp(field_name, "bin")) {
1181 if (dbg_info_src && dbg_info_src->bin_path) {
1182 GString *tmp = g_string_new(NULL);
1183
1184 if (component->arg_full_path) {
1185 g_string_printf(tmp, "%s%s",
1186 dbg_info_src->bin_path,
1187 dbg_info_src->bin_loc);
1188 } else {
1189 g_string_printf(tmp, "%s%s",
1190 dbg_info_src->short_bin_path,
1191 dbg_info_src->bin_loc);
1192 }
1193 ret = bt_ctf_field_string_set_value(field, tmp->str);
1194 g_string_free(tmp, true);
1195 } else {
1196 ret = bt_ctf_field_string_set_value(field, "");
1197 }
1198 } else if (!strcmp(field_name, "func")) {
1199 if (dbg_info_src && dbg_info_src->func) {
1200 ret = bt_ctf_field_string_set_value(field,
1201 dbg_info_src->func);
1202 } else {
1203 ret = bt_ctf_field_string_set_value(field, "");
1204 }
1205 } else if (!strcmp(field_name, "src")) {
1206 if (dbg_info_src && dbg_info_src->src_path) {
1207 GString *tmp = g_string_new(NULL);
1208
1209 if (component->arg_full_path) {
1210 g_string_printf(tmp, "%s:%" PRId64,
1211 dbg_info_src->src_path,
1212 dbg_info_src->line_no);
1213 } else {
1214 g_string_printf(tmp, "%s:%" PRId64,
1215 dbg_info_src->short_src_path,
1216 dbg_info_src->line_no);
1217 }
1218 ret = bt_ctf_field_string_set_value(field, tmp->str);
1219 g_string_free(tmp, true);
1220 } else {
1221 ret = bt_ctf_field_string_set_value(field, "");
1222 }
1223 }
1224 BT_PUT(field);
1225 if (ret) {
1226 fprintf(err, "[error] %s in %s:%d\n", __func__,
1227 __FILE__, __LINE__);
1228 goto error;
1229 }
1230 }
1231 ret = 0;
1232 goto end;
1233
1234error:
1235 ret = -1;
1236end:
1237 bt_put(field_type);
1238 bt_put(field);
1239 bt_put(debug_field_type);
1240 return ret;
1241}
1242
1243static
1244int copy_set_debug_info_stream_event_context(FILE *err,
1245 struct bt_ctf_field *event_context,
1246 struct bt_ctf_event *event,
1247 struct bt_ctf_event *writer_event,
1248 struct debug_info *debug_info,
1249 struct debug_info_component *component)
1250{
1251 struct bt_ctf_field_type *writer_event_context_type = NULL;
1252 struct bt_ctf_field *writer_event_context = NULL;
1253 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1254 struct bt_ctf_field_type *field_type = NULL;
1255 struct debug_info_source *dbg_info_src;
1256 int ret, nr_fields, i;
1257
1258 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1259 if (!writer_event_context) {
1260 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1261 goto error;
1262 }
1263
1264 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1265 if (!writer_event_context_type) {
1266 fprintf(err, "[error] %s in %s:%d\n", __func__,
1267 __FILE__, __LINE__);
1268 goto error;
1269 }
1270
1271 /*
1272 * If it is not a structure, we did not modify it to add the debug info
1273 * fields, so just assign it as is.
1274 */
1487a16a 1275 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
1276 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1277 goto end;
1278 }
1279
1280 dbg_info_src = lookup_debug_info(err, event, debug_info);
1281
1282 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1283 for (i = 0; i < nr_fields; i++) {
1284 const char *field_name;
1285
1286 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1287 &field_name, &field_type, i) < 0) {
1288 fprintf(err, "[error] %s in %s:%d\n", __func__,
1289 __FILE__, __LINE__);
1290 goto error;
1291 }
1292
1293 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1294 /*
1295 * The debug_info field, only exists in the writer event or
1296 * if it was set by a earlier pass of the debug_info plugin.
1297 *
1298 * FIXME: are we replacing an exisiting debug_info struct here ??
1299 */
1300 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1301 !field) {
1302 debug_field = bt_ctf_field_structure_get_field_by_index(
1303 writer_event_context, i);
1304 if (!debug_field) {
1305 fprintf(err, "[error] %s in %s:%d\n", __func__,
1306 __FILE__, __LINE__);
1307 goto error;
1308 }
1309 ret = set_debug_info_field(err, debug_field,
1310 dbg_info_src, component);
1311 if (ret) {
1312 fprintf(err, "[error] %s in %s:%d\n", __func__,
1313 __FILE__, __LINE__);
1314 goto error;
1315 }
1316 BT_PUT(debug_field);
1317 } else {
1318 copy_field = bt_ctf_field_copy(field);
1319 if (!copy_field) {
1320 fprintf(err, "[error] %s in %s:%d\n", __func__,
1321 __FILE__, __LINE__);
1322 goto error;
1323 }
1324
1325 ret = bt_ctf_field_structure_set_field(writer_event_context,
1326 field_name, copy_field);
1327 if (ret) {
1328 fprintf(err, "[error] %s in %s:%d\n", __func__,
1329 __FILE__, __LINE__);
1330 goto error;
1331 }
1332 BT_PUT(copy_field);
1333 }
1334 BT_PUT(field_type);
1335 BT_PUT(field);
1336 }
1337
1338 ret = 0;
1339 goto end;
1340
1341error:
1342 ret = -1;
1343end:
1344 bt_put(writer_event_context_type);
1345 bt_put(writer_event_context);
1346 bt_put(field);
1347 bt_put(copy_field);
1348 bt_put(debug_field);
1349 bt_put(field_type);
1350 return ret;
1351}
1352
1353static
1354struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1355 struct bt_ctf_stream_class *stream_class)
1356{
1357 struct bt_ctf_trace *trace = NULL;
1358 struct bt_ctf_clock_class *clock_class = NULL;
1359
1360 trace = bt_ctf_stream_class_get_trace(stream_class);
1361 if (!trace) {
1362 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1363 __LINE__);
1364 goto end;
1365 }
1366
1367 /* FIXME multi-clock? */
9ac68eb1 1368 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
4f45f9bb
JD
1369
1370 bt_put(trace);
1371
1372end:
1373 return clock_class;
1374}
1375
1376static
1377struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1378{
1379 struct bt_ctf_event_class *event_class = NULL;
1380 struct bt_ctf_stream_class *stream_class = NULL;
1381 struct bt_ctf_clock_class *clock_class = NULL;
1382
1383 event_class = bt_ctf_event_get_class(event);
1384 if (!event_class) {
1385 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1386 __LINE__);
1387 goto error;
1388 }
1389
1390 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1391 if (!stream_class) {
1392 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1393 __LINE__);
1394 goto error;
1395 }
1396
1397 clock_class = stream_class_get_clock_class(err, stream_class);
1398 goto end;
1399
1400error:
1401 BT_PUT(clock_class);
1402end:
1403 bt_put(stream_class);
1404 bt_put(event_class);
1405 return clock_class;
1406}
1407
1408static
1409int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1410 struct bt_ctf_event *writer_event)
1411{
1412 struct bt_ctf_clock_class *clock_class = NULL;
1413 struct bt_ctf_clock_value *clock_value = NULL;
1414 int ret;
1415
1416 clock_class = event_get_clock_class(err, event);
1417 if (!clock_class) {
1418 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1419 __LINE__);
1420 goto error;
1421 }
1422
1423 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1424 if (!clock_value) {
1425 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1426 __LINE__);
1427 goto error;
1428 }
1429
1430 /*
1431 * We share the same clocks, so we can assign the clock value to the
1432 * writer event.
1433 */
1434 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1435 if (ret) {
1436 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1437 __LINE__);
1438 goto error;
1439 }
1440
1441 ret = 0;
1442 goto end;
1443
1444error:
1445 ret = -1;
1446end:
1447 bt_put(clock_class);
1448 bt_put(clock_value);
1449 return ret;
1450}
1451
1452static
1453struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1454 struct bt_ctf_event_class *writer_event_class,
1455 struct debug_info *debug_info,
1456 struct debug_info_component *component)
1457{
1458 struct bt_ctf_event *writer_event = NULL;
f6f999a3 1459 struct bt_ctf_field *field = NULL, *copy_field = NULL;
4f45f9bb
JD
1460 int ret;
1461
1462 writer_event = bt_ctf_event_create(writer_event_class);
1463 if (!writer_event) {
1464 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1465 __LINE__);
1466 goto error;
1467 }
1468
1469 ret = set_event_clock_value(err, event, writer_event);
1470 if (ret) {
1471 fprintf(err, "[error] %s in %s:%d\n", __func__,
1472 __FILE__, __LINE__);
1473 goto error;
1474 }
1475
60ef553b 1476 /* Optional field, so it can fail silently. */
4f45f9bb 1477 field = bt_ctf_event_get_header(event);
60ef553b
JD
1478 if (field) {
1479 ret = ctf_copy_event_header(err, event, writer_event_class,
1480 writer_event, field);
1481 if (ret) {
1482 fprintf(err, "[error] %s in %s:%d\n", __func__,
1483 __FILE__, __LINE__);
1484 goto error;
1485 }
1486 BT_PUT(field);
4f45f9bb 1487 }
4f45f9bb
JD
1488
1489 /* Optional field, so it can fail silently. */
1490 field = bt_ctf_event_get_stream_event_context(event);
1491 if (field) {
1492 ret = copy_set_debug_info_stream_event_context(err,
1493 field, event, writer_event, debug_info,
1494 component);
1495 if (ret < 0) {
1496 fprintf(err, "[error] %s in %s:%d\n", __func__,
1497 __FILE__, __LINE__);
1498 goto error;
1499 }
1500 BT_PUT(field);
1501 }
1502
1503 /* Optional field, so it can fail silently. */
1504 field = bt_ctf_event_get_event_context(event);
60ef553b
JD
1505 if (field) {
1506 copy_field = bt_ctf_field_copy(field);
1507 if (!copy_field) {
1508 fprintf(err, "[error] %s in %s:%d\n", __func__,
1509 __FILE__, __LINE__);
1510 goto error;
1511 }
4f45f9bb
JD
1512 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
1513 if (ret < 0) {
1514 fprintf(err, "[error] %s in %s:%d\n", __func__,
1515 __FILE__, __LINE__);
1516 goto error;
1517 }
1518 BT_PUT(copy_field);
60ef553b 1519 BT_PUT(field);
4f45f9bb 1520 }
4f45f9bb 1521
9ac68eb1 1522 field = bt_ctf_event_get_event_payload(event);
4f45f9bb
JD
1523 if (!field) {
1524 fprintf(err, "[error] %s in %s:%d\n", __func__,
1525 __FILE__, __LINE__);
1526 goto error;
1527 }
1528 copy_field = bt_ctf_field_copy(field);
1529 if (copy_field) {
9ac68eb1 1530 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
4f45f9bb
JD
1531 if (ret < 0) {
1532 fprintf(err, "[error] %s in %s:%d\n", __func__,
1533 __FILE__, __LINE__);
1534 goto error;
1535 }
1536 BT_PUT(copy_field);
1537 }
1538 BT_PUT(field);
1539
1540 goto end;
1541
1542error:
1543 BT_PUT(writer_event);
1544end:
1545 bt_put(copy_field);
1546 bt_put(field);
1547 return writer_event;
1548}
1549
1550BT_HIDDEN
1551struct bt_ctf_event *debug_info_output_event(
1552 struct debug_info_iterator *debug_it,
1553 struct bt_ctf_event *event)
1554{
1555 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
1556 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
1557 struct bt_ctf_event *writer_event = NULL;
f6f999a3 1558 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
4f45f9bb
JD
1559 struct bt_ctf_trace *writer_trace = NULL;
1560 struct debug_info *debug_info;
1561 const char *event_name;
1562 int int_ret;
1563
1564 event_class = bt_ctf_event_get_class(event);
1565 if (!event_class) {
1566 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1567 __FILE__, __LINE__);
1568 goto error;
1569 }
1570
1571 event_name = bt_ctf_event_class_get_name(event_class);
1572 if (!event_name) {
1573 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1574 __FILE__, __LINE__);
1575 goto error;
1576 }
1577
1578 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1579 if (!stream_class) {
1580 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1581 __FILE__, __LINE__);
1582 goto error;
1583 }
1584
1585 writer_stream_class = g_hash_table_lookup(
1586 debug_it->stream_class_map,
1587 (gpointer) stream_class);
1588 if (!writer_stream_class || !bt_get(writer_stream_class)) {
1589 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1590 __FILE__, __LINE__);
1591 goto error;
1592 }
1593
1594 writer_event_class = get_event_class(debug_it,
1595 writer_stream_class, event_class);
1596 if (!writer_event_class) {
1597 writer_event_class = ctf_copy_event_class(debug_it->err,
1598 event_class);
1599 if (!writer_event_class) {
1600 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1601 __func__, __FILE__, __LINE__);
1602 goto error;
1603 }
1604 int_ret = bt_ctf_stream_class_add_event_class(
1605 writer_stream_class, writer_event_class);
1606 if (int_ret) {
1607 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1608 __func__, __FILE__, __LINE__);
1609 goto error;
1610 }
1611 }
1612
1613 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
1614 if (!writer_trace) {
1615 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1616 __FILE__, __LINE__);
1617 goto error;
1618 }
1619
1620 debug_info = get_trace_debug_info(debug_it, writer_trace);
1621 if (debug_info) {
1622 debug_info_handle_event(debug_it->err, event, debug_info);
1623 }
1624
1625 writer_event = debug_info_copy_event(debug_it->err, event,
1626 writer_event_class, debug_info,
1627 debug_it->debug_info_component);
1628 if (!writer_event) {
1629 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1630 __FILE__, __LINE__);
1631 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
1632 bt_ctf_event_class_get_name(writer_event_class));
1633 goto error;
1634 }
1635
1636 packet = bt_ctf_event_get_packet(event);
1637 if (!packet) {
1638 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1639 __FILE__, __LINE__);
1640 goto error;
1641 }
1642
1643 writer_packet = lookup_packet(debug_it, packet);
1644 if (!writer_packet) {
1645 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1646 __FILE__, __LINE__);
1647 goto error;
1648 }
1649 bt_get(writer_packet);
1650
1651 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
1652 if (int_ret < 0) {
1653 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1654 __FILE__, __LINE__);
1655 fprintf(debug_it->err, "[error] Failed to append event %s\n",
1656 bt_ctf_event_class_get_name(writer_event_class));
1657 goto error;
1658 }
1659
1660 /* Keep the reference on the writer event */
1661 goto end;
1662
1663error:
1664 BT_PUT(writer_event);
1665
1666end:
1667 bt_put(writer_trace);
1668 bt_put(writer_packet);
1669 bt_put(packet);
1670 bt_put(writer_event_class);
1671 bt_put(writer_stream_class);
1672 bt_put(stream_class);
1673 bt_put(event_class);
1674 return writer_event;
1675}
This page took 0.08636 seconds and 4 git commands to generate.