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