Fix debug-info: prevent invalid access in the original event_context
[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) {
4f45f9bb
JD
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
1487a16a 97 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
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
105end:
106 bt_put(sec_type);
107 bt_put(sec);
108 return field;
109}
110
111BT_HIDDEN
112int 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) {
4f45f9bb
JD
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
1487a16a 132 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
147error:
148 ret = -1;
149end:
150 bt_put(field_type);
151 bt_put(field);
152 return ret;
153}
154
155BT_HIDDEN
156int 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
1487a16a 175 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
190error:
191 ret = -1;
192end:
193 bt_put(field_type);
194 bt_put(field);
195 return ret;
196}
197
198BT_HIDDEN
199int 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
1487a16a 221 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
236error:
237 ret = -1;
238end:
239 bt_put(field_type);
240 bt_put(field);
241 return ret;
242}
243
244BT_HIDDEN
245int 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
1487a16a 266 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
4f45f9bb
JD
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
281error:
282 ret = -1;
283end:
284 bt_put(field_type);
285 bt_put(field);
286 return ret;
287}
288
289BT_HIDDEN
290int 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
1487a16a 312 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) {
4f45f9bb
JD
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
328error:
329 ret = -1;
330end:
331 bt_put(field_type);
332 bt_put(field);
333 return ret;
334}
335
336BT_HIDDEN
337int 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
1487a16a 363 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
4f45f9bb
JD
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
414error:
415 g_free(*build_id);
416 ret = -1;
417end:
418 bt_put(field_type);
419 bt_put(field);
420 return ret;
421}
422
423static
424struct 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
432static
433struct 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
9d325e17 478 debug_info = debug_info_create(debug_it->debug_info_component);
4f45f9bb
JD
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
488end:
489 bt_put(field);
490 return debug_info;
491}
492
493static
494struct 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
506end:
507 return debug_info;
508}
509
510static
511struct 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
519static
520struct 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
542error:
543 BT_PUT(writer_trace);
544end:
545 return writer_trace;
546}
547
548static
549struct 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
557static
558struct 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
572end:
573 return writer_packet;
574}
575
576static
577int 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
665error:
666 BT_PUT(debug_field_type);
667 ret = -1;
668end:
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
676static
677int 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
710error:
711 ret = -1;
712end:
713 return ret;
714}
715
716static
717struct 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
800error:
801 BT_PUT(writer_stream_class);
802end:
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 */
813static
814int 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 =
9ac68eb1 824 bt_ctf_trace_get_clock_class_by_index(trace, i);
4f45f9bb
JD
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
844error:
845 ret = -1;
846end:
847 return ret;
848
849}
850
851static
852struct 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
914error:
915 BT_PUT(writer_stream_class);
916end:
917 bt_put(trace);
918 bt_put(writer_trace);
919 return writer_stream_class;
920}
921
922static
923struct 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
959error:
960 BT_PUT(writer_stream);
961end:
962 bt_put(writer_stream_class);
963 return writer_stream;
964}
965
966static
967struct 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
975static
976struct 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{
a9f0d01b
PP
980 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
981 bt_ctf_event_class_get_id(event_class));
4f45f9bb
JD
982}
983
984static
985struct 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
1007error:
1008 BT_PUT(writer_stream);
1009end:
1010 bt_put(stream_class);
1011 return writer_stream;
1012}
1013
1014BT_HIDDEN
1015struct 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 }
4f45f9bb
JD
1054
1055 writer_packet_context = ctf_copy_packet_context(debug_it->err, packet,
ab80adac 1056 writer_stream, 0);
4f45f9bb
JD
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
1071error:
1072
1073end:
1074 bt_put(writer_packet_context);
1075 bt_put(writer_stream);
1076 bt_put(stream);
1077 return writer_packet;
1078}
1079
1080BT_HIDDEN
1081struct 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
1095end:
1096 return writer_packet;
1097}
1098
1099BT_HIDDEN
1100struct 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 }
34101229 1111 bt_get(writer_stream);
4f45f9bb
JD
1112 g_hash_table_remove(debug_it->stream_map, stream);
1113
1114end:
1115 return writer_stream;
1116}
1117
1118static
1119struct 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
1143end:
1144 return dbg_info_src;
1145}
1146
1147static
1148int 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{
2afcfbfb 1152 int i, nr_fields, ret = 0;
4f45f9bb
JD
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
1231error:
1232 ret = -1;
1233end:
1234 bt_put(field_type);
1235 bt_put(field);
1236 bt_put(debug_field_type);
1237 return ret;
1238}
1239
1240static
1241int 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{
08b6e8e8
JD
1248 struct bt_ctf_field_type *writer_event_context_type = NULL,
1249 *event_context_type = NULL;
4f45f9bb
JD
1250 struct bt_ctf_field *writer_event_context = NULL;
1251 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1252 struct bt_ctf_field_type *field_type = NULL;
1253 struct debug_info_source *dbg_info_src;
1254 int ret, nr_fields, i;
1255
1256 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1257 if (!writer_event_context) {
1258 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1259 goto error;
1260 }
1261
1262 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1263 if (!writer_event_context_type) {
1264 fprintf(err, "[error] %s in %s:%d\n", __func__,
1265 __FILE__, __LINE__);
1266 goto error;
1267 }
1268
08b6e8e8
JD
1269 event_context_type = bt_ctf_field_get_type(event_context);
1270 if (!event_context_type) {
1271 fprintf(err, "[error] %s in %s:%d\n", __func__,
1272 __FILE__, __LINE__);
1273 goto error;
1274 }
1275
4f45f9bb
JD
1276 /*
1277 * If it is not a structure, we did not modify it to add the debug info
1278 * fields, so just assign it as is.
1279 */
1487a16a 1280 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
4f45f9bb
JD
1281 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1282 goto end;
1283 }
1284
1285 dbg_info_src = lookup_debug_info(err, event, debug_info);
1286
1287 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1288 for (i = 0; i < nr_fields; i++) {
1289 const char *field_name;
1290
1291 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1292 &field_name, &field_type, i) < 0) {
1293 fprintf(err, "[error] %s in %s:%d\n", __func__,
1294 __FILE__, __LINE__);
1295 goto error;
1296 }
1297
08b6e8e8
JD
1298 /*
1299 * Prevent illegal access in the event_context.
1300 */
1301 if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) {
1302 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1303 }
4f45f9bb
JD
1304 /*
1305 * The debug_info field, only exists in the writer event or
1306 * if it was set by a earlier pass of the debug_info plugin.
4f45f9bb
JD
1307 */
1308 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1309 !field) {
1310 debug_field = bt_ctf_field_structure_get_field_by_index(
1311 writer_event_context, i);
1312 if (!debug_field) {
1313 fprintf(err, "[error] %s in %s:%d\n", __func__,
1314 __FILE__, __LINE__);
1315 goto error;
1316 }
1317 ret = set_debug_info_field(err, debug_field,
1318 dbg_info_src, component);
1319 if (ret) {
1320 fprintf(err, "[error] %s in %s:%d\n", __func__,
1321 __FILE__, __LINE__);
1322 goto error;
1323 }
1324 BT_PUT(debug_field);
1325 } else {
1326 copy_field = bt_ctf_field_copy(field);
1327 if (!copy_field) {
1328 fprintf(err, "[error] %s in %s:%d\n", __func__,
1329 __FILE__, __LINE__);
1330 goto error;
1331 }
1332
1333 ret = bt_ctf_field_structure_set_field(writer_event_context,
1334 field_name, copy_field);
1335 if (ret) {
1336 fprintf(err, "[error] %s in %s:%d\n", __func__,
1337 __FILE__, __LINE__);
1338 goto error;
1339 }
1340 BT_PUT(copy_field);
1341 }
1342 BT_PUT(field_type);
1343 BT_PUT(field);
1344 }
1345
1346 ret = 0;
1347 goto end;
1348
1349error:
1350 ret = -1;
1351end:
08b6e8e8 1352 bt_put(event_context_type);
4f45f9bb
JD
1353 bt_put(writer_event_context_type);
1354 bt_put(writer_event_context);
1355 bt_put(field);
1356 bt_put(copy_field);
1357 bt_put(debug_field);
1358 bt_put(field_type);
1359 return ret;
1360}
1361
1362static
1363struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1364 struct bt_ctf_stream_class *stream_class)
1365{
1366 struct bt_ctf_trace *trace = NULL;
1367 struct bt_ctf_clock_class *clock_class = NULL;
1368
1369 trace = bt_ctf_stream_class_get_trace(stream_class);
1370 if (!trace) {
1371 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1372 __LINE__);
1373 goto end;
1374 }
1375
1376 /* FIXME multi-clock? */
9ac68eb1 1377 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
4f45f9bb
JD
1378
1379 bt_put(trace);
1380
1381end:
1382 return clock_class;
1383}
1384
1385static
1386struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1387{
1388 struct bt_ctf_event_class *event_class = NULL;
1389 struct bt_ctf_stream_class *stream_class = NULL;
1390 struct bt_ctf_clock_class *clock_class = NULL;
1391
1392 event_class = bt_ctf_event_get_class(event);
1393 if (!event_class) {
1394 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1395 __LINE__);
1396 goto error;
1397 }
1398
1399 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1400 if (!stream_class) {
1401 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1402 __LINE__);
1403 goto error;
1404 }
1405
1406 clock_class = stream_class_get_clock_class(err, stream_class);
1407 goto end;
1408
1409error:
1410 BT_PUT(clock_class);
1411end:
1412 bt_put(stream_class);
1413 bt_put(event_class);
1414 return clock_class;
1415}
1416
1417static
1418int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1419 struct bt_ctf_event *writer_event)
1420{
1421 struct bt_ctf_clock_class *clock_class = NULL;
1422 struct bt_ctf_clock_value *clock_value = NULL;
1423 int ret;
1424
1425 clock_class = event_get_clock_class(err, event);
1426 if (!clock_class) {
1427 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1428 __LINE__);
1429 goto error;
1430 }
1431
1432 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1433 if (!clock_value) {
1434 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1435 __LINE__);
1436 goto error;
1437 }
1438
1439 /*
1440 * We share the same clocks, so we can assign the clock value to the
1441 * writer event.
1442 */
1443 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1444 if (ret) {
1445 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1446 __LINE__);
1447 goto error;
1448 }
1449
1450 ret = 0;
1451 goto end;
1452
1453error:
1454 ret = -1;
1455end:
1456 bt_put(clock_class);
1457 bt_put(clock_value);
1458 return ret;
1459}
1460
1461static
1462struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1463 struct bt_ctf_event_class *writer_event_class,
1464 struct debug_info *debug_info,
1465 struct debug_info_component *component)
1466{
1467 struct bt_ctf_event *writer_event = NULL;
f6f999a3 1468 struct bt_ctf_field *field = NULL, *copy_field = NULL;
4f45f9bb
JD
1469 int ret;
1470
1471 writer_event = bt_ctf_event_create(writer_event_class);
1472 if (!writer_event) {
1473 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1474 __LINE__);
1475 goto error;
1476 }
1477
1478 ret = set_event_clock_value(err, event, writer_event);
1479 if (ret) {
1480 fprintf(err, "[error] %s in %s:%d\n", __func__,
1481 __FILE__, __LINE__);
1482 goto error;
1483 }
1484
60ef553b 1485 /* Optional field, so it can fail silently. */
4f45f9bb 1486 field = bt_ctf_event_get_header(event);
60ef553b
JD
1487 if (field) {
1488 ret = ctf_copy_event_header(err, event, writer_event_class,
1489 writer_event, field);
1490 if (ret) {
1491 fprintf(err, "[error] %s in %s:%d\n", __func__,
1492 __FILE__, __LINE__);
1493 goto error;
1494 }
1495 BT_PUT(field);
4f45f9bb 1496 }
4f45f9bb
JD
1497
1498 /* Optional field, so it can fail silently. */
1499 field = bt_ctf_event_get_stream_event_context(event);
1500 if (field) {
1501 ret = copy_set_debug_info_stream_event_context(err,
1502 field, event, writer_event, debug_info,
1503 component);
1504 if (ret < 0) {
1505 fprintf(err, "[error] %s in %s:%d\n", __func__,
1506 __FILE__, __LINE__);
1507 goto error;
1508 }
1509 BT_PUT(field);
1510 }
1511
1512 /* Optional field, so it can fail silently. */
1513 field = bt_ctf_event_get_event_context(event);
60ef553b
JD
1514 if (field) {
1515 copy_field = bt_ctf_field_copy(field);
1516 if (!copy_field) {
1517 fprintf(err, "[error] %s in %s:%d\n", __func__,
1518 __FILE__, __LINE__);
1519 goto error;
1520 }
4f45f9bb
JD
1521 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
1522 if (ret < 0) {
1523 fprintf(err, "[error] %s in %s:%d\n", __func__,
1524 __FILE__, __LINE__);
1525 goto error;
1526 }
1527 BT_PUT(copy_field);
60ef553b 1528 BT_PUT(field);
4f45f9bb 1529 }
4f45f9bb 1530
9ac68eb1 1531 field = bt_ctf_event_get_event_payload(event);
4f45f9bb
JD
1532 if (!field) {
1533 fprintf(err, "[error] %s in %s:%d\n", __func__,
1534 __FILE__, __LINE__);
1535 goto error;
1536 }
1537 copy_field = bt_ctf_field_copy(field);
1538 if (copy_field) {
9ac68eb1 1539 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
4f45f9bb
JD
1540 if (ret < 0) {
1541 fprintf(err, "[error] %s in %s:%d\n", __func__,
1542 __FILE__, __LINE__);
1543 goto error;
1544 }
1545 BT_PUT(copy_field);
1546 }
1547 BT_PUT(field);
1548
1549 goto end;
1550
1551error:
1552 BT_PUT(writer_event);
1553end:
1554 bt_put(copy_field);
1555 bt_put(field);
1556 return writer_event;
1557}
1558
1559BT_HIDDEN
1560struct bt_ctf_event *debug_info_output_event(
1561 struct debug_info_iterator *debug_it,
1562 struct bt_ctf_event *event)
1563{
1564 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
1565 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
1566 struct bt_ctf_event *writer_event = NULL;
f6f999a3 1567 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
4f45f9bb
JD
1568 struct bt_ctf_trace *writer_trace = NULL;
1569 struct debug_info *debug_info;
1570 const char *event_name;
1571 int int_ret;
1572
1573 event_class = bt_ctf_event_get_class(event);
1574 if (!event_class) {
1575 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1576 __FILE__, __LINE__);
1577 goto error;
1578 }
1579
1580 event_name = bt_ctf_event_class_get_name(event_class);
1581 if (!event_name) {
1582 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1583 __FILE__, __LINE__);
1584 goto error;
1585 }
1586
1587 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1588 if (!stream_class) {
1589 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1590 __FILE__, __LINE__);
1591 goto error;
1592 }
1593
1594 writer_stream_class = g_hash_table_lookup(
1595 debug_it->stream_class_map,
1596 (gpointer) stream_class);
1597 if (!writer_stream_class || !bt_get(writer_stream_class)) {
1598 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1599 __FILE__, __LINE__);
1600 goto error;
1601 }
1602
1603 writer_event_class = get_event_class(debug_it,
1604 writer_stream_class, event_class);
1605 if (!writer_event_class) {
1606 writer_event_class = ctf_copy_event_class(debug_it->err,
1607 event_class);
1608 if (!writer_event_class) {
1609 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1610 __func__, __FILE__, __LINE__);
1611 goto error;
1612 }
1613 int_ret = bt_ctf_stream_class_add_event_class(
1614 writer_stream_class, writer_event_class);
1615 if (int_ret) {
1616 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1617 __func__, __FILE__, __LINE__);
1618 goto error;
1619 }
1620 }
1621
1622 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
1623 if (!writer_trace) {
1624 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1625 __FILE__, __LINE__);
1626 goto error;
1627 }
1628
1629 debug_info = get_trace_debug_info(debug_it, writer_trace);
1630 if (debug_info) {
1631 debug_info_handle_event(debug_it->err, event, debug_info);
1632 }
1633
1634 writer_event = debug_info_copy_event(debug_it->err, event,
1635 writer_event_class, debug_info,
1636 debug_it->debug_info_component);
1637 if (!writer_event) {
1638 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1639 __FILE__, __LINE__);
1640 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
1641 bt_ctf_event_class_get_name(writer_event_class));
1642 goto error;
1643 }
1644
1645 packet = bt_ctf_event_get_packet(event);
1646 if (!packet) {
1647 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1648 __FILE__, __LINE__);
1649 goto error;
1650 }
1651
1652 writer_packet = lookup_packet(debug_it, packet);
1653 if (!writer_packet) {
1654 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1655 __FILE__, __LINE__);
1656 goto error;
1657 }
1658 bt_get(writer_packet);
1659
1660 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
1661 if (int_ret < 0) {
1662 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1663 __FILE__, __LINE__);
1664 fprintf(debug_it->err, "[error] Failed to append event %s\n",
1665 bt_ctf_event_class_get_name(writer_event_class));
1666 goto error;
1667 }
1668
1669 /* Keep the reference on the writer event */
1670 goto end;
1671
1672error:
1673 BT_PUT(writer_event);
1674
1675end:
1676 bt_put(writer_trace);
1677 bt_put(writer_packet);
1678 bt_put(packet);
1679 bt_put(writer_event_class);
1680 bt_put(writer_stream_class);
1681 bt_put(stream_class);
1682 bt_put(event_class);
1683 return writer_event;
1684}
This page took 0.090181 seconds and 4 git commands to generate.