Fix: debug info plugin incorrect assumption about header and clock
[babeltrace.git] / plugins / lttng-utils / copy.c
1 /*
2 * copy.c
3 *
4 * Babeltrace Copy Trace Structure
5 *
6 * Copyright 2017 Julien Desfossez <jdesfossez@efficios.com>
7 *
8 * Author: Julien Desfossez <jdesfossez@efficios.com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a copy
11 * of this software and associated documentation files (the "Software"), to deal
12 * in the Software without restriction, including without limitation the rights
13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the Software is
15 * furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included in
18 * all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 * SOFTWARE.
27 */
28
29 #include <inttypes.h>
30 #include <babeltrace/ctf-ir/event.h>
31 #include <babeltrace/ctf-ir/packet.h>
32 #include <babeltrace/ctf-ir/event-class.h>
33 #include <babeltrace/ctf-ir/stream.h>
34 #include <babeltrace/ctf-ir/stream-class.h>
35 #include <babeltrace/ctf-ir/clock-class.h>
36 #include <babeltrace/ctf-ir/fields.h>
37 #include <babeltrace/ctf-writer/stream-class.h>
38 #include <babeltrace/ctf-writer/stream.h>
39
40 #include <ctfcopytrace.h>
41 #include "debug-info.h"
42
43 static
44 struct bt_ctf_stream *insert_new_stream(
45 struct debug_info_iterator *debug_it,
46 struct bt_ctf_stream *stream,
47 struct debug_info_trace *di_trace);
48
49 static
50 void unref_stream(struct bt_ctf_stream *stream)
51 {
52 bt_put(stream);
53 }
54
55 static
56 void unref_packet(struct bt_ctf_packet *packet)
57 {
58 bt_put(packet);
59 }
60
61 static
62 void unref_stream_class(struct bt_ctf_stream_class *stream_class)
63 {
64 bt_put(stream_class);
65 }
66
67 static
68 void unref_debug_info(struct debug_info *debug_info)
69 {
70 debug_info_destroy(debug_info);
71 }
72
73 static
74 void destroy_stream_state_key(gpointer key)
75 {
76 g_free((enum fs_writer_stream_state *) key);
77 }
78
79 static
80 struct bt_ctf_field *get_payload_field(FILE *err,
81 struct bt_ctf_event *event, const char *field_name)
82 {
83 struct bt_ctf_field *field = NULL, *sec = NULL;
84 struct bt_ctf_field_type *sec_type = NULL;
85
86 sec = bt_ctf_event_get_payload(event, NULL);
87 if (!sec) {
88 fprintf(err, "[error] %s in %s:%d\n", __func__,
89 __FILE__, __LINE__);
90 goto end;
91 }
92
93 sec_type = bt_ctf_field_get_type(sec);
94 if (!sec_type) {
95 fprintf(err, "[error] %s in %s:%d\n", __func__,
96 __FILE__, __LINE__);
97 goto end;
98 }
99
100 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
101 fprintf(err, "[error] %s in %s:%d\n", __func__,
102 __FILE__, __LINE__);
103 goto end;
104 }
105
106 field = bt_ctf_field_structure_get_field(sec, field_name);
107
108 end:
109 bt_put(sec_type);
110 bt_put(sec);
111 return field;
112 }
113
114 static
115 struct bt_ctf_field *get_stream_event_context_field(FILE *err,
116 struct bt_ctf_event *event, const char *field_name)
117 {
118 struct bt_ctf_field *field = NULL, *sec = NULL;
119 struct bt_ctf_field_type *sec_type = NULL;
120
121 sec = bt_ctf_event_get_stream_event_context(event);
122 if (!sec) {
123 goto end;
124 }
125
126 sec_type = bt_ctf_field_get_type(sec);
127 if (!sec_type) {
128 fprintf(err, "[error] %s in %s:%d\n", __func__,
129 __FILE__, __LINE__);
130 goto end;
131 }
132
133 if (bt_ctf_field_type_get_type_id(sec_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
134 fprintf(err, "[error] %s in %s:%d\n", __func__,
135 __FILE__, __LINE__);
136 goto end;
137 }
138
139 field = bt_ctf_field_structure_get_field(sec, field_name);
140
141 end:
142 bt_put(sec_type);
143 bt_put(sec);
144 return field;
145 }
146
147 BT_HIDDEN
148 int get_stream_event_context_unsigned_int_field_value(FILE *err,
149 struct bt_ctf_event *event, const char *field_name,
150 uint64_t *value)
151 {
152 int ret;
153 struct bt_ctf_field *field = NULL;
154 struct bt_ctf_field_type *field_type = NULL;
155
156 field = get_stream_event_context_field(err, event, field_name);
157 if (!field) {
158 goto error;
159 }
160
161 field_type = bt_ctf_field_get_type(field);
162 if (!field_type) {
163 fprintf(err, "[error] %s in %s:%d\n", __func__,
164 __FILE__, __LINE__);
165 goto error;
166 }
167
168 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
169 fprintf(err, "[error] %s in %s:%d\n", __func__,
170 __FILE__, __LINE__);
171 goto error;
172 }
173
174 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
175 fprintf(err, "[error] %s in %s:%d\n", __func__,
176 __FILE__, __LINE__);
177 goto error;
178 }
179
180 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
181 goto end;
182
183 error:
184 ret = -1;
185 end:
186 bt_put(field_type);
187 bt_put(field);
188 return ret;
189 }
190
191 BT_HIDDEN
192 int get_stream_event_context_int_field_value(FILE *err, struct bt_ctf_event *event,
193 const char *field_name, int64_t *value)
194 {
195 struct bt_ctf_field *field = NULL;
196 struct bt_ctf_field_type *field_type = NULL;
197 int ret;
198
199 field = get_stream_event_context_field(err, event, field_name);
200 if (!field) {
201 goto error;
202 }
203
204 field_type = bt_ctf_field_get_type(field);
205 if (!field_type) {
206 fprintf(err, "[error] %s in %s:%d\n", __func__,
207 __FILE__, __LINE__);
208 goto error;
209 }
210
211 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
212 fprintf(err, "[error] %s in %s:%d\n", __func__,
213 __FILE__, __LINE__);
214 goto error;
215 }
216
217 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
218 fprintf(err, "[error] %s in %s:%d\n", __func__,
219 __FILE__, __LINE__);
220 goto error;
221 }
222
223 ret = bt_ctf_field_signed_integer_get_value(field, value);
224 goto end;
225
226 error:
227 ret = -1;
228 end:
229 bt_put(field_type);
230 bt_put(field);
231 return ret;
232 }
233
234 BT_HIDDEN
235 int get_payload_unsigned_int_field_value(FILE *err,
236 struct bt_ctf_event *event, const char *field_name,
237 uint64_t *value)
238 {
239 struct bt_ctf_field *field = NULL;
240 struct bt_ctf_field_type *field_type = NULL;
241 int ret;
242
243 field = get_payload_field(err, event, field_name);
244 if (!field) {
245 fprintf(err, "[error] %s in %s:%d\n", __func__,
246 __FILE__, __LINE__);
247 goto error;
248 }
249
250 field_type = bt_ctf_field_get_type(field);
251 if (!field_type) {
252 fprintf(err, "[error] %s in %s:%d\n", __func__,
253 __FILE__, __LINE__);
254 goto error;
255 }
256
257 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
258 fprintf(err, "[error] %s in %s:%d\n", __func__,
259 __FILE__, __LINE__);
260 goto error;
261 }
262
263 if (bt_ctf_field_type_integer_get_signed(field_type) != 0) {
264 fprintf(err, "[error] %s in %s:%d\n", __func__,
265 __FILE__, __LINE__);
266 goto error;
267 }
268
269 ret = bt_ctf_field_unsigned_integer_get_value(field, value);
270 goto end;
271
272 error:
273 ret = -1;
274 end:
275 bt_put(field_type);
276 bt_put(field);
277 return ret;
278 }
279
280 BT_HIDDEN
281 int get_payload_int_field_value(FILE *err, struct bt_ctf_event *event,
282 const char *field_name, int64_t *value)
283 {
284 struct bt_ctf_field *field = NULL;
285 struct bt_ctf_field_type *field_type = NULL;
286 int ret;
287
288 field = get_payload_field(err, event, field_name);
289 if (!field) {
290 fprintf(err, "[error] %s in %s:%d\n", __func__,
291 __FILE__, __LINE__);
292 goto error;
293 }
294
295 field_type = bt_ctf_field_get_type(field);
296 if (!field_type) {
297 fprintf(err, "[error] %s in %s:%d\n", __func__,
298 __FILE__, __LINE__);
299 goto error;
300 }
301
302 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_INTEGER) {
303 fprintf(err, "[error] %s in %s:%d\n", __func__,
304 __FILE__, __LINE__);
305 goto error;
306 }
307
308 if (bt_ctf_field_type_integer_get_signed(field_type) != 1) {
309 fprintf(err, "[error] %s in %s:%d\n", __func__,
310 __FILE__, __LINE__);
311 goto error;
312 }
313
314 ret = bt_ctf_field_signed_integer_get_value(field, value);
315 goto end;
316
317 error:
318 ret = -1;
319 end:
320 bt_put(field_type);
321 bt_put(field);
322 return ret;
323 }
324
325 BT_HIDDEN
326 int get_payload_string_field_value(FILE *err,
327 struct bt_ctf_event *event, const char *field_name,
328 const char **value)
329 {
330 struct bt_ctf_field *field = NULL;
331 struct bt_ctf_field_type *field_type = NULL;
332 int ret;
333
334 /*
335 * The field might not exist, no error here.
336 */
337 field = get_payload_field(err, event, field_name);
338 if (!field) {
339 goto error;
340 }
341
342 field_type = bt_ctf_field_get_type(field);
343 if (!field_type) {
344 fprintf(err, "[error] %s in %s:%d\n", __func__,
345 __FILE__, __LINE__);
346 goto error;
347 }
348
349 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_STRING) {
350 fprintf(err, "[error] %s in %s:%d\n", __func__,
351 __FILE__, __LINE__);
352 goto error;
353 }
354
355 *value = bt_ctf_field_string_get_value(field);
356 if (!*value) {
357 fprintf(err, "[error] %s in %s:%d\n", __func__,
358 __FILE__, __LINE__);
359 goto error;
360 }
361
362 ret = 0;
363 goto end;
364
365 error:
366 ret = -1;
367 end:
368 bt_put(field_type);
369 bt_put(field);
370 return ret;
371 }
372
373 BT_HIDDEN
374 int get_payload_build_id_field_value(FILE *err,
375 struct bt_ctf_event *event, const char *field_name,
376 uint8_t **build_id, uint64_t *build_id_len)
377 {
378 struct bt_ctf_field *field = NULL, *seq_len = NULL;
379 struct bt_ctf_field_type *field_type = NULL;
380 struct bt_ctf_field *seq_field = NULL;
381 uint64_t i;
382 int ret;
383
384 *build_id = NULL;
385
386 field = get_payload_field(err, event, field_name);
387 if (!field) {
388 fprintf(err, "[error] %s in %s:%d\n", __func__,
389 __FILE__, __LINE__);
390 goto error;
391 }
392
393 field_type = bt_ctf_field_get_type(field);
394 if (!field_type) {
395 fprintf(err, "[error] %s in %s:%d\n", __func__,
396 __FILE__, __LINE__);
397 goto error;
398 }
399
400 if (bt_ctf_field_type_get_type_id(field_type) != BT_CTF_FIELD_TYPE_ID_SEQUENCE) {
401 fprintf(err, "[error] %s in %s:%d\n", __func__,
402 __FILE__, __LINE__);
403 goto error;
404 }
405 BT_PUT(field_type);
406
407 seq_len = bt_ctf_field_sequence_get_length(field);
408 if (!seq_len) {
409 fprintf(err, "[error] %s in %s:%d\n", __func__,
410 __FILE__, __LINE__);
411 goto error;
412 }
413
414 ret = bt_ctf_field_unsigned_integer_get_value(seq_len, build_id_len);
415 if (ret) {
416 fprintf(err, "[error] %s in %s:%d\n", __func__,
417 __FILE__, __LINE__);
418 goto error;
419 }
420 BT_PUT(seq_len);
421
422 *build_id = g_new0(uint8_t, *build_id_len);
423 if (!*build_id) {
424 fprintf(err, "[error] %s in %s:%d\n", __func__,
425 __FILE__, __LINE__);
426 goto error;
427 }
428
429 for (i = 0; i < *build_id_len; i++) {
430 uint64_t tmp;
431
432 seq_field = bt_ctf_field_sequence_get_field(field, i);
433 if (!seq_field) {
434 fprintf(err, "[error] %s in %s:%d\n", __func__,
435 __FILE__, __LINE__);
436 goto error;
437 }
438
439 ret = bt_ctf_field_unsigned_integer_get_value(seq_field, &tmp);
440 if (ret) {
441 fprintf(err, "[error] %s in %s:%d\n", __func__,
442 __FILE__, __LINE__);
443 goto error;
444 }
445 BT_PUT(seq_field);
446 (*build_id)[i] = (uint8_t) tmp;
447 }
448 ret = 0;
449 goto end;
450
451 error:
452 g_free(*build_id);
453 ret = -1;
454 end:
455 bt_put(field_type);
456 bt_put(field);
457 return ret;
458 }
459
460 static
461 struct debug_info *lookup_trace_debug_info(struct debug_info_iterator *debug_it,
462 struct bt_ctf_trace *writer_trace,
463 struct debug_info_trace *di_trace)
464 {
465 return (struct debug_info *) g_hash_table_lookup(
466 di_trace->trace_debug_map,
467 (gpointer) writer_trace);
468 }
469
470 static
471 struct debug_info *insert_new_debug_info(struct debug_info_iterator *debug_it,
472 struct bt_ctf_trace *writer_trace,
473 struct debug_info_trace *di_trace)
474 {
475 struct debug_info *debug_info = NULL;
476 struct bt_value *field = NULL;
477 const char *str_value;
478 enum bt_value_status ret;
479
480 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
481 "domain");
482 /* No domain field, no debug info */
483 if (!field) {
484 goto end;
485 }
486 ret = bt_value_string_get(field, &str_value);
487 if (ret != BT_VALUE_STATUS_OK) {
488 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
489 __FILE__, __LINE__);
490 goto end;
491 }
492 /* Domain not ust, no debug info */
493 if (strcmp(str_value, "ust") != 0) {
494 goto end;
495 }
496 BT_PUT(field);
497
498 /* No tracer_name, no debug info */
499 field = bt_ctf_trace_get_environment_field_value_by_name(writer_trace,
500 "tracer_name");
501 /* No tracer_name, no debug info */
502 if (!field) {
503 goto end;
504 }
505 ret = bt_value_string_get(field, &str_value);
506 if (ret != BT_VALUE_STATUS_OK) {
507 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
508 __FILE__, __LINE__);
509 goto end;
510 }
511 /* Tracer_name not lttng-ust, no debug info */
512 if (strcmp(str_value, "lttng-ust") != 0) {
513 goto end;
514 }
515 BT_PUT(field);
516
517 debug_info = debug_info_create(debug_it->debug_info_component);
518 if (!debug_info) {
519 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
520 __FILE__, __LINE__);
521 goto end;
522 }
523
524 g_hash_table_insert(di_trace->trace_debug_map, (gpointer) writer_trace,
525 debug_info);
526
527 end:
528 bt_put(field);
529 return debug_info;
530 }
531
532 static
533 struct debug_info *get_trace_debug_info(struct debug_info_iterator *debug_it,
534 struct bt_ctf_trace *writer_trace,
535 struct debug_info_trace *di_trace)
536 {
537 struct debug_info *debug_info;
538
539 debug_info = lookup_trace_debug_info(debug_it, writer_trace, di_trace);
540 if (debug_info) {
541 goto end;
542 }
543
544 debug_info = insert_new_debug_info(debug_it, writer_trace, di_trace);
545
546 end:
547 return debug_info;
548 }
549
550 static
551 struct debug_info_trace *lookup_trace(struct debug_info_iterator *debug_it,
552 struct bt_ctf_trace *trace)
553 {
554 return (struct debug_info_trace *) g_hash_table_lookup(
555 debug_it->trace_map,
556 (gpointer) trace);
557 }
558
559 static
560 enum debug_info_stream_state *insert_new_stream_state(
561 struct debug_info_iterator *debug_it,
562 struct debug_info_trace *di_trace, struct bt_ctf_stream *stream)
563 {
564 enum debug_info_stream_state *v = NULL;
565
566 v = g_new0(enum debug_info_stream_state, 1);
567 if (!v) {
568 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
569 __FILE__, __LINE__);
570 goto end;
571 }
572 *v = DEBUG_INFO_UNKNOWN_STREAM;
573
574 g_hash_table_insert(di_trace->stream_states, stream, v);
575
576 end:
577 return v;
578 }
579
580 static
581 void check_completed_trace(gpointer key, gpointer value, gpointer user_data)
582 {
583 enum debug_info_stream_state *state = value;
584 int *trace_completed = user_data;
585
586 if (*state != DEBUG_INFO_COMPLETED_STREAM) {
587 *trace_completed = 0;
588 }
589 }
590
591 static
592 gboolean empty_ht(gpointer key, gpointer value, gpointer user_data)
593 {
594 return TRUE;
595 }
596
597 BT_HIDDEN
598 void debug_info_close_trace(struct debug_info_iterator *debug_it,
599 struct debug_info_trace *di_trace)
600 {
601 if (di_trace->static_listener_id >= 0) {
602 bt_ctf_trace_remove_is_static_listener(di_trace->trace,
603 di_trace->static_listener_id);
604 }
605
606 /* Empty the stream class HT. */
607 g_hash_table_foreach_remove(di_trace->stream_class_map,
608 empty_ht, NULL);
609 g_hash_table_destroy(di_trace->stream_class_map);
610
611 /* Empty the stream HT. */
612 g_hash_table_foreach_remove(di_trace->stream_map,
613 empty_ht, NULL);
614 g_hash_table_destroy(di_trace->stream_map);
615
616 /* Empty the stream state HT. */
617 g_hash_table_foreach_remove(di_trace->stream_states,
618 empty_ht, NULL);
619 g_hash_table_destroy(di_trace->stream_states);
620
621 /* Empty the packet HT. */
622 g_hash_table_foreach_remove(di_trace->packet_map,
623 empty_ht, NULL);
624 g_hash_table_destroy(di_trace->packet_map);
625
626 /* Empty the trace_debug HT. */
627 g_hash_table_foreach_remove(di_trace->trace_debug_map,
628 empty_ht, NULL);
629 g_hash_table_destroy(di_trace->trace_debug_map);
630 }
631
632 static
633 int sync_event_classes(struct debug_info_iterator *debug_it,
634 struct bt_ctf_stream *stream,
635 struct bt_ctf_stream *writer_stream)
636 {
637 int int_ret;
638 struct bt_ctf_stream_class *stream_class = NULL,
639 *writer_stream_class = NULL;
640 enum bt_component_status ret;
641
642 stream_class = bt_ctf_stream_get_class(stream);
643 if (!stream_class) {
644 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
645 __FILE__, __LINE__);
646 goto error;
647 }
648
649 writer_stream_class = bt_ctf_stream_get_class(writer_stream);
650 if (!writer_stream_class) {
651 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
652 __FILE__, __LINE__);
653 goto error;
654 }
655
656 ret = ctf_copy_event_classes(debug_it->err, stream_class,
657 writer_stream_class);
658 if (ret != BT_COMPONENT_STATUS_OK) {
659 goto error;
660 }
661
662 int_ret = 0;
663 goto end;
664
665 error:
666 int_ret = -1;
667 end:
668 bt_put(stream_class);
669 bt_put(writer_stream_class);
670 return int_ret;
671 }
672
673 static
674 void trace_is_static_listener(struct bt_ctf_trace *trace, void *data)
675 {
676 struct debug_info_trace *di_trace = data;
677 struct debug_info_iterator *debug_it = di_trace->debug_it;
678 int trace_completed = 1, ret, nr_stream, i;
679 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
680 struct bt_ctf_trace *writer_trace = di_trace->writer_trace;
681
682 /*
683 * When the trace becomes static, make sure that we have all
684 * the event classes in our stream_class copies before setting it
685 * static as well.
686 */
687 nr_stream = bt_ctf_trace_get_stream_count(trace);
688 for (i = 0; i < nr_stream; i++) {
689 stream = bt_ctf_trace_get_stream_by_index(trace, i);
690 if (!stream) {
691 fprintf(debug_it->err,
692 "[error] %s in %s:%d\n", __func__,
693 __FILE__, __LINE__);
694 goto error;
695 }
696 writer_stream = bt_ctf_trace_get_stream_by_index(writer_trace, i);
697 if (!writer_stream) {
698 fprintf(debug_it->err,
699 "[error] %s in %s:%d\n", __func__,
700 __FILE__, __LINE__);
701 goto error;
702 }
703 ret = sync_event_classes(di_trace->debug_it, stream, writer_stream);
704 if (ret) {
705 fprintf(debug_it->err,
706 "[error] %s in %s:%d\n", __func__,
707 __FILE__, __LINE__);
708 goto error;
709 }
710 BT_PUT(stream);
711 BT_PUT(writer_stream);
712 }
713
714 bt_ctf_trace_set_is_static(di_trace->writer_trace);
715 di_trace->trace_static = 1;
716
717 g_hash_table_foreach(di_trace->stream_states,
718 check_completed_trace, &trace_completed);
719 if (trace_completed) {
720 debug_info_close_trace(di_trace->debug_it, di_trace);
721 g_hash_table_remove(di_trace->debug_it->trace_map,
722 di_trace->trace);
723 }
724
725 error:
726 bt_put(writer_stream);
727 bt_put(stream);
728 }
729
730 static
731 struct debug_info_trace *insert_new_trace(struct debug_info_iterator *debug_it,
732 struct bt_ctf_stream *stream) {
733 struct bt_ctf_trace *writer_trace = NULL;
734 struct debug_info_trace *di_trace = NULL;
735 struct bt_ctf_trace *trace = NULL;
736 struct bt_ctf_stream_class *stream_class = NULL;
737 struct bt_ctf_stream *writer_stream = NULL;
738 int ret, nr_stream, i;
739
740 writer_trace = bt_ctf_trace_create();
741 if (!writer_trace) {
742 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
743 __FILE__, __LINE__);
744 goto error;
745 }
746
747 stream_class = bt_ctf_stream_get_class(stream);
748 if (!stream_class) {
749 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
750 __FILE__, __LINE__);
751 goto error;
752 }
753
754 trace = bt_ctf_stream_class_get_trace(stream_class);
755 if (!trace) {
756 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
757 __FILE__, __LINE__);
758 goto error;
759 }
760
761 ret = ctf_copy_trace(debug_it->err, trace, writer_trace);
762 if (ret != BT_COMPONENT_STATUS_OK) {
763 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
764 __FILE__, __LINE__);
765 goto error;
766 }
767
768 di_trace = g_new0(struct debug_info_trace, 1);
769 if (!di_trace) {
770 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
771 __FILE__, __LINE__);
772 goto error;
773 }
774
775 di_trace->trace = trace;
776 di_trace->writer_trace = writer_trace;
777 di_trace->debug_info_component = debug_it->debug_info_component;
778 di_trace->debug_it = debug_it;
779 di_trace->stream_map = g_hash_table_new_full(g_direct_hash,
780 g_direct_equal, NULL, (GDestroyNotify) unref_stream);
781 di_trace->stream_class_map = g_hash_table_new_full(g_direct_hash,
782 g_direct_equal, NULL, (GDestroyNotify) unref_stream_class);
783 di_trace->packet_map = g_hash_table_new_full(g_direct_hash,
784 g_direct_equal, NULL, (GDestroyNotify) unref_packet);
785 di_trace->trace_debug_map = g_hash_table_new_full(g_direct_hash,
786 g_direct_equal, NULL, (GDestroyNotify) unref_debug_info);
787 di_trace->stream_states = g_hash_table_new_full(g_direct_hash,
788 g_direct_equal, NULL, destroy_stream_state_key);
789 g_hash_table_insert(debug_it->trace_map, (gpointer) trace, di_trace);
790
791 /* Set all the existing streams in the unknown state. */
792 nr_stream = bt_ctf_trace_get_stream_count(trace);
793 for (i = 0; i < nr_stream; i++) {
794 stream = bt_ctf_trace_get_stream_by_index(trace, i);
795 if (!stream) {
796 fprintf(debug_it->err,
797 "[error] %s in %s:%d\n", __func__,
798 __FILE__, __LINE__);
799 goto error;
800 }
801 insert_new_stream_state(debug_it, di_trace, stream);
802 writer_stream = insert_new_stream(debug_it, stream, di_trace);
803 if (!writer_stream) {
804 fprintf(debug_it->err,
805 "[error] %s in %s:%d\n", __func__,
806 __FILE__, __LINE__);
807 goto error;
808 }
809 bt_get(writer_stream);
810 ret = sync_event_classes(debug_it, stream, writer_stream);
811 if (ret) {
812 fprintf(debug_it->err,
813 "[error] %s in %s:%d\n", __func__,
814 __FILE__, __LINE__);
815 goto error;
816 }
817 BT_PUT(writer_stream);
818 BT_PUT(stream);
819 }
820
821 /* Check if the trace is already static or register a listener. */
822 if (bt_ctf_trace_is_static(trace)) {
823 di_trace->trace_static = 1;
824 di_trace->static_listener_id = -1;
825 bt_ctf_trace_set_is_static(writer_trace);
826 } else {
827 ret = bt_ctf_trace_add_is_static_listener(trace,
828 trace_is_static_listener, di_trace);
829 if (ret < 0) {
830 fprintf(debug_it->err,
831 "[error] %s in %s:%d\n", __func__, __FILE__,
832 __LINE__);
833 goto error;
834 }
835 di_trace->static_listener_id = ret;
836 }
837
838
839 goto end;
840
841 error:
842 BT_PUT(writer_trace);
843 g_free(di_trace);
844 di_trace = NULL;
845 end:
846 bt_put(stream);
847 bt_put(writer_stream);
848 bt_put(stream_class);
849 bt_put(trace);
850 return di_trace;
851 }
852
853 static
854 struct bt_ctf_packet *lookup_packet(struct debug_info_iterator *debug_it,
855 struct bt_ctf_packet *packet,
856 struct debug_info_trace *di_trace)
857 {
858 return (struct bt_ctf_packet *) g_hash_table_lookup(
859 di_trace->packet_map,
860 (gpointer) packet);
861 }
862
863 static
864 struct bt_ctf_packet *insert_new_packet(struct debug_info_iterator *debug_it,
865 struct bt_ctf_packet *packet,
866 struct bt_ctf_stream *writer_stream,
867 struct debug_info_trace *di_trace)
868 {
869 struct bt_ctf_packet *writer_packet;
870
871 writer_packet = bt_ctf_packet_create(writer_stream);
872 if (!writer_packet) {
873 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
874 __FILE__, __LINE__);
875 goto end;
876 }
877 g_hash_table_insert(di_trace->packet_map, (gpointer) packet, writer_packet);
878
879 end:
880 return writer_packet;
881 }
882
883 static
884 int add_debug_info_fields(FILE *err,
885 struct bt_ctf_field_type *writer_event_context_type,
886 struct debug_info_component *component)
887 {
888 struct bt_ctf_field_type *ip_field = NULL, *debug_field_type = NULL,
889 *bin_field_type = NULL, *func_field_type = NULL,
890 *src_field_type = NULL;
891 int ret = 0;
892
893 ip_field = bt_ctf_field_type_structure_get_field_type_by_name(
894 writer_event_context_type, "_ip");
895 /* No ip field, so no debug info. */
896 if (!ip_field) {
897 goto end;
898 }
899 BT_PUT(ip_field);
900
901 debug_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
902 writer_event_context_type,
903 component->arg_debug_info_field_name);
904 /* Already existing debug_info field, no need to add it. */
905 if (debug_field_type) {
906 goto end;
907 }
908
909 debug_field_type = bt_ctf_field_type_structure_create();
910 if (!debug_field_type) {
911 fprintf(err, "[error] %s in %s:%d\n", __func__,
912 __FILE__, __LINE__);
913 goto error;
914 }
915
916 bin_field_type = bt_ctf_field_type_string_create();
917 if (!bin_field_type) {
918 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
919 __LINE__);
920 goto error;
921 }
922
923 func_field_type = bt_ctf_field_type_string_create();
924 if (!func_field_type) {
925 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
926 __LINE__);
927 goto error;
928 }
929
930 src_field_type = bt_ctf_field_type_string_create();
931 if (!src_field_type) {
932 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
933 __LINE__);
934 goto error;
935 }
936
937 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
938 bin_field_type, "bin");
939 if (ret) {
940 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
941 __LINE__);
942 goto error;
943 }
944
945 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
946 func_field_type, "func");
947 if (ret) {
948 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
949 __LINE__);
950 goto error;
951 }
952
953 ret = bt_ctf_field_type_structure_add_field(debug_field_type,
954 src_field_type, "src");
955 if (ret) {
956 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
957 __LINE__);
958 goto error;
959 }
960
961 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
962 debug_field_type, component->arg_debug_info_field_name);
963 if (ret) {
964 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
965 __LINE__);
966 goto error;
967 }
968
969 ret = 0;
970 goto end;
971
972 error:
973 BT_PUT(debug_field_type);
974 ret = -1;
975 end:
976 bt_put(src_field_type);
977 bt_put(func_field_type);
978 bt_put(bin_field_type);
979 bt_put(debug_field_type);
980 return ret;
981 }
982
983 static
984 int create_debug_info_event_context_type(FILE *err,
985 struct bt_ctf_field_type *event_context_type,
986 struct bt_ctf_field_type *writer_event_context_type,
987 struct debug_info_component *component)
988 {
989 int ret, nr_fields, i;
990
991 nr_fields = bt_ctf_field_type_structure_get_field_count(event_context_type);
992 for (i = 0; i < nr_fields; i++) {
993 struct bt_ctf_field_type *field_type = NULL;
994 const char *field_name;
995
996 if (bt_ctf_field_type_structure_get_field(event_context_type,
997 &field_name, &field_type, i) < 0) {
998 fprintf(err, "[error] %s in %s:%d\n", __func__,
999 __FILE__, __LINE__);
1000 goto error;
1001 }
1002
1003 ret = bt_ctf_field_type_structure_add_field(writer_event_context_type,
1004 field_type, field_name);
1005 BT_PUT(field_type);
1006 if (ret) {
1007 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1008 __LINE__);
1009 goto error;
1010 }
1011 }
1012
1013 ret = add_debug_info_fields(err, writer_event_context_type,
1014 component);
1015 goto end;
1016
1017 error:
1018 ret = -1;
1019 end:
1020 return ret;
1021 }
1022
1023 static
1024 struct bt_ctf_stream_class *copy_stream_class_debug_info(FILE *err,
1025 struct bt_ctf_stream_class *stream_class,
1026 struct bt_ctf_trace *writer_trace,
1027 struct debug_info_component *component)
1028 {
1029 struct bt_ctf_field_type *type = NULL;
1030 struct bt_ctf_stream_class *writer_stream_class = NULL;
1031 struct bt_ctf_field_type *writer_event_context_type = NULL;
1032 int ret_int;
1033 const char *name = bt_ctf_stream_class_get_name(stream_class);
1034
1035 if (strlen(name) == 0) {
1036 name = NULL;
1037 }
1038
1039 writer_stream_class = bt_ctf_stream_class_create(name);
1040 if (!writer_stream_class) {
1041 fprintf(err, "[error] %s in %s:%d\n",
1042 __func__, __FILE__, __LINE__);
1043 goto error;
1044 }
1045
1046 type = bt_ctf_stream_class_get_packet_context_type(stream_class);
1047 if (!type) {
1048 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1049 __LINE__);
1050 goto error;
1051 }
1052
1053 ret_int = bt_ctf_stream_class_set_packet_context_type(
1054 writer_stream_class, type);
1055 if (ret_int < 0) {
1056 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1057 __LINE__);
1058 goto error;
1059 }
1060 BT_PUT(type);
1061
1062 type = bt_ctf_stream_class_get_event_header_type(stream_class);
1063 if (type) {
1064 ret_int = bt_ctf_stream_class_set_event_header_type(
1065 writer_stream_class, type);
1066 if (ret_int < 0) {
1067 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1068 __LINE__);
1069 goto error;
1070 }
1071 BT_PUT(type);
1072 }
1073
1074 type = bt_ctf_stream_class_get_event_context_type(stream_class);
1075 if (type) {
1076 writer_event_context_type = bt_ctf_field_type_structure_create();
1077 if (!writer_event_context_type) {
1078 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1079 __LINE__);
1080 goto error;
1081 }
1082 ret_int = create_debug_info_event_context_type(err, type,
1083 writer_event_context_type, component);
1084 if (ret_int) {
1085 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1086 __LINE__);
1087 goto error;
1088 }
1089 BT_PUT(type);
1090
1091 ret_int = bt_ctf_stream_class_set_event_context_type(
1092 writer_stream_class, writer_event_context_type);
1093 if (ret_int < 0) {
1094 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1095 __LINE__);
1096 goto error;
1097 }
1098 BT_PUT(writer_event_context_type);
1099 }
1100
1101 goto end;
1102
1103 error:
1104 BT_PUT(writer_stream_class);
1105 end:
1106 bt_put(writer_event_context_type);
1107 bt_put(type);
1108 return writer_stream_class;
1109 }
1110
1111 /*
1112 * Add the original clock classes to the new trace, we do not need to copy
1113 * them, and if we did, we would have to manually inspect the stream class
1114 * to update the integers mapping to a clock.
1115 */
1116 static
1117 int add_clock_classes(FILE *err, struct bt_ctf_trace *writer_trace,
1118 struct bt_ctf_stream_class *writer_stream_class,
1119 struct bt_ctf_trace *trace)
1120 {
1121 int ret, clock_class_count, i;
1122
1123 clock_class_count = bt_ctf_trace_get_clock_class_count(trace);
1124
1125 for (i = 0; i < clock_class_count; i++) {
1126 struct bt_ctf_clock_class *clock_class =
1127 bt_ctf_trace_get_clock_class_by_index(trace, i);
1128
1129 if (!clock_class) {
1130 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1131 __LINE__);
1132 goto error;
1133 }
1134
1135 ret = bt_ctf_trace_add_clock_class(writer_trace, clock_class);
1136 BT_PUT(clock_class);
1137 if (ret != 0) {
1138 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1139 __LINE__);
1140 goto error;
1141 }
1142 }
1143
1144 ret = 0;
1145 goto end;
1146
1147 error:
1148 ret = -1;
1149 end:
1150 return ret;
1151
1152 }
1153
1154 static
1155 struct bt_ctf_stream_class *insert_new_stream_class(
1156 struct debug_info_iterator *debug_it,
1157 struct bt_ctf_stream_class *stream_class)
1158 {
1159 struct bt_ctf_stream_class *writer_stream_class = NULL;
1160 struct bt_ctf_trace *trace, *writer_trace = NULL;
1161 struct debug_info_trace *di_trace;
1162 enum bt_component_status ret;
1163 int int_ret;
1164
1165 trace = bt_ctf_stream_class_get_trace(stream_class);
1166 if (!trace) {
1167 fprintf(debug_it->err,
1168 "[error] %s in %s:%d\n", __func__, __FILE__,
1169 __LINE__);
1170 goto error;
1171 }
1172
1173 di_trace = lookup_trace(debug_it, trace);
1174 if (!di_trace) {
1175 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1176 __FILE__, __LINE__);
1177 ret = BT_COMPONENT_STATUS_ERROR;
1178 goto error;
1179 }
1180 writer_trace = di_trace->writer_trace;
1181 bt_get(writer_trace);
1182
1183 writer_stream_class = copy_stream_class_debug_info(debug_it->err, stream_class,
1184 writer_trace, debug_it->debug_info_component);
1185 if (!writer_stream_class) {
1186 fprintf(debug_it->err, "[error] Failed to copy stream class\n");
1187 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1188 __func__, __FILE__, __LINE__);
1189 goto error;
1190 }
1191
1192 int_ret = bt_ctf_trace_add_stream_class(writer_trace, writer_stream_class);
1193 if (int_ret) {
1194 fprintf(debug_it->err,
1195 "[error] %s in %s:%d\n", __func__, __FILE__,
1196 __LINE__);
1197 goto error;
1198 }
1199
1200 ret = add_clock_classes(debug_it->err, writer_trace,
1201 writer_stream_class, trace);
1202 if (ret != BT_COMPONENT_STATUS_OK) {
1203 fprintf(debug_it->err,
1204 "[error] %s in %s:%d\n", __func__, __FILE__,
1205 __LINE__);
1206 goto error;
1207 }
1208
1209 g_hash_table_insert(di_trace->stream_class_map,
1210 (gpointer) stream_class, writer_stream_class);
1211
1212 goto end;
1213
1214 error:
1215 BT_PUT(writer_stream_class);
1216 end:
1217 bt_put(trace);
1218 bt_put(writer_trace);
1219 return writer_stream_class;
1220 }
1221
1222 static
1223 struct bt_ctf_stream *insert_new_stream(
1224 struct debug_info_iterator *debug_it,
1225 struct bt_ctf_stream *stream,
1226 struct debug_info_trace *di_trace)
1227 {
1228 struct bt_ctf_stream *writer_stream = NULL;
1229 struct bt_ctf_stream_class *stream_class = NULL;
1230 struct bt_ctf_stream_class *writer_stream_class = NULL;
1231
1232 stream_class = bt_ctf_stream_get_class(stream);
1233 if (!stream_class) {
1234 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1235 __func__, __FILE__, __LINE__);
1236 goto error;
1237 }
1238
1239 writer_stream_class = g_hash_table_lookup(
1240 di_trace->stream_class_map,
1241 (gpointer) stream_class);
1242
1243 if (!writer_stream_class) {
1244 writer_stream_class = insert_new_stream_class(debug_it,
1245 stream_class);
1246 if (!writer_stream_class) {
1247 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1248 __func__, __FILE__, __LINE__);
1249 goto error;
1250 }
1251 }
1252 bt_get(writer_stream_class);
1253
1254 writer_stream = bt_ctf_stream_create(writer_stream_class,
1255 bt_ctf_stream_get_name(stream));
1256 if (!writer_stream) {
1257 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1258 __func__, __FILE__, __LINE__);
1259 goto error;
1260 }
1261
1262 g_hash_table_insert(di_trace->stream_map, (gpointer) stream,
1263 writer_stream);
1264
1265 goto end;
1266
1267 error:
1268 BT_PUT(writer_stream);
1269 end:
1270 bt_put(stream_class);
1271 bt_put(writer_stream_class);
1272 return writer_stream;
1273 }
1274
1275 static
1276 struct bt_ctf_stream *lookup_stream(struct debug_info_iterator *debug_it,
1277 struct bt_ctf_stream *stream,
1278 struct debug_info_trace *di_trace)
1279 {
1280 return (struct bt_ctf_stream *) g_hash_table_lookup(
1281 di_trace->stream_map, (gpointer) stream);
1282 }
1283
1284 static
1285 struct bt_ctf_event_class *get_event_class(struct debug_info_iterator *debug_it,
1286 struct bt_ctf_stream_class *writer_stream_class,
1287 struct bt_ctf_event_class *event_class)
1288 {
1289 return bt_ctf_stream_class_get_event_class_by_id(writer_stream_class,
1290 bt_ctf_event_class_get_id(event_class));
1291 }
1292
1293 static
1294 struct debug_info_trace *lookup_di_trace_from_stream(
1295 struct debug_info_iterator *debug_it,
1296 struct bt_ctf_stream *stream)
1297 {
1298 struct bt_ctf_stream_class *stream_class = NULL;
1299 struct bt_ctf_trace *trace = NULL;
1300 struct debug_info_trace *di_trace = NULL;
1301
1302 stream_class = bt_ctf_stream_get_class(stream);
1303 if (!stream_class) {
1304 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1305 __func__, __FILE__, __LINE__);
1306 goto end;
1307 }
1308
1309 trace = bt_ctf_stream_class_get_trace(stream_class);
1310 if (!trace) {
1311 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1312 __func__, __FILE__, __LINE__);
1313 goto end;
1314 }
1315
1316 di_trace = (struct debug_info_trace *) g_hash_table_lookup(
1317 debug_it->trace_map, (gpointer) trace);
1318
1319 end:
1320 BT_PUT(stream_class);
1321 BT_PUT(trace);
1322 return di_trace;
1323 }
1324
1325 static
1326 struct bt_ctf_stream *get_writer_stream(
1327 struct debug_info_iterator *debug_it,
1328 struct bt_ctf_packet *packet, struct bt_ctf_stream *stream)
1329 {
1330 struct bt_ctf_stream_class *stream_class = NULL;
1331 struct bt_ctf_stream *writer_stream = NULL;
1332 struct debug_info_trace *di_trace = NULL;
1333
1334 stream_class = bt_ctf_stream_get_class(stream);
1335 if (!stream_class) {
1336 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1337 __func__, __FILE__, __LINE__);
1338 goto error;
1339 }
1340
1341 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1342 if (!di_trace) {
1343 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1344 __func__, __FILE__, __LINE__);
1345 goto error;
1346 }
1347
1348 writer_stream = lookup_stream(debug_it, stream, di_trace);
1349 if (!writer_stream) {
1350 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1351 __func__, __FILE__, __LINE__);
1352 goto error;
1353 }
1354 bt_get(writer_stream);
1355
1356 goto end;
1357
1358 error:
1359 BT_PUT(writer_stream);
1360 end:
1361 bt_put(stream_class);
1362 return writer_stream;
1363 }
1364
1365 BT_HIDDEN
1366 struct bt_ctf_packet *debug_info_new_packet(
1367 struct debug_info_iterator *debug_it,
1368 struct bt_ctf_packet *packet)
1369 {
1370 struct bt_ctf_stream *stream = NULL, *writer_stream = NULL;
1371 struct bt_ctf_field *writer_packet_context = NULL;
1372 struct bt_ctf_packet *writer_packet = NULL;
1373 struct debug_info_trace *di_trace;
1374 int int_ret;
1375
1376 stream = bt_ctf_packet_get_stream(packet);
1377 if (!stream) {
1378 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1379 __func__, __FILE__, __LINE__);
1380 goto error;
1381 }
1382
1383 writer_stream = get_writer_stream(debug_it, packet, stream);
1384 if (!writer_stream) {
1385 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1386 __func__, __FILE__, __LINE__);
1387 goto error;
1388 }
1389
1390 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1391 if (!di_trace) {
1392 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1393 __FILE__, __LINE__);
1394 goto error;
1395 }
1396
1397 /*
1398 * If a packet was already opened, close it and remove it from
1399 * the HT.
1400 */
1401 writer_packet = lookup_packet(debug_it, packet, di_trace);
1402 if (writer_packet) {
1403 g_hash_table_remove(di_trace->packet_map, packet);
1404 BT_PUT(writer_packet);
1405 }
1406
1407 writer_packet = insert_new_packet(debug_it, packet, writer_stream,
1408 di_trace);
1409 if (!writer_packet) {
1410 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1411 __func__, __FILE__, __LINE__);
1412 goto error;
1413 }
1414
1415 writer_packet_context = ctf_copy_packet_context(debug_it->err, packet,
1416 writer_stream);
1417 if (!writer_packet_context) {
1418 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1419 __func__, __FILE__, __LINE__);
1420 goto error;
1421 }
1422
1423 int_ret = bt_ctf_packet_set_context(writer_packet, writer_packet_context);
1424 if (int_ret) {
1425 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1426 __func__, __FILE__, __LINE__);
1427 goto error;
1428 }
1429
1430 bt_get(writer_packet);
1431 goto end;
1432
1433 error:
1434
1435 end:
1436 bt_put(writer_packet_context);
1437 bt_put(writer_stream);
1438 bt_put(stream);
1439 return writer_packet;
1440 }
1441
1442 BT_HIDDEN
1443 struct bt_ctf_packet *debug_info_close_packet(
1444 struct debug_info_iterator *debug_it,
1445 struct bt_ctf_packet *packet)
1446 {
1447 struct bt_ctf_packet *writer_packet = NULL;
1448 struct bt_ctf_stream *stream = NULL;
1449 struct debug_info_trace *di_trace;
1450
1451 stream = bt_ctf_packet_get_stream(packet);
1452 if (!stream) {
1453 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1454 __FILE__, __LINE__);
1455 goto end;
1456 }
1457
1458 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1459 if (!di_trace) {
1460 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
1461 __FILE__, __LINE__);
1462 goto end;
1463 }
1464
1465 writer_packet = lookup_packet(debug_it, packet, di_trace);
1466 if (!writer_packet) {
1467 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1468 __func__, __FILE__, __LINE__);
1469 goto end;
1470 }
1471 bt_get(writer_packet);
1472 g_hash_table_remove(di_trace->packet_map, packet);
1473
1474 end:
1475 bt_put(stream);
1476 return writer_packet;
1477 }
1478
1479 BT_HIDDEN
1480 struct bt_ctf_stream *debug_info_stream_begin(
1481 struct debug_info_iterator *debug_it,
1482 struct bt_ctf_stream *stream)
1483 {
1484 struct bt_ctf_stream *writer_stream = NULL;
1485 enum debug_info_stream_state *state;
1486 struct debug_info_trace *di_trace = NULL;
1487
1488 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1489 if (!di_trace) {
1490 di_trace = insert_new_trace(debug_it, stream);
1491 if (!di_trace) {
1492 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1493 __func__, __FILE__, __LINE__);
1494 goto error;
1495 }
1496 }
1497
1498 /* Set the stream as active */
1499 state = g_hash_table_lookup(di_trace->stream_states, stream);
1500 if (!state) {
1501 if (di_trace->trace_static) {
1502 fprintf(debug_it->err, "[error] Adding a new stream "
1503 "on a static trace\n");
1504 goto error;
1505 }
1506 state = insert_new_stream_state(debug_it, di_trace,
1507 stream);
1508 if (!state) {
1509 fprintf(debug_it->err, "[error] Adding a new stream "
1510 "on a static trace\n");
1511 goto error;
1512 }
1513 }
1514 if (*state != DEBUG_INFO_UNKNOWN_STREAM) {
1515 fprintf(debug_it->err, "[error] Unexpected stream state %d\n",
1516 *state);
1517 goto error;
1518 }
1519 *state = DEBUG_INFO_ACTIVE_STREAM;
1520
1521 writer_stream = lookup_stream(debug_it, stream, di_trace);
1522 if (!writer_stream) {
1523 writer_stream = insert_new_stream(debug_it, stream, di_trace);
1524 }
1525 bt_get(writer_stream);
1526
1527 goto end;
1528
1529 error:
1530 BT_PUT(writer_stream);
1531 end:
1532 return writer_stream;
1533 }
1534
1535 BT_HIDDEN
1536 struct bt_ctf_stream *debug_info_stream_end(struct debug_info_iterator *debug_it,
1537 struct bt_ctf_stream *stream)
1538 {
1539 struct bt_ctf_stream *writer_stream = NULL;
1540 struct debug_info_trace *di_trace = NULL;
1541 enum debug_info_stream_state *state;
1542
1543 di_trace = lookup_di_trace_from_stream(debug_it, stream);
1544 if (!di_trace) {
1545 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1546 __func__, __FILE__, __LINE__);
1547 goto error;
1548 }
1549
1550 writer_stream = lookup_stream(debug_it, stream, di_trace);
1551 if (!writer_stream) {
1552 fprintf(debug_it->err, "[error] %s in %s:%d\n",
1553 __func__, __FILE__, __LINE__);
1554 goto error;
1555 }
1556 /*
1557 * Take the ref on the stream and keep it until the notification
1558 * is created.
1559 */
1560 bt_get(writer_stream);
1561
1562 state = g_hash_table_lookup(di_trace->stream_states, stream);
1563 if (*state != DEBUG_INFO_ACTIVE_STREAM) {
1564 fprintf(debug_it->err, "[error] Unexpected stream "
1565 "state %d\n", *state);
1566 goto error;
1567 }
1568 *state = DEBUG_INFO_COMPLETED_STREAM;
1569
1570 g_hash_table_remove(di_trace->stream_map, stream);
1571
1572 if (di_trace->trace_static) {
1573 int trace_completed = 1;
1574
1575 g_hash_table_foreach(di_trace->stream_states,
1576 check_completed_trace, &trace_completed);
1577 if (trace_completed) {
1578 debug_info_close_trace(debug_it, di_trace);
1579 g_hash_table_remove(debug_it->trace_map,
1580 di_trace->trace);
1581 }
1582 }
1583
1584 goto end;
1585
1586 error:
1587 BT_PUT(writer_stream);
1588
1589 end:
1590 return writer_stream;
1591 }
1592
1593 static
1594 struct debug_info_source *lookup_debug_info(FILE *err,
1595 struct bt_ctf_event *event,
1596 struct debug_info *debug_info)
1597 {
1598 int64_t vpid;
1599 uint64_t ip;
1600 struct debug_info_source *dbg_info_src = NULL;
1601 int ret;
1602
1603 ret = get_stream_event_context_int_field_value(err, event,
1604 "_vpid", &vpid);
1605 if (ret) {
1606 goto end;
1607 }
1608
1609 ret = get_stream_event_context_unsigned_int_field_value(err, event,
1610 "_ip", &ip);
1611 if (ret) {
1612 goto end;
1613 }
1614
1615 /* Get debug info for this context. */
1616 dbg_info_src = debug_info_query(debug_info, vpid, ip);
1617
1618 end:
1619 return dbg_info_src;
1620 }
1621
1622 static
1623 int set_debug_info_field(FILE *err, struct bt_ctf_field *debug_field,
1624 struct debug_info_source *dbg_info_src,
1625 struct debug_info_component *component)
1626 {
1627 int i, nr_fields, ret = 0;
1628 struct bt_ctf_field_type *debug_field_type = NULL;
1629 struct bt_ctf_field *field = NULL;
1630 struct bt_ctf_field_type *field_type = NULL;
1631
1632 debug_field_type = bt_ctf_field_get_type(debug_field);
1633 if (!debug_field_type) {
1634 fprintf(err, "[error] %s in %s:%d\n", __func__,
1635 __FILE__, __LINE__);
1636 goto error;
1637 }
1638
1639 nr_fields = bt_ctf_field_type_structure_get_field_count(debug_field_type);
1640 for (i = 0; i < nr_fields; i++) {
1641 const char *field_name;
1642
1643 if (bt_ctf_field_type_structure_get_field(debug_field_type,
1644 &field_name, &field_type, i) < 0) {
1645 fprintf(err, "[error] %s in %s:%d\n", __func__,
1646 __FILE__, __LINE__);
1647 goto error;
1648 }
1649 BT_PUT(field_type);
1650
1651 field = bt_ctf_field_structure_get_field_by_index(debug_field, i);
1652 if (!strcmp(field_name, "bin")) {
1653 if (dbg_info_src && dbg_info_src->bin_path) {
1654 GString *tmp = g_string_new(NULL);
1655
1656 if (component->arg_full_path) {
1657 g_string_printf(tmp, "%s%s",
1658 dbg_info_src->bin_path,
1659 dbg_info_src->bin_loc);
1660 } else {
1661 g_string_printf(tmp, "%s%s",
1662 dbg_info_src->short_bin_path,
1663 dbg_info_src->bin_loc);
1664 }
1665 ret = bt_ctf_field_string_set_value(field, tmp->str);
1666 g_string_free(tmp, true);
1667 } else {
1668 ret = bt_ctf_field_string_set_value(field, "");
1669 }
1670 } else if (!strcmp(field_name, "func")) {
1671 if (dbg_info_src && dbg_info_src->func) {
1672 ret = bt_ctf_field_string_set_value(field,
1673 dbg_info_src->func);
1674 } else {
1675 ret = bt_ctf_field_string_set_value(field, "");
1676 }
1677 } else if (!strcmp(field_name, "src")) {
1678 if (dbg_info_src && dbg_info_src->src_path) {
1679 GString *tmp = g_string_new(NULL);
1680
1681 if (component->arg_full_path) {
1682 g_string_printf(tmp, "%s:%" PRId64,
1683 dbg_info_src->src_path,
1684 dbg_info_src->line_no);
1685 } else {
1686 g_string_printf(tmp, "%s:%" PRId64,
1687 dbg_info_src->short_src_path,
1688 dbg_info_src->line_no);
1689 }
1690 ret = bt_ctf_field_string_set_value(field, tmp->str);
1691 g_string_free(tmp, true);
1692 } else {
1693 ret = bt_ctf_field_string_set_value(field, "");
1694 }
1695 }
1696 BT_PUT(field);
1697 if (ret) {
1698 fprintf(err, "[error] %s in %s:%d\n", __func__,
1699 __FILE__, __LINE__);
1700 goto error;
1701 }
1702 }
1703 ret = 0;
1704 goto end;
1705
1706 error:
1707 ret = -1;
1708 end:
1709 bt_put(field_type);
1710 bt_put(field);
1711 bt_put(debug_field_type);
1712 return ret;
1713 }
1714
1715 static
1716 int copy_set_debug_info_stream_event_context(FILE *err,
1717 struct bt_ctf_field *event_context,
1718 struct bt_ctf_event *event,
1719 struct bt_ctf_event *writer_event,
1720 struct debug_info *debug_info,
1721 struct debug_info_component *component)
1722 {
1723 struct bt_ctf_field_type *writer_event_context_type = NULL,
1724 *event_context_type = NULL;
1725 struct bt_ctf_field *writer_event_context = NULL;
1726 struct bt_ctf_field *field = NULL, *copy_field = NULL, *debug_field = NULL;
1727 struct bt_ctf_field_type *field_type = NULL;
1728 struct debug_info_source *dbg_info_src;
1729 int ret, nr_fields, i;
1730
1731 writer_event_context = bt_ctf_event_get_stream_event_context(writer_event);
1732 if (!writer_event_context) {
1733 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__, __LINE__);
1734 goto error;
1735 }
1736
1737 writer_event_context_type = bt_ctf_field_get_type(writer_event_context);
1738 if (!writer_event_context_type) {
1739 fprintf(err, "[error] %s in %s:%d\n", __func__,
1740 __FILE__, __LINE__);
1741 goto error;
1742 }
1743
1744 event_context_type = bt_ctf_field_get_type(event_context);
1745 if (!event_context_type) {
1746 fprintf(err, "[error] %s in %s:%d\n", __func__,
1747 __FILE__, __LINE__);
1748 goto error;
1749 }
1750
1751 /*
1752 * If it is not a structure, we did not modify it to add the debug info
1753 * fields, so just assign it as is.
1754 */
1755 if (bt_ctf_field_type_get_type_id(writer_event_context_type) != BT_CTF_FIELD_TYPE_ID_STRUCT) {
1756 ret = bt_ctf_event_set_event_context(writer_event, event_context);
1757 goto end;
1758 }
1759
1760 dbg_info_src = lookup_debug_info(err, event, debug_info);
1761
1762 nr_fields = bt_ctf_field_type_structure_get_field_count(writer_event_context_type);
1763 for (i = 0; i < nr_fields; i++) {
1764 const char *field_name;
1765
1766 if (bt_ctf_field_type_structure_get_field(writer_event_context_type,
1767 &field_name, &field_type, i) < 0) {
1768 fprintf(err, "[error] %s in %s:%d\n", __func__,
1769 __FILE__, __LINE__);
1770 goto error;
1771 }
1772
1773 /*
1774 * Prevent illegal access in the event_context.
1775 */
1776 if (i < bt_ctf_field_type_structure_get_field_count(event_context_type)) {
1777 field = bt_ctf_field_structure_get_field_by_index(event_context, i);
1778 }
1779 /*
1780 * The debug_info field, only exists in the writer event or
1781 * if it was set by a earlier pass of the debug_info plugin.
1782 */
1783 if (!strcmp(field_name, component->arg_debug_info_field_name) &&
1784 !field) {
1785 debug_field = bt_ctf_field_structure_get_field_by_index(
1786 writer_event_context, i);
1787 if (!debug_field) {
1788 fprintf(err, "[error] %s in %s:%d\n", __func__,
1789 __FILE__, __LINE__);
1790 goto error;
1791 }
1792 ret = set_debug_info_field(err, debug_field,
1793 dbg_info_src, component);
1794 if (ret) {
1795 fprintf(err, "[error] %s in %s:%d\n", __func__,
1796 __FILE__, __LINE__);
1797 goto error;
1798 }
1799 BT_PUT(debug_field);
1800 } else {
1801 copy_field = bt_ctf_field_copy(field);
1802 if (!copy_field) {
1803 fprintf(err, "[error] %s in %s:%d\n", __func__,
1804 __FILE__, __LINE__);
1805 goto error;
1806 }
1807
1808 ret = bt_ctf_field_structure_set_field(writer_event_context,
1809 field_name, copy_field);
1810 if (ret) {
1811 fprintf(err, "[error] %s in %s:%d\n", __func__,
1812 __FILE__, __LINE__);
1813 goto error;
1814 }
1815 BT_PUT(copy_field);
1816 }
1817 BT_PUT(field_type);
1818 BT_PUT(field);
1819 }
1820
1821 ret = 0;
1822 goto end;
1823
1824 error:
1825 ret = -1;
1826 end:
1827 bt_put(event_context_type);
1828 bt_put(writer_event_context_type);
1829 bt_put(writer_event_context);
1830 bt_put(field);
1831 bt_put(copy_field);
1832 bt_put(debug_field);
1833 bt_put(field_type);
1834 return ret;
1835 }
1836
1837 static
1838 struct bt_ctf_clock_class *stream_class_get_clock_class(FILE *err,
1839 struct bt_ctf_stream_class *stream_class)
1840 {
1841 struct bt_ctf_trace *trace = NULL;
1842 struct bt_ctf_clock_class *clock_class = NULL;
1843
1844 trace = bt_ctf_stream_class_get_trace(stream_class);
1845 if (!trace) {
1846 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1847 __LINE__);
1848 goto end;
1849 }
1850
1851 if (!bt_ctf_trace_get_clock_class_count(trace)) {
1852 /* No clock. */
1853 goto end;
1854 }
1855
1856 /* FIXME multi-clock? */
1857 clock_class = bt_ctf_trace_get_clock_class_by_index(trace, 0);
1858
1859 bt_put(trace);
1860
1861 end:
1862 return clock_class;
1863 }
1864
1865 static
1866 struct bt_ctf_clock_class *event_get_clock_class(FILE *err, struct bt_ctf_event *event)
1867 {
1868 struct bt_ctf_event_class *event_class = NULL;
1869 struct bt_ctf_stream_class *stream_class = NULL;
1870 struct bt_ctf_clock_class *clock_class = NULL;
1871
1872 event_class = bt_ctf_event_get_class(event);
1873 if (!event_class) {
1874 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1875 __LINE__);
1876 goto error;
1877 }
1878
1879 stream_class = bt_ctf_event_class_get_stream_class(event_class);
1880 if (!stream_class) {
1881 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1882 __LINE__);
1883 goto error;
1884 }
1885
1886 clock_class = stream_class_get_clock_class(err, stream_class);
1887 goto end;
1888
1889 error:
1890 BT_PUT(clock_class);
1891 end:
1892 bt_put(stream_class);
1893 bt_put(event_class);
1894 return clock_class;
1895 }
1896
1897 static
1898 int set_event_clock_value(FILE *err, struct bt_ctf_event *event,
1899 struct bt_ctf_event *writer_event)
1900 {
1901 struct bt_ctf_clock_class *clock_class = NULL;
1902 struct bt_ctf_clock_value *clock_value = NULL;
1903 int ret;
1904
1905 clock_class = event_get_clock_class(err, event);
1906 if (!clock_class) {
1907 /* No clock on input trace. */
1908 goto end;
1909 }
1910
1911 clock_value = bt_ctf_event_get_clock_value(event, clock_class);
1912 if (!clock_value) {
1913 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1914 __LINE__);
1915 goto error;
1916 }
1917
1918 /*
1919 * We share the same clocks, so we can assign the clock value to the
1920 * writer event.
1921 */
1922 ret = bt_ctf_event_set_clock_value(writer_event, clock_value);
1923 if (ret) {
1924 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1925 __LINE__);
1926 goto error;
1927 }
1928
1929 ret = 0;
1930 goto end;
1931
1932 error:
1933 ret = -1;
1934 end:
1935 bt_put(clock_class);
1936 bt_put(clock_value);
1937 return ret;
1938 }
1939
1940 static
1941 struct bt_ctf_event *debug_info_copy_event(FILE *err, struct bt_ctf_event *event,
1942 struct bt_ctf_event_class *writer_event_class,
1943 struct debug_info *debug_info,
1944 struct debug_info_component *component)
1945 {
1946 struct bt_ctf_event *writer_event = NULL;
1947 struct bt_ctf_field *field = NULL, *copy_field = NULL;
1948 int ret;
1949
1950 writer_event = bt_ctf_event_create(writer_event_class);
1951 if (!writer_event) {
1952 fprintf(err, "[error] %s in %s:%d\n", __func__, __FILE__,
1953 __LINE__);
1954 goto error;
1955 }
1956
1957 ret = set_event_clock_value(err, event, writer_event);
1958 if (ret) {
1959 fprintf(err, "[error] %s in %s:%d\n", __func__,
1960 __FILE__, __LINE__);
1961 goto error;
1962 }
1963
1964 /* Optional field, so it can fail silently. */
1965 field = bt_ctf_event_get_header(event);
1966 if (field) {
1967 ret = ctf_copy_event_header(err, event, writer_event_class,
1968 writer_event, field);
1969 if (ret) {
1970 fprintf(err, "[error] %s in %s:%d\n", __func__,
1971 __FILE__, __LINE__);
1972 goto error;
1973 }
1974 BT_PUT(field);
1975 }
1976
1977 /* Optional field, so it can fail silently. */
1978 field = bt_ctf_event_get_stream_event_context(event);
1979 if (field) {
1980 ret = copy_set_debug_info_stream_event_context(err,
1981 field, event, writer_event, debug_info,
1982 component);
1983 if (ret < 0) {
1984 fprintf(err, "[error] %s in %s:%d\n", __func__,
1985 __FILE__, __LINE__);
1986 goto error;
1987 }
1988 BT_PUT(field);
1989 }
1990
1991 /* Optional field, so it can fail silently. */
1992 field = bt_ctf_event_get_event_context(event);
1993 if (field) {
1994 copy_field = bt_ctf_field_copy(field);
1995 if (!copy_field) {
1996 fprintf(err, "[error] %s in %s:%d\n", __func__,
1997 __FILE__, __LINE__);
1998 goto error;
1999 }
2000 ret = bt_ctf_event_set_event_context(writer_event, copy_field);
2001 if (ret < 0) {
2002 fprintf(err, "[error] %s in %s:%d\n", __func__,
2003 __FILE__, __LINE__);
2004 goto error;
2005 }
2006 BT_PUT(copy_field);
2007 BT_PUT(field);
2008 }
2009
2010 field = bt_ctf_event_get_event_payload(event);
2011 if (!field) {
2012 fprintf(err, "[error] %s in %s:%d\n", __func__,
2013 __FILE__, __LINE__);
2014 goto error;
2015 }
2016 copy_field = bt_ctf_field_copy(field);
2017 if (copy_field) {
2018 ret = bt_ctf_event_set_event_payload(writer_event, copy_field);
2019 if (ret < 0) {
2020 fprintf(err, "[error] %s in %s:%d\n", __func__,
2021 __FILE__, __LINE__);
2022 goto error;
2023 }
2024 BT_PUT(copy_field);
2025 }
2026 BT_PUT(field);
2027
2028 goto end;
2029
2030 error:
2031 BT_PUT(writer_event);
2032 end:
2033 bt_put(copy_field);
2034 bt_put(field);
2035 return writer_event;
2036 }
2037
2038 BT_HIDDEN
2039 struct bt_ctf_event *debug_info_output_event(
2040 struct debug_info_iterator *debug_it,
2041 struct bt_ctf_event *event)
2042 {
2043 struct bt_ctf_event_class *event_class = NULL, *writer_event_class = NULL;
2044 struct bt_ctf_stream_class *stream_class = NULL, *writer_stream_class = NULL;
2045 struct bt_ctf_event *writer_event = NULL;
2046 struct bt_ctf_packet *packet = NULL, *writer_packet = NULL;
2047 struct bt_ctf_trace *writer_trace = NULL;
2048 struct bt_ctf_stream *stream = NULL;
2049 struct debug_info_trace *di_trace;
2050 struct debug_info *debug_info;
2051 const char *event_name;
2052 int int_ret;
2053
2054 event_class = bt_ctf_event_get_class(event);
2055 if (!event_class) {
2056 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2057 __FILE__, __LINE__);
2058 goto error;
2059 }
2060
2061 event_name = bt_ctf_event_class_get_name(event_class);
2062 if (!event_name) {
2063 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2064 __FILE__, __LINE__);
2065 goto error;
2066 }
2067
2068 stream_class = bt_ctf_event_class_get_stream_class(event_class);
2069 if (!stream_class) {
2070 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2071 __FILE__, __LINE__);
2072 goto error;
2073 }
2074 stream = bt_ctf_event_get_stream(event);
2075 if (!stream) {
2076 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2077 __FILE__, __LINE__);
2078 goto error;
2079 }
2080 di_trace = lookup_di_trace_from_stream(debug_it, stream);
2081 if (!di_trace) {
2082 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2083 __FILE__, __LINE__);
2084 goto error;
2085 }
2086
2087 writer_stream_class = g_hash_table_lookup(
2088 di_trace->stream_class_map,
2089 (gpointer) stream_class);
2090 if (!writer_stream_class) {
2091 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2092 __FILE__, __LINE__);
2093 goto error;
2094 }
2095 bt_get(writer_stream_class);
2096
2097 writer_event_class = get_event_class(debug_it,
2098 writer_stream_class, event_class);
2099 if (!writer_event_class) {
2100 writer_event_class = ctf_copy_event_class(debug_it->err,
2101 event_class);
2102 if (!writer_event_class) {
2103 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2104 __func__, __FILE__, __LINE__);
2105 goto error;
2106 }
2107 int_ret = bt_ctf_stream_class_add_event_class(
2108 writer_stream_class, writer_event_class);
2109 if (int_ret) {
2110 fprintf(debug_it->err, "[error] %s in %s:%d\n",
2111 __func__, __FILE__, __LINE__);
2112 goto error;
2113 }
2114 }
2115
2116 writer_trace = bt_ctf_stream_class_get_trace(writer_stream_class);
2117 if (!writer_trace) {
2118 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2119 __FILE__, __LINE__);
2120 goto error;
2121 }
2122
2123 debug_info = get_trace_debug_info(debug_it, writer_trace, di_trace);
2124 if (debug_info) {
2125 debug_info_handle_event(debug_it->err, event, debug_info);
2126 }
2127
2128 writer_event = debug_info_copy_event(debug_it->err, event,
2129 writer_event_class, debug_info,
2130 debug_it->debug_info_component);
2131 if (!writer_event) {
2132 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2133 __FILE__, __LINE__);
2134 fprintf(debug_it->err, "[error] Failed to copy event %s\n",
2135 bt_ctf_event_class_get_name(writer_event_class));
2136 goto error;
2137 }
2138
2139 packet = bt_ctf_event_get_packet(event);
2140 if (!packet) {
2141 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2142 __FILE__, __LINE__);
2143 goto error;
2144 }
2145
2146 writer_packet = lookup_packet(debug_it, packet, di_trace);
2147 if (!writer_packet) {
2148 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2149 __FILE__, __LINE__);
2150 goto error;
2151 }
2152 bt_get(writer_packet);
2153
2154 int_ret = bt_ctf_event_set_packet(writer_event, writer_packet);
2155 if (int_ret < 0) {
2156 fprintf(debug_it->err, "[error] %s in %s:%d\n", __func__,
2157 __FILE__, __LINE__);
2158 fprintf(debug_it->err, "[error] Failed to append event %s\n",
2159 bt_ctf_event_class_get_name(writer_event_class));
2160 goto error;
2161 }
2162
2163 /* Keep the reference on the writer event */
2164 goto end;
2165
2166 error:
2167 BT_PUT(writer_event);
2168
2169 end:
2170 bt_put(stream);
2171 bt_put(writer_trace);
2172 bt_put(writer_packet);
2173 bt_put(packet);
2174 bt_put(writer_event_class);
2175 bt_put(writer_stream_class);
2176 bt_put(stream_class);
2177 bt_put(event_class);
2178 return writer_event;
2179 }
This page took 0.109878 seconds and 4 git commands to generate.