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