lib: create_packet_message(): make assertion message less convoluted
[babeltrace.git] / plugins / lttng-utils / debug-info / trace-ir-metadata-copy.c
CommitLineData
ca9f27f3
FD
1/*
2 * Babeltrace - Trace IR metadata object copy
3 *
4 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27#define BT_LOG_TAG "PLUGIN-LTTNG-UTILS-DEBUG-INFO-TRACE-IR-METADATA-COPY"
28#include "logging.h"
29
30#include <inttypes.h>
31#include <stdint.h>
32
33#include <babeltrace/assert-internal.h>
34
35#include "trace-ir-metadata-copy.h"
36#include "trace-ir-metadata-field-class-copy.h"
37#include "utils.h"
38
39BT_HIDDEN
40int copy_trace_class_content(const bt_trace_class *in_trace_class,
41 bt_trace_class *out_trace_class)
42{
43 int ret = 0;
44 uint64_t i, env_field_count;
45 const char *in_trace_class_name;
ca9f27f3
FD
46
47 BT_LOGD("Copying content of trace class: in-tc-addr=%p, out-tc-addr=%p",
48 in_trace_class, out_trace_class);
49
50 /* Use the same stream class ids as in the origin trace class. */
51 bt_trace_class_set_assigns_automatic_stream_class_id(out_trace_class,
52 BT_FALSE);
53
54 in_trace_class_name = bt_trace_class_get_name(in_trace_class);
55 if (in_trace_class_name) {
56 bt_trace_class_set_name(out_trace_class, in_trace_class_name);
57 }
58
2d836ebb
FD
59 /*
60 * Do not copy the trace class UUID as it may be modified and should no
61 * longer have the same UUID.
62 */
ca9f27f3
FD
63
64 /*
65 * Go over all the entries in the environment section of the trace class
66 * and copy the content to the new trace class.
67 */
68 env_field_count = bt_trace_class_get_environment_entry_count(in_trace_class);
69 for (i = 0; i < env_field_count; i++) {
70 const char *value_name;
71 const bt_value *value = NULL;
72 bt_trace_class_status trace_class_status;
73
74 bt_trace_class_borrow_environment_entry_by_index_const(
75 in_trace_class, i, &value_name, &value);
76
77 BT_LOGD("Copying trace class environnement entry: "
78 "index=%" PRId64 ", value-addr=%p, value-name=%s",
79 i, value, value_name);
80
81 BT_ASSERT(value_name);
82 BT_ASSERT(value);
83
fdd3a2da 84 if (bt_value_is_signed_integer(value)) {
ca9f27f3
FD
85 trace_class_status =
86 bt_trace_class_set_environment_entry_integer(
87 out_trace_class, value_name,
fdd3a2da
PP
88 bt_value_signed_integer_get(
89 value));
ca9f27f3
FD
90 } else if (bt_value_is_string(value)) {
91 trace_class_status =
92 bt_trace_class_set_environment_entry_string(
93 out_trace_class, value_name,
94 bt_value_string_get(value));
95 } else {
96 abort();
97 }
98
99 if (trace_class_status != BT_TRACE_CLASS_STATUS_OK) {
100 ret = -1;
101 goto error;
102 }
103 }
104
105 BT_LOGD("Copied content of trace class: in-tc-addr=%p, out-tc-addr=%p",
106 in_trace_class, out_trace_class);
107error:
108 return ret;
109}
110
111static
112int copy_clock_class_content(const bt_clock_class *in_clock_class,
113 bt_clock_class *out_clock_class)
114{
115 bt_clock_class_status status;
116 const char *clock_class_name, *clock_class_description;
117 int64_t seconds;
118 uint64_t cycles;
119 bt_uuid in_uuid;
120 int ret = 0;
121
122 BT_LOGD("Copying content of clock class: in-cc-addr=%p, out-cc-addr=%p",
123 in_clock_class, out_clock_class);
124
125 clock_class_name = bt_clock_class_get_name(in_clock_class);
126
127 if (clock_class_name) {
128 status = bt_clock_class_set_name(out_clock_class, clock_class_name);
129 if (status != BT_CLOCK_CLASS_STATUS_OK) {
130 BT_LOGE("Error setting clock class' name cc-addr=%p, name=%p",
131 out_clock_class, clock_class_name);
132 out_clock_class = NULL;
133 ret = -1;
134 goto error;
135 }
136 }
137
138 clock_class_description = bt_clock_class_get_description(in_clock_class);
139
140 if (clock_class_description) {
141 status = bt_clock_class_set_description(out_clock_class,
142 clock_class_description);
143 if (status != BT_CLOCK_CLASS_STATUS_OK) {
144 BT_LOGE("Error setting clock class' description cc-addr=%p, "
145 "name=%p", out_clock_class, clock_class_description);
146 out_clock_class = NULL;
147 ret = -1;
148 goto error;
149 }
150 }
151
152 in_uuid = bt_clock_class_get_uuid(in_clock_class);
153 if (in_uuid) {
154 bt_clock_class_set_uuid(out_clock_class, in_uuid);
155 }
156
157 bt_clock_class_set_frequency(out_clock_class,
158 bt_clock_class_get_frequency(in_clock_class));
159 bt_clock_class_set_precision(out_clock_class,
160 bt_clock_class_get_precision(in_clock_class));
161 bt_clock_class_get_offset(in_clock_class, &seconds, &cycles);
162 bt_clock_class_set_offset(out_clock_class, seconds, cycles);
163 bt_clock_class_set_origin_is_unix_epoch(out_clock_class,
164 bt_clock_class_origin_is_unix_epoch(in_clock_class));
165
166 BT_LOGD("Copied content of clock class: in-cc-addr=%p, out-cc-addr=%p",
167 in_clock_class, out_clock_class);
168
169error:
170 return ret;
171}
172
173static
174bt_clock_class *borrow_mapped_clock_class(
175 struct trace_ir_metadata_maps *md_maps,
176 const bt_clock_class *in_clock_class)
177{
178 BT_ASSERT(md_maps);
179 BT_ASSERT(in_clock_class);
180
181 return g_hash_table_lookup(md_maps->clock_class_map,
182 (gpointer) in_clock_class);
183}
184
185static
186bt_clock_class *create_new_mapped_clock_class(
187 bt_self_component *self_comp,
188 struct trace_ir_metadata_maps *md_maps,
189 const bt_clock_class *in_clock_class)
190{
191 bt_clock_class *out_clock_class;
192 int ret;
193
194 BT_LOGD("Creating new mapped clock class: in-cc-addr=%p",
195 in_clock_class);
196
197 BT_ASSERT(md_maps);
198 BT_ASSERT(in_clock_class);
199
200 BT_ASSERT(!borrow_mapped_clock_class(md_maps, in_clock_class));
201
202 out_clock_class = bt_clock_class_create(self_comp);
203 if (!out_clock_class) {
204 BT_LOGE_STR("Cannot create clock class");
205 goto end;
206 }
207 /* If not, create a new one and add it to the mapping. */
208 ret = copy_clock_class_content(in_clock_class, out_clock_class);
209 if (ret) {
210 BT_LOGE_STR("Cannot copy clock class");
211 goto end;
212 }
213
214 g_hash_table_insert(md_maps->clock_class_map,
215 (gpointer) in_clock_class, out_clock_class);
216
217 BT_LOGD("Created new mapped clock class: in-cc-addr=%p, out-cc-addr=%p",
218 in_clock_class, out_clock_class);
219end:
220 return out_clock_class;
221}
222
223BT_HIDDEN
224int copy_stream_class_content(struct trace_ir_maps *ir_maps,
225 const bt_stream_class *in_stream_class,
226 bt_stream_class *out_stream_class)
227{
228 struct trace_ir_metadata_maps *md_maps;
229 const bt_clock_class *in_clock_class;
230 bt_clock_class *out_clock_class;
231 const bt_field_class *in_packet_context_fc, *in_common_context_fc;
232 bt_field_class *out_packet_context_fc, *out_common_context_fc;
233 bt_stream_class_status status;
234 const char *in_name;
235 int ret = 0;
236
237 BT_LOGD("Copying content of stream class: in-sc-addr=%p, out-sc-addr=%p",
238 in_stream_class, out_stream_class);
239
240 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, in_stream_class);
241 in_clock_class = bt_stream_class_borrow_default_clock_class_const(
242 in_stream_class);
243
244 if (in_clock_class) {
245 /* Copy the clock class. */
246 out_clock_class =
247 borrow_mapped_clock_class(md_maps, in_clock_class);
248 if (!out_clock_class) {
249 out_clock_class = create_new_mapped_clock_class(
250 ir_maps->self_comp, md_maps,
251 in_clock_class);
252 }
253 bt_stream_class_set_default_clock_class(out_stream_class,
254 out_clock_class);
255
256 }
257
649934d2
PP
258 bt_stream_class_set_packets_have_default_beginning_clock_snapshot(
259 out_stream_class,
260 bt_stream_class_packets_have_default_beginning_clock_snapshot(
261 in_stream_class));
262 bt_stream_class_set_packets_have_default_end_clock_snapshot(
263 out_stream_class,
264 bt_stream_class_packets_have_default_end_clock_snapshot(
265 in_stream_class));
266
ca9f27f3
FD
267 in_name = bt_stream_class_get_name(in_stream_class);
268 if (in_name) {
269 status = bt_stream_class_set_name(out_stream_class, in_name);
270 if (status != BT_STREAM_CLASS_STATUS_OK) {
271 BT_LOGE("Error set stream class name: out-sc-addr=%p, "
272 "name=%s", out_stream_class, in_name);
273 ret = -1;
274 goto error;
275 }
276 }
277
278 bt_stream_class_set_assigns_automatic_stream_id(out_stream_class,
279 BT_FALSE);
280 bt_stream_class_set_assigns_automatic_event_class_id(out_stream_class,
281 BT_FALSE);
282
283 /*
284 * Add the input packet context field class to the context to
285 * resolution in the further steps.
286 */
287 in_packet_context_fc =
288 bt_stream_class_borrow_packet_context_field_class_const(
289 in_stream_class);
290 md_maps->fc_resolving_ctx->packet_context =
291 in_packet_context_fc;
292
293 if (in_packet_context_fc) {
294 /* Copy packet context. */
295 out_packet_context_fc = create_field_class_copy(
296 md_maps, in_packet_context_fc);
297
298 ret = copy_field_class_content(md_maps,
299 in_packet_context_fc, out_packet_context_fc);
300 if (ret) {
301 ret = -1;
302 goto error;
303 }
304
305 status = bt_stream_class_set_packet_context_field_class(
306 out_stream_class, out_packet_context_fc);
307 if (status != BT_STREAM_CLASS_STATUS_OK) {
308 BT_LOGE("Error setting stream class' packet context "
309 "field class: sc-addr=%p, packet-fc-addr=%p",
310 out_stream_class, out_packet_context_fc);
311 ret = -1;
312 goto error;
313 }
314 }
315
316 /*
317 * Add the input common context field class to the context to
318 * resolution in the further steps.
319 */
320 in_common_context_fc =
321 bt_stream_class_borrow_event_common_context_field_class_const(
322 in_stream_class);
323 md_maps->fc_resolving_ctx->event_common_context =
324 in_common_context_fc;
325
326 if (in_common_context_fc) {
327 /* Copy common context. */
328 /* TODO: I find it a bit awkward to have this special function
329 * here to add the debug-info field class. I would like to
330 * abstract that.*/
331 out_common_context_fc = create_field_class_copy(
332 md_maps, in_common_context_fc);
333
334 ret = copy_event_common_context_field_class_content(
335 md_maps, ir_maps->debug_info_field_class_name,
336 in_common_context_fc, out_common_context_fc);
337 if (ret) {
338 goto error;
339 }
340
341 status = bt_stream_class_set_event_common_context_field_class(
342 out_stream_class, out_common_context_fc);
343 if (status != BT_STREAM_CLASS_STATUS_OK) {
344 BT_LOGE("Error setting stream class' packet context "
345 "field class: sc-addr=%p, packet-fc-addr=%p",
346 out_stream_class, out_common_context_fc);
347 ret = -1;
348 goto error;
349 }
350 }
351
352 /* Set packet snapshot boolean fields. */
353 BT_LOGD("Copied content of stream class: in-sc-addr=%p, out-sc-addr=%p",
354 in_stream_class, out_stream_class);
355error:
356 return ret;
357}
358
359BT_HIDDEN
360int copy_event_class_content(struct trace_ir_maps *ir_maps,
361 const bt_event_class *in_event_class,
362 bt_event_class *out_event_class)
363{
364 struct trace_ir_metadata_maps *md_maps;
365 const char *in_event_class_name, *in_emf_uri;
366 bt_property_availability prop_avail;
367 bt_event_class_log_level log_level;
368 bt_event_class_status status;
369 bt_field_class *out_specific_context_fc, *out_payload_fc;
370 const bt_field_class *in_event_specific_context, *in_event_payload;
371 int ret = 0;
372
373 BT_LOGD("Copying content of event class: in-ec-addr=%p, out-ec-addr=%p",
374 in_event_class, out_event_class);
375
376 /* Copy event class name. */
377 in_event_class_name = bt_event_class_get_name(in_event_class);
378 if (in_event_class_name) {
379 status = bt_event_class_set_name(out_event_class, in_event_class_name);
380 if (status != BT_EVENT_CLASS_STATUS_OK) {
381 BT_LOGE("Error setting event class' name: ec-addr=%p, "
382 "name=%s", out_event_class, in_event_class_name);
383 ret = -1;
384 goto error;
385 }
386 }
387
388 /* Copy event class loglevel. */
389 prop_avail = bt_event_class_get_log_level(in_event_class, &log_level);
390 if (prop_avail == BT_PROPERTY_AVAILABILITY_AVAILABLE) {
391 bt_event_class_set_log_level(out_event_class,
392 log_level);
393 }
394
395 /* Copy event class emf uri. */
396 in_emf_uri = bt_event_class_get_emf_uri(in_event_class);
397 if (in_emf_uri) {
398 status = bt_event_class_set_emf_uri(out_event_class, in_emf_uri);
399 if (status != BT_EVENT_CLASS_STATUS_OK) {
400 BT_LOGE("Error setting event class' emf uri: ec-addr=%p, "
401 "emf uri=%s", out_event_class, in_emf_uri);
402 ret = -1;
403 goto error;
404 }
405 }
406
407 md_maps = borrow_metadata_maps_from_input_event_class(ir_maps, in_event_class);
408 /*
409 * Add the input event class' specific ctx to te
410 * context.
411 */
412 in_event_specific_context =
413 bt_event_class_borrow_specific_context_field_class_const(
414 in_event_class);
415
416 md_maps->fc_resolving_ctx->event_specific_context =
417 in_event_specific_context;
418
419 if (in_event_specific_context) {
420 /* Copy the specific context of this event class. */
421 out_specific_context_fc = create_field_class_copy(md_maps,
422 in_event_specific_context);
423
5e1abef6 424 ret = copy_field_class_content(md_maps,
ca9f27f3
FD
425 in_event_specific_context, out_specific_context_fc);
426 if (ret) {
427 goto error;
428 }
429 /*
430 * Add the output specific context to the output event
431 * class.
432 */
433 status = bt_event_class_set_specific_context_field_class(
434 out_event_class, out_specific_context_fc);
435 if (status != BT_EVENT_CLASS_STATUS_OK) {
436 BT_LOGE("Error setting event class' specific context "
437 "field class: ec-addr=%p, ctx-fc-addr=%p",
438 out_event_class, out_specific_context_fc);
439 ret = -1;
440 goto error;
441 }
442 }
443
444 /*
445 * Add the input event class' payload field class to
446 * the context.
447 */
448 in_event_payload = bt_event_class_borrow_payload_field_class_const(
449 in_event_class);
450
451 md_maps->fc_resolving_ctx->event_payload = in_event_payload;
452
453 if (in_event_payload) {
454 /* Copy the payload of this event class. */
455 out_payload_fc = create_field_class_copy(md_maps,
456 in_event_payload);
5e1abef6 457 ret = copy_field_class_content(md_maps,
ca9f27f3
FD
458 in_event_payload, out_payload_fc);
459 if (ret) {
460 goto error;
461 }
462
463 /* Add the output payload to the output event class. */
464 status = bt_event_class_set_payload_field_class(
465 out_event_class, out_payload_fc);
466 if (status != BT_EVENT_CLASS_STATUS_OK) {
467 BT_LOGE("Error setting event class' payload "
468 "field class: ec-addr=%p, payload-fc-addr=%p",
469 out_event_class, out_payload_fc);
470 ret = -1;
471 goto error;
472 }
473 }
474
475 BT_LOGD("Copied content of event class: in-ec-addr=%p, out-ec-addr=%p",
476 in_event_class, out_event_class);
477error:
478 return ret;
479}
480
481BT_HIDDEN
482int copy_event_common_context_field_class_content(
483 struct trace_ir_metadata_maps *md_maps,
484 const char *debug_info_fc_name,
485 const bt_field_class *in_field_class,
486 bt_field_class *out_field_class)
487{
488 bt_field_class_status status;
489 bt_field_class *debug_field_class = NULL, *bin_field_class = NULL,
490 *func_field_class = NULL, *src_field_class = NULL;
491 int ret = 0;
492
493 BT_LOGD("Copying content of event common context field class: "
494 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
495
496 /* Copy the content of the input common context. */
497 ret = copy_field_class_content(md_maps, in_field_class, out_field_class);
498 if (ret) {
499 goto error;
500 }
501
502 /*
503 * If this event common context has the necessary fields to compute the
504 * debug information append the debug-info field class to the event
505 * common context.
506 */
507 if (is_event_common_ctx_dbg_info_compatible(in_field_class, debug_info_fc_name)) {
508 /*
509 * The struct field and 3 sub-fields are not stored in the
510 * field class map because they don't have input equivalent.
511 * We need to put our reference each of these field classes
512 * once they are added to their respective containing field
513 * classes.
514 */
515 debug_field_class = bt_field_class_structure_create(
516 md_maps->output_trace_class);
517 if (!debug_field_class) {
518 BT_LOGE_STR("Failed to create debug_info structure.");
519 ret = -1;
520 goto error;
521 }
522
523 bin_field_class = bt_field_class_string_create(
524 md_maps->output_trace_class);
525 if (!bin_field_class) {
526 BT_LOGE_STR("Failed to create string for field=bin.");
527 ret = -1;
528 goto error;
529 }
530
531 func_field_class = bt_field_class_string_create(
532 md_maps->output_trace_class);
533 if (!func_field_class) {
534 BT_LOGE_STR("Failed to create string for field=func.");
535 ret = -1;
536 goto error;
537 }
538
539 src_field_class = bt_field_class_string_create(
540 md_maps->output_trace_class);
541 if (!src_field_class) {
542 BT_LOGE_STR("Failed to create string for field=src.");
543 ret = -1;
544 goto error;
545 }
546
547 status = bt_field_class_structure_append_member(
548 debug_field_class, "bin", bin_field_class);
549 if (status != BT_FIELD_CLASS_STATUS_OK) {
550 BT_LOGE_STR("Failed to add a field to debug_info "
551 "struct: field=bin.");
552 ret = -1;
553 goto error;
554 }
555 BT_FIELD_CLASS_PUT_REF_AND_RESET(bin_field_class);
556
557 status = bt_field_class_structure_append_member(
558 debug_field_class, "func", func_field_class);
559 if (status != BT_FIELD_CLASS_STATUS_OK) {
560 BT_LOGE_STR("Failed to add a field to debug_info "
561 "struct: field=func.");
562 ret = -1;
563 goto error;
564 }
565 BT_FIELD_CLASS_PUT_REF_AND_RESET(func_field_class);
566
567 status = bt_field_class_structure_append_member(
568 debug_field_class, "src", src_field_class);
569 if (status != BT_FIELD_CLASS_STATUS_OK) {
570 BT_LOGE_STR("Failed to add a field to debug_info "
571 "struct: field=src.");
572 ret = -1;
573 goto error;
574 }
575 BT_FIELD_CLASS_PUT_REF_AND_RESET(src_field_class);
576
577 /*Add the filled debug-info field class to the common context. */
578 status = bt_field_class_structure_append_member(out_field_class,
579 debug_info_fc_name,
580 debug_field_class);
581 if (status != BT_FIELD_CLASS_STATUS_OK) {
582 BT_LOGE_STR("Failed to add debug_info field to "
583 "event common context.");
584 ret = -1;
585 goto error;
586 }
587 BT_FIELD_CLASS_PUT_REF_AND_RESET(debug_field_class);
588 }
589 BT_LOGD("Copied content of event common context field class: "
590 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
591 goto end;
592
593error:
594 if (debug_field_class) {
595 bt_field_class_put_ref(debug_field_class);
596 }
597 if (bin_field_class) {
598 bt_field_class_put_ref(bin_field_class);
599 }
600 if (func_field_class) {
601 bt_field_class_put_ref(func_field_class);
602 }
603 if (src_field_class) {
604 bt_field_class_put_ref(src_field_class);
605 }
606end:
607 return ret;
608}
609
610BT_HIDDEN
611bt_field_class *create_field_class_copy(struct trace_ir_metadata_maps *md_maps,
612 const bt_field_class *in_field_class)
613{
614 return create_field_class_copy_internal(md_maps, in_field_class);
615}
616
617BT_HIDDEN
618int copy_field_class_content(struct trace_ir_metadata_maps *md_maps,
619 const bt_field_class *in_field_class,
620 bt_field_class *out_field_class)
621{
622 return copy_field_class_content_internal(md_maps, in_field_class,
623 out_field_class);
624}
This page took 0.049326 seconds and 4 git commands to generate.