lib: make packets and packet messages optional, disabled by default
[babeltrace.git] / src / plugins / lttng-utils / debug-info / trace-ir-metadata-copy.c
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_COMP_LOG_SELF_COMP self_comp
28 #define BT_LOG_OUTPUT_LEVEL log_level
29 #define BT_LOG_TAG "PLUGIN/FLT.LTTNG-UTILS.DEBUG-INFO/TRACE-IR-META-COPY"
30 #include "plugins/comp-logging.h"
31
32 #include <inttypes.h>
33 #include <stdint.h>
34
35 #include "common/assert.h"
36
37 #include "trace-ir-metadata-copy.h"
38 #include "trace-ir-metadata-field-class-copy.h"
39 #include "utils.h"
40
41 BT_HIDDEN
42 int copy_trace_class_content(const bt_trace_class *in_trace_class,
43 bt_trace_class *out_trace_class, bt_logging_level log_level,
44 bt_self_component *self_comp)
45 {
46 BT_COMP_LOGD("Copying content of trace class: in-tc-addr=%p, out-tc-addr=%p",
47 in_trace_class, out_trace_class);
48
49 /* Use the same stream class ids as in the origin trace class. */
50 bt_trace_class_set_assigns_automatic_stream_class_id(out_trace_class,
51 BT_FALSE);
52 BT_COMP_LOGD("Copied content of trace class: in-tc-addr=%p, out-tc-addr=%p",
53 in_trace_class, out_trace_class);
54 return 0;
55 }
56
57 static
58 int copy_clock_class_content(const bt_clock_class *in_clock_class,
59 bt_clock_class *out_clock_class, bt_logging_level log_level,
60 bt_self_component *self_comp)
61 {
62 const char *clock_class_name, *clock_class_description;
63 int64_t seconds;
64 uint64_t cycles;
65 bt_uuid in_uuid;
66 int ret = 0;
67
68 BT_COMP_LOGD("Copying content of clock class: in-cc-addr=%p, out-cc-addr=%p",
69 in_clock_class, out_clock_class);
70
71 clock_class_name = bt_clock_class_get_name(in_clock_class);
72
73 if (clock_class_name) {
74 if (bt_clock_class_set_name(out_clock_class, clock_class_name)
75 != BT_CLOCK_CLASS_SET_NAME_STATUS_OK) {
76 BT_COMP_LOGE("Error setting clock class' name cc-addr=%p, name=%p",
77 out_clock_class, clock_class_name);
78 out_clock_class = NULL;
79 ret = -1;
80 goto error;
81 }
82 }
83
84 clock_class_description = bt_clock_class_get_description(in_clock_class);
85
86 if (clock_class_description) {
87 if (bt_clock_class_set_description(out_clock_class,
88 clock_class_description) !=
89 BT_CLOCK_CLASS_SET_DESCRIPTION_STATUS_OK) {
90 BT_COMP_LOGE("Error setting clock class' description cc-addr=%p, "
91 "name=%p", out_clock_class, clock_class_description);
92 out_clock_class = NULL;
93 ret = -1;
94 goto error;
95 }
96 }
97
98 in_uuid = bt_clock_class_get_uuid(in_clock_class);
99 if (in_uuid) {
100 bt_clock_class_set_uuid(out_clock_class, in_uuid);
101 }
102
103 bt_clock_class_set_frequency(out_clock_class,
104 bt_clock_class_get_frequency(in_clock_class));
105 bt_clock_class_set_precision(out_clock_class,
106 bt_clock_class_get_precision(in_clock_class));
107 bt_clock_class_get_offset(in_clock_class, &seconds, &cycles);
108 bt_clock_class_set_offset(out_clock_class, seconds, cycles);
109 bt_clock_class_set_origin_is_unix_epoch(out_clock_class,
110 bt_clock_class_origin_is_unix_epoch(in_clock_class));
111
112 BT_COMP_LOGD("Copied content of clock class: in-cc-addr=%p, out-cc-addr=%p",
113 in_clock_class, out_clock_class);
114
115 error:
116 return ret;
117 }
118
119 static
120 bt_clock_class *borrow_mapped_clock_class(
121 struct trace_ir_metadata_maps *md_maps,
122 const bt_clock_class *in_clock_class)
123 {
124 BT_ASSERT(md_maps);
125 BT_ASSERT(in_clock_class);
126
127 return g_hash_table_lookup(md_maps->clock_class_map,
128 (gpointer) in_clock_class);
129 }
130
131 static
132 bt_clock_class *create_new_mapped_clock_class(
133 bt_self_component *self_comp,
134 struct trace_ir_metadata_maps *md_maps,
135 const bt_clock_class *in_clock_class)
136 {
137 bt_clock_class *out_clock_class;
138 int ret;
139 bt_logging_level log_level = md_maps->log_level;
140
141 BT_COMP_LOGD("Creating new mapped clock class: in-cc-addr=%p",
142 in_clock_class);
143
144 BT_ASSERT(md_maps);
145 BT_ASSERT(in_clock_class);
146
147 BT_ASSERT(!borrow_mapped_clock_class(md_maps, in_clock_class));
148
149 out_clock_class = bt_clock_class_create(self_comp);
150 if (!out_clock_class) {
151 BT_COMP_LOGE_STR("Cannot create clock class");
152 goto end;
153 }
154 /* If not, create a new one and add it to the mapping. */
155 ret = copy_clock_class_content(in_clock_class, out_clock_class,
156 log_level, self_comp);
157 if (ret) {
158 BT_COMP_LOGE_STR("Cannot copy clock class");
159 goto end;
160 }
161
162 g_hash_table_insert(md_maps->clock_class_map,
163 (gpointer) in_clock_class, out_clock_class);
164
165 BT_COMP_LOGD("Created new mapped clock class: in-cc-addr=%p, out-cc-addr=%p",
166 in_clock_class, out_clock_class);
167 end:
168 return out_clock_class;
169 }
170
171 BT_HIDDEN
172 int copy_stream_class_content(struct trace_ir_maps *ir_maps,
173 const bt_stream_class *in_stream_class,
174 bt_stream_class *out_stream_class)
175 {
176 struct trace_ir_metadata_maps *md_maps;
177 const bt_clock_class *in_clock_class;
178 bt_clock_class *out_clock_class;
179 const bt_field_class *in_packet_context_fc, *in_common_context_fc;
180 bt_field_class *out_packet_context_fc, *out_common_context_fc;
181 const char *in_name;
182 int ret = 0;
183 bt_logging_level log_level = ir_maps->log_level;
184 bt_self_component *self_comp = ir_maps->self_comp;
185
186 BT_COMP_LOGD("Copying content of stream class: in-sc-addr=%p, out-sc-addr=%p",
187 in_stream_class, out_stream_class);
188
189 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, in_stream_class);
190 in_clock_class = bt_stream_class_borrow_default_clock_class_const(
191 in_stream_class);
192
193 if (in_clock_class) {
194 /* Copy the clock class. */
195 out_clock_class =
196 borrow_mapped_clock_class(md_maps, in_clock_class);
197 if (!out_clock_class) {
198 out_clock_class = create_new_mapped_clock_class(
199 ir_maps->self_comp, md_maps,
200 in_clock_class);
201 }
202 bt_stream_class_set_default_clock_class(out_stream_class,
203 out_clock_class);
204
205 }
206
207 bt_stream_class_set_supports_packets(
208 out_stream_class,
209 bt_stream_class_supports_packets(in_stream_class),
210 bt_stream_class_packets_have_beginning_default_clock_snapshot(
211 in_stream_class),
212 bt_stream_class_packets_have_end_default_clock_snapshot(
213 in_stream_class));
214 bt_stream_class_set_supports_discarded_events(
215 out_stream_class,
216 bt_stream_class_supports_discarded_events(in_stream_class),
217 bt_stream_class_discarded_events_have_default_clock_snapshots(
218 in_stream_class));
219 bt_stream_class_set_supports_discarded_packets(
220 out_stream_class,
221 bt_stream_class_supports_discarded_packets(in_stream_class),
222 bt_stream_class_discarded_packets_have_default_clock_snapshots(
223 in_stream_class));
224
225 in_name = bt_stream_class_get_name(in_stream_class);
226 if (in_name) {
227 if (bt_stream_class_set_name(out_stream_class, in_name) !=
228 BT_STREAM_CLASS_SET_NAME_STATUS_OK) {
229 BT_COMP_LOGE("Error set stream class name: out-sc-addr=%p, "
230 "name=%s", out_stream_class, in_name);
231 ret = -1;
232 goto error;
233 }
234 }
235
236 bt_stream_class_set_assigns_automatic_stream_id(out_stream_class,
237 BT_FALSE);
238 bt_stream_class_set_assigns_automatic_event_class_id(out_stream_class,
239 BT_FALSE);
240
241 /*
242 * Add the input packet context field class to the context to
243 * resolution in the further steps.
244 */
245 in_packet_context_fc =
246 bt_stream_class_borrow_packet_context_field_class_const(
247 in_stream_class);
248 md_maps->fc_resolving_ctx->packet_context =
249 in_packet_context_fc;
250
251 if (in_packet_context_fc) {
252 /* Copy packet context. */
253 out_packet_context_fc = create_field_class_copy(
254 md_maps, in_packet_context_fc);
255
256 ret = copy_field_class_content(md_maps,
257 in_packet_context_fc, out_packet_context_fc);
258 if (ret) {
259 ret = -1;
260 goto error;
261 }
262
263 if (bt_stream_class_set_packet_context_field_class(
264 out_stream_class, out_packet_context_fc) !=
265 BT_STREAM_CLASS_SET_FIELD_CLASS_STATUS_OK) {
266 BT_COMP_LOGE("Error setting stream class' packet context "
267 "field class: sc-addr=%p, packet-fc-addr=%p",
268 out_stream_class, out_packet_context_fc);
269 ret = -1;
270 goto error;
271 }
272 }
273
274 /*
275 * Add the input common context field class to the context to
276 * resolution in the further steps.
277 */
278 in_common_context_fc =
279 bt_stream_class_borrow_event_common_context_field_class_const(
280 in_stream_class);
281 md_maps->fc_resolving_ctx->event_common_context =
282 in_common_context_fc;
283
284 if (in_common_context_fc) {
285 /* Copy common context. */
286 /* TODO: I find it a bit awkward to have this special function
287 * here to add the debug-info field class. I would like to
288 * abstract that.*/
289 out_common_context_fc = create_field_class_copy(
290 md_maps, in_common_context_fc);
291
292 ret = copy_event_common_context_field_class_content(
293 md_maps, ir_maps->debug_info_field_class_name,
294 in_common_context_fc, out_common_context_fc);
295 if (ret) {
296 goto error;
297 }
298
299 if (bt_stream_class_set_event_common_context_field_class(
300 out_stream_class, out_common_context_fc) !=
301 BT_STREAM_CLASS_SET_FIELD_CLASS_STATUS_OK) {
302 BT_COMP_LOGE("Error setting stream class' packet context "
303 "field class: sc-addr=%p, packet-fc-addr=%p",
304 out_stream_class, out_common_context_fc);
305 ret = -1;
306 goto error;
307 }
308 }
309
310 /* Set packet snapshot boolean fields. */
311 BT_COMP_LOGD("Copied content of stream class: in-sc-addr=%p, out-sc-addr=%p",
312 in_stream_class, out_stream_class);
313 error:
314 return ret;
315 }
316
317 BT_HIDDEN
318 int copy_event_class_content(struct trace_ir_maps *ir_maps,
319 const bt_event_class *in_event_class,
320 bt_event_class *out_event_class)
321 {
322 struct trace_ir_metadata_maps *md_maps;
323 const char *in_event_class_name, *in_emf_uri;
324 bt_property_availability prop_avail;
325 bt_event_class_log_level ec_log_level;
326 bt_field_class *out_specific_context_fc, *out_payload_fc;
327 const bt_field_class *in_event_specific_context, *in_event_payload;
328 int ret = 0;
329 bt_logging_level log_level = ir_maps->log_level;
330 bt_self_component *self_comp = ir_maps->self_comp;
331
332 BT_COMP_LOGD("Copying content of event class: in-ec-addr=%p, out-ec-addr=%p",
333 in_event_class, out_event_class);
334
335 /* Copy event class name. */
336 in_event_class_name = bt_event_class_get_name(in_event_class);
337 if (in_event_class_name) {
338 if (bt_event_class_set_name(out_event_class,
339 in_event_class_name) !=
340 BT_EVENT_CLASS_SET_NAME_STATUS_OK) {
341 BT_COMP_LOGE("Error setting event class' name: ec-addr=%p, "
342 "name=%s", out_event_class, in_event_class_name);
343 ret = -1;
344 goto error;
345 }
346 }
347
348 /* Copy event class loglevel. */
349 prop_avail = bt_event_class_get_log_level(in_event_class,
350 &ec_log_level);
351 if (prop_avail == BT_PROPERTY_AVAILABILITY_AVAILABLE) {
352 bt_event_class_set_log_level(out_event_class,
353 ec_log_level);
354 }
355
356 /* Copy event class emf uri. */
357 in_emf_uri = bt_event_class_get_emf_uri(in_event_class);
358 if (in_emf_uri) {
359 if (bt_event_class_set_emf_uri(out_event_class, in_emf_uri) !=
360 BT_EVENT_CLASS_SET_EMF_URI_STATUS_OK) {
361 BT_COMP_LOGE("Error setting event class' emf uri: ec-addr=%p, "
362 "emf uri=%s", out_event_class, in_emf_uri);
363 ret = -1;
364 goto error;
365 }
366 }
367
368 md_maps = borrow_metadata_maps_from_input_event_class(ir_maps, in_event_class);
369 /*
370 * Add the input event class' specific ctx to te
371 * context.
372 */
373 in_event_specific_context =
374 bt_event_class_borrow_specific_context_field_class_const(
375 in_event_class);
376
377 md_maps->fc_resolving_ctx->event_specific_context =
378 in_event_specific_context;
379
380 if (in_event_specific_context) {
381 /* Copy the specific context of this event class. */
382 out_specific_context_fc = create_field_class_copy(md_maps,
383 in_event_specific_context);
384
385 ret = copy_field_class_content(md_maps,
386 in_event_specific_context, out_specific_context_fc);
387 if (ret) {
388 goto error;
389 }
390 /*
391 * Add the output specific context to the output event
392 * class.
393 */
394 if (bt_event_class_set_specific_context_field_class(
395 out_event_class, out_specific_context_fc) !=
396 BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_OK) {
397 BT_COMP_LOGE("Error setting event class' specific context "
398 "field class: ec-addr=%p, ctx-fc-addr=%p",
399 out_event_class, out_specific_context_fc);
400 ret = -1;
401 goto error;
402 }
403 }
404
405 /*
406 * Add the input event class' payload field class to
407 * the context.
408 */
409 in_event_payload = bt_event_class_borrow_payload_field_class_const(
410 in_event_class);
411
412 md_maps->fc_resolving_ctx->event_payload = in_event_payload;
413
414 if (in_event_payload) {
415 /* Copy the payload of this event class. */
416 out_payload_fc = create_field_class_copy(md_maps,
417 in_event_payload);
418 ret = copy_field_class_content(md_maps,
419 in_event_payload, out_payload_fc);
420 if (ret) {
421 goto error;
422 }
423
424 /* Add the output payload to the output event class. */
425 if (bt_event_class_set_payload_field_class(
426 out_event_class, out_payload_fc) !=
427 BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_OK) {
428 BT_COMP_LOGE("Error setting event class' payload "
429 "field class: ec-addr=%p, payload-fc-addr=%p",
430 out_event_class, out_payload_fc);
431 ret = -1;
432 goto error;
433 }
434 }
435
436 BT_COMP_LOGD("Copied content of event class: in-ec-addr=%p, out-ec-addr=%p",
437 in_event_class, out_event_class);
438 error:
439 return ret;
440 }
441
442 BT_HIDDEN
443 int copy_event_common_context_field_class_content(
444 struct trace_ir_metadata_maps *md_maps,
445 const char *debug_info_fc_name,
446 const bt_field_class *in_field_class,
447 bt_field_class *out_field_class)
448 {
449 bt_field_class *debug_field_class = NULL, *bin_field_class = NULL,
450 *func_field_class = NULL, *src_field_class = NULL;
451 int ret = 0;
452 bt_logging_level log_level = md_maps->log_level;
453 bt_self_component *self_comp = md_maps->self_comp;
454
455 BT_COMP_LOGD("Copying content of event common context field class: "
456 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
457
458 /* Copy the content of the input common context. */
459 ret = copy_field_class_content(md_maps, in_field_class, out_field_class);
460 if (ret) {
461 goto error;
462 }
463
464 /*
465 * If this event common context has the necessary fields to compute the
466 * debug information append the debug-info field class to the event
467 * common context.
468 */
469 if (is_event_common_ctx_dbg_info_compatible(in_field_class, debug_info_fc_name)) {
470 /*
471 * The struct field and 3 sub-fields are not stored in the
472 * field class map because they don't have input equivalent.
473 * We need to put our reference each of these field classes
474 * once they are added to their respective containing field
475 * classes.
476 */
477 debug_field_class = bt_field_class_structure_create(
478 md_maps->output_trace_class);
479 if (!debug_field_class) {
480 BT_COMP_LOGE_STR("Failed to create debug_info structure.");
481 ret = -1;
482 goto error;
483 }
484
485 bin_field_class = bt_field_class_string_create(
486 md_maps->output_trace_class);
487 if (!bin_field_class) {
488 BT_COMP_LOGE_STR("Failed to create string for field=bin.");
489 ret = -1;
490 goto error;
491 }
492
493 func_field_class = bt_field_class_string_create(
494 md_maps->output_trace_class);
495 if (!func_field_class) {
496 BT_COMP_LOGE_STR("Failed to create string for field=func.");
497 ret = -1;
498 goto error;
499 }
500
501 src_field_class = bt_field_class_string_create(
502 md_maps->output_trace_class);
503 if (!src_field_class) {
504 BT_COMP_LOGE_STR("Failed to create string for field=src.");
505 ret = -1;
506 goto error;
507 }
508
509 if (bt_field_class_structure_append_member(
510 debug_field_class, "bin", bin_field_class) !=
511 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
512 BT_COMP_LOGE_STR("Failed to add a field to debug_info "
513 "struct: field=bin.");
514 ret = -1;
515 goto error;
516 }
517 BT_FIELD_CLASS_PUT_REF_AND_RESET(bin_field_class);
518
519 if (bt_field_class_structure_append_member(
520 debug_field_class, "func", func_field_class) !=
521 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
522 BT_COMP_LOGE_STR("Failed to add a field to debug_info "
523 "struct: field=func.");
524 ret = -1;
525 goto error;
526 }
527 BT_FIELD_CLASS_PUT_REF_AND_RESET(func_field_class);
528
529 if (bt_field_class_structure_append_member(
530 debug_field_class, "src", src_field_class) !=
531 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
532 BT_COMP_LOGE_STR("Failed to add a field to debug_info "
533 "struct: field=src.");
534 ret = -1;
535 goto error;
536 }
537 BT_FIELD_CLASS_PUT_REF_AND_RESET(src_field_class);
538
539 /*Add the filled debug-info field class to the common context. */
540 if (bt_field_class_structure_append_member(out_field_class,
541 debug_info_fc_name, debug_field_class) !=
542 BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK) {
543 BT_COMP_LOGE_STR("Failed to add debug_info field to "
544 "event common context.");
545 ret = -1;
546 goto error;
547 }
548 BT_FIELD_CLASS_PUT_REF_AND_RESET(debug_field_class);
549 }
550 BT_COMP_LOGD("Copied content of event common context field class: "
551 "in-fc-addr=%p, out-fc-addr=%p", in_field_class, out_field_class);
552 goto end;
553
554 error:
555 if (debug_field_class) {
556 bt_field_class_put_ref(debug_field_class);
557 }
558 if (bin_field_class) {
559 bt_field_class_put_ref(bin_field_class);
560 }
561 if (func_field_class) {
562 bt_field_class_put_ref(func_field_class);
563 }
564 if (src_field_class) {
565 bt_field_class_put_ref(src_field_class);
566 }
567 end:
568 return ret;
569 }
570
571 BT_HIDDEN
572 bt_field_class *create_field_class_copy(struct trace_ir_metadata_maps *md_maps,
573 const bt_field_class *in_field_class)
574 {
575 return create_field_class_copy_internal(md_maps, in_field_class);
576 }
577
578 BT_HIDDEN
579 int copy_field_class_content(struct trace_ir_metadata_maps *md_maps,
580 const bt_field_class *in_field_class,
581 bt_field_class *out_field_class)
582 {
583 return copy_field_class_content_internal(md_maps, in_field_class,
584 out_field_class);
585 }
This page took 0.046239 seconds and 4 git commands to generate.