Fix: flt.lttng-utils.debug-info: Error in src line reporting
[babeltrace.git] / plugins / lttng-utils / trace-ir-mapping.c
1 /*
2 * Babeltrace - Mapping of IR metadata and data object between input and output
3 * trace
4 *
5 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
6 * Copyright (c) 2018 Philippe Proulx <pproulx@efficios.com>
7 * Copyright (c) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * SOFTWARE.
26 */
27
28 #define BT_LOG_TAG "PLUGIN-LTTNG-UTILS-DEBUG-INFO-TRACE-IR-MAPPING"
29 #include "logging.h"
30
31 #include <stdbool.h>
32
33 #include <babeltrace/assert-internal.h>
34 #include <babeltrace/babeltrace.h>
35 /* For bt_property_availability */
36 #include <babeltrace/property.h>
37
38 #include "debug-info.h"
39 #include "trace-ir-data-copy.h"
40 #include "trace-ir-mapping.h"
41 #include "trace-ir-metadata-copy.h"
42
43 static
44 bt_trace_class *create_new_mapped_trace_class(struct trace_ir_maps *ir_maps,
45 const bt_trace_class *in_trace_class)
46 {
47 int ret;
48 bt_trace_class *out_trace_class;
49
50 BT_LOGD("Creating new mapped trace class: in-tc-addr=%p", in_trace_class);
51
52 BT_ASSERT(ir_maps);
53 BT_ASSERT(in_trace_class);
54
55 /* Create the ouput trace class. */
56 out_trace_class = bt_trace_class_create(ir_maps->self_comp);
57 if (!out_trace_class) {
58 BT_LOGE_STR("Error create output trace class");
59 goto end;
60 }
61
62 /* If not, create a new one and add it to the mapping. */
63 ret = copy_trace_class_content(in_trace_class, out_trace_class);
64 if (ret) {
65 BT_LOGE_STR("Error copy content to output trace class");
66 out_trace_class = NULL;
67 goto end;
68 }
69
70 BT_LOGD("Created new mapped trace class: in-tc-addr=%p, out-tc-addr=%p",
71 in_trace_class, out_trace_class);
72
73 end:
74 return out_trace_class;
75 }
76
77 static
78 bt_trace *create_new_mapped_trace(struct trace_ir_maps *ir_maps,
79 const bt_trace *in_trace)
80 {
81 bt_trace *out_trace;
82 const bt_trace_class *in_trace_class;
83 struct trace_ir_metadata_maps *metadata_maps;
84
85 BT_LOGD("Creating new mapped trace: in-t-addr=%p", in_trace);
86 BT_ASSERT(ir_maps);
87 BT_ASSERT(in_trace);
88
89 in_trace_class = bt_trace_borrow_class_const(in_trace);
90 metadata_maps = borrow_metadata_maps_from_input_trace_class(ir_maps,
91 in_trace_class);
92
93 if (!metadata_maps->output_trace_class) {
94 metadata_maps->output_trace_class =
95 create_new_mapped_trace_class(ir_maps, in_trace_class);
96 if (!metadata_maps->output_trace_class) {
97 out_trace = NULL;
98 goto end;
99 }
100 }
101
102 out_trace = bt_trace_create(metadata_maps->output_trace_class);
103 if (!out_trace) {
104 BT_LOGE_STR("Error create output trace");
105 goto end;
106 }
107
108 /* If not, create a new one and add it to the mapping. */
109 copy_trace_content(in_trace, out_trace);
110
111 BT_LOGD("Created new mapped trace: in-t-addr=%p, out-t-addr=%p",
112 in_trace, out_trace);
113 end:
114 return out_trace;
115 }
116
117 static
118 bt_stream_class *borrow_mapped_stream_class(struct trace_ir_metadata_maps *md_maps,
119 const bt_stream_class *in_stream_class)
120 {
121 BT_ASSERT(md_maps);
122 BT_ASSERT(in_stream_class);
123
124 return g_hash_table_lookup(md_maps->stream_class_map,
125 (gpointer) in_stream_class);
126 }
127
128 static
129 bt_stream_class *create_new_mapped_stream_class(struct trace_ir_maps *ir_maps,
130 const bt_stream_class *in_stream_class)
131 {
132 int ret;
133 bt_stream_class *out_stream_class;
134 struct trace_ir_metadata_maps *md_maps;
135
136 BT_LOGD("Creating new mapped stream class: in-sc-addr=%p",
137 in_stream_class);
138
139 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps,
140 in_stream_class);
141
142 BT_ASSERT(md_maps);
143 BT_ASSERT(in_stream_class);
144 BT_ASSERT(!borrow_mapped_stream_class(md_maps, in_stream_class));
145
146 /* Create an out_stream_class. */
147 out_stream_class = bt_stream_class_create_with_id(
148 md_maps->output_trace_class,
149 bt_stream_class_get_id(in_stream_class));
150 if (!out_stream_class) {
151 BT_LOGE_STR("Error create output stream class");
152 goto end;
153 }
154
155 /* If not, create a new one and add it to the mapping. */
156 ret = copy_stream_class_content(ir_maps, in_stream_class,
157 out_stream_class);
158 if (ret) {
159 BT_LOGE_STR("Error copy content to output stream class");
160 out_stream_class = NULL;
161 goto end;
162 }
163
164 g_hash_table_insert(md_maps->stream_class_map,
165 (gpointer) in_stream_class, out_stream_class);
166
167 BT_LOGD("Created new mapped stream class: in-sc-addr=%p, out-sc-addr=%p",
168 in_stream_class, out_stream_class);
169
170 end:
171 return out_stream_class;
172 }
173
174 static
175 bt_stream *borrow_mapped_stream(struct trace_ir_data_maps *d_maps,
176 const bt_stream *in_stream)
177 {
178 BT_ASSERT(d_maps);
179 BT_ASSERT(in_stream);
180
181 return g_hash_table_lookup(d_maps->stream_map, (gpointer) in_stream);
182 }
183
184 BT_HIDDEN
185 bt_stream *trace_ir_mapping_create_new_mapped_stream(
186 struct trace_ir_maps *ir_maps,
187 const bt_stream *in_stream)
188 {
189 struct trace_ir_data_maps *d_maps;
190 struct trace_ir_metadata_maps *md_maps;
191 const bt_stream_class *in_stream_class;
192 const bt_trace *in_trace;
193 bt_stream_class *out_stream_class;
194 bt_stream *out_stream = NULL;
195
196 BT_LOGD("Creating new mapped stream: in-s-addr=%p", in_stream);
197
198 BT_ASSERT(ir_maps);
199 BT_ASSERT(in_stream);
200
201 in_trace = bt_stream_borrow_trace_const(in_stream);
202
203 d_maps = borrow_data_maps_from_input_trace(ir_maps, in_trace);
204 if (!d_maps->output_trace) {
205 d_maps->output_trace = create_new_mapped_trace(ir_maps, in_trace);
206 if (!d_maps->output_trace) {
207 goto end;
208 }
209 }
210
211 BT_ASSERT(d_maps->output_trace);
212 BT_ASSERT(!borrow_mapped_stream(d_maps, in_stream));
213
214 in_stream_class = bt_stream_borrow_class_const(in_stream);
215 if (bt_stream_class_default_clock_is_always_known(in_stream_class)
216 == BT_FALSE) {
217 BT_LOGE("Stream class default clock class is not always "
218 "known: in-sc-addr=%p", in_stream_class);
219 goto end;
220 }
221
222 md_maps = borrow_metadata_maps_from_input_stream_class(ir_maps, in_stream_class);
223 out_stream_class = borrow_mapped_stream_class(md_maps, in_stream_class);
224 if (!out_stream_class) {
225 out_stream_class = create_new_mapped_stream_class(ir_maps,
226 in_stream_class);
227 if (!out_stream_class) {
228 goto end;
229 }
230 }
231 BT_ASSERT(out_stream_class);
232
233 out_stream = bt_stream_create_with_id(out_stream_class,
234 d_maps->output_trace, bt_stream_get_id(in_stream));
235 if (!out_stream) {
236 BT_LOGE_STR("Error creating output stream");
237 goto end;
238 }
239 /*
240 * Release our ref since the trace object will be managing the life
241 * time of the stream objects.
242 */
243
244 copy_stream_content(in_stream, out_stream);
245
246 g_hash_table_insert(d_maps->stream_map, (gpointer) in_stream,
247 out_stream);
248
249 BT_LOGD("Created new mapped stream: in-s-addr=%p, out-s-addr=%p",
250 in_stream, out_stream);
251
252 end:
253 return out_stream;
254 }
255
256 BT_HIDDEN
257 bt_stream *trace_ir_mapping_borrow_mapped_stream(struct trace_ir_maps *ir_maps,
258 const bt_stream *in_stream)
259 {
260 BT_ASSERT(ir_maps);
261 BT_ASSERT(in_stream);
262 struct trace_ir_data_maps *d_maps;
263
264 d_maps = borrow_data_maps_from_input_stream(ir_maps, in_stream);
265 /* Return the mapped stream. */
266 return borrow_mapped_stream(d_maps, in_stream);
267 }
268
269 static inline
270 bt_event_class *borrow_mapped_event_class(struct trace_ir_metadata_maps *md_maps,
271 const bt_event_class *in_event_class)
272 {
273 return g_hash_table_lookup(md_maps->event_class_map,
274 (gpointer) in_event_class);
275 }
276
277 BT_HIDDEN
278 bt_event_class *trace_ir_mapping_create_new_mapped_event_class(
279 struct trace_ir_maps *ir_maps,
280 const bt_event_class *in_event_class)
281 {
282 bt_event_class *out_event_class;
283 const bt_trace_class *in_trace_class;
284 const bt_stream_class *in_stream_class;
285 bt_stream_class *out_stream_class;
286 struct trace_ir_metadata_maps *md_maps;
287 int ret;
288
289 BT_LOGD("Creating new mapped event class: in-ec-addr=%p",
290 in_event_class);
291
292 BT_ASSERT(ir_maps);
293 BT_ASSERT(in_event_class);
294
295 in_trace_class = bt_stream_class_borrow_trace_class_const(
296 bt_event_class_borrow_stream_class_const(
297 in_event_class));
298
299 md_maps = borrow_metadata_maps_from_input_trace_class(ir_maps, in_trace_class);
300
301 BT_ASSERT(!borrow_mapped_event_class(md_maps, in_event_class));
302
303 in_stream_class =
304 bt_event_class_borrow_stream_class_const(in_event_class);
305 BT_ASSERT(in_stream_class);
306
307 /* Get the right output stream class to add the new event class to. */
308 out_stream_class = borrow_mapped_stream_class(md_maps, in_stream_class);
309 BT_ASSERT(out_stream_class);
310
311 /* Create an output event class. */
312 out_event_class = bt_event_class_create_with_id(out_stream_class,
313 bt_event_class_get_id(in_event_class));
314 if (!out_event_class) {
315 BT_LOGE_STR("Error creating output event class");
316 goto end;
317 }
318
319 /* If not, create a new one and add it to the mapping. */
320 ret = copy_event_class_content(ir_maps, in_event_class,
321 out_event_class);
322 if (ret) {
323 BT_LOGE_STR("Error copy content to output event class");
324 out_event_class = NULL;
325 goto end;
326 }
327
328 g_hash_table_insert(md_maps->event_class_map,
329 (gpointer) in_event_class, out_event_class);
330
331 BT_LOGD("Created new mapped event class: in-ec-addr=%p, out-ec-addr=%p",
332 in_event_class, out_event_class);
333
334 end:
335 return out_event_class;
336 }
337
338 BT_HIDDEN
339 bt_event_class *trace_ir_mapping_borrow_mapped_event_class(
340 struct trace_ir_maps *ir_maps,
341 const bt_event_class *in_event_class)
342 {
343 struct trace_ir_metadata_maps *md_maps;
344
345 BT_ASSERT(ir_maps);
346 BT_ASSERT(in_event_class);
347
348 md_maps = borrow_metadata_maps_from_input_event_class(ir_maps, in_event_class);
349
350 /* Return the mapped event_class. */
351 return borrow_mapped_event_class(md_maps, in_event_class);
352 }
353
354 static inline
355 bt_packet *borrow_mapped_packet(struct trace_ir_data_maps *d_maps,
356 const bt_packet *in_packet)
357 {
358 BT_ASSERT(d_maps);
359 BT_ASSERT(in_packet);
360
361 return g_hash_table_lookup(d_maps->packet_map,
362 (gpointer) in_packet);
363 }
364
365 BT_HIDDEN
366 bt_packet *trace_ir_mapping_create_new_mapped_packet(
367 struct trace_ir_maps *ir_maps,
368 const bt_packet *in_packet)
369 {
370 struct trace_ir_data_maps *d_maps;
371 const bt_trace *in_trace;
372 const bt_stream *in_stream;
373 bt_packet *out_packet;
374 bt_stream *out_stream;
375
376 BT_LOGD("Creating new mapped packet: in-p-addr=%p", in_packet);
377
378 in_stream = bt_packet_borrow_stream_const(in_packet);
379 in_trace = bt_stream_borrow_trace_const(in_stream);
380 d_maps = borrow_data_maps_from_input_trace(ir_maps, in_trace);
381
382 /* There should never be a mapped packet. */
383 BT_ASSERT(!borrow_mapped_packet(d_maps, in_packet));
384
385 BT_ASSERT(in_stream);
386
387 /* Get output stream corresponding to this input stream. */
388 out_stream = borrow_mapped_stream(d_maps, in_stream);
389 BT_ASSERT(out_stream);
390
391 /* Create the output packet. */
392 out_packet = bt_packet_create(out_stream);
393 if (!out_packet) {
394 BT_LOGE_STR("Error create output packet");
395 goto end;
396 }
397
398 /*
399 * Release our ref since the stream object will be managing the life
400 * time of the packet objects.
401 */
402 copy_packet_content(in_packet, out_packet);
403
404 g_hash_table_insert(d_maps->packet_map,
405 (gpointer) in_packet, out_packet);
406
407 BT_LOGD("Created new mapped packet: in-p-addr=%p, out-p-addr=%p",
408 in_packet, out_packet);
409
410 end:
411 return out_packet;
412 }
413
414 BT_HIDDEN
415 bt_packet *trace_ir_mapping_borrow_mapped_packet(struct trace_ir_maps *ir_maps,
416 const bt_packet *in_packet)
417 {
418 struct trace_ir_data_maps *d_maps;
419 BT_ASSERT(ir_maps);
420 BT_ASSERT(in_packet);
421
422 d_maps = borrow_data_maps_from_input_packet(ir_maps, in_packet);
423
424 return borrow_mapped_packet(d_maps, in_packet);
425 }
426
427 BT_HIDDEN
428 void trace_ir_mapping_remove_mapped_packet(struct trace_ir_maps *ir_maps,
429 const bt_packet *in_packet)
430 {
431 gboolean ret;
432
433 struct trace_ir_data_maps *d_maps;
434 BT_ASSERT(ir_maps);
435 BT_ASSERT(in_packet);
436
437 d_maps = borrow_data_maps_from_input_packet(ir_maps, in_packet);
438
439 ret = g_hash_table_remove(d_maps->packet_map, in_packet);
440
441 BT_ASSERT(ret);
442 }
443
444 BT_HIDDEN
445 void trace_ir_mapping_remove_mapped_stream(struct trace_ir_maps *ir_maps,
446 const bt_stream *in_stream)
447 {
448 gboolean ret;
449 struct trace_ir_data_maps *d_maps;
450
451 BT_ASSERT(ir_maps);
452 BT_ASSERT(in_stream);
453
454 d_maps = borrow_data_maps_from_input_stream(ir_maps, in_stream);
455
456 ret = g_hash_table_remove(d_maps->stream_map, in_stream);
457
458 BT_ASSERT(ret);
459 }
460
461 static
462 void trace_ir_metadata_maps_remove_func(const bt_trace_class *in_trace_class,
463 void *data)
464 {
465 struct trace_ir_maps *maps = (struct trace_ir_maps *) data;
466 if (maps->metadata_maps) {
467 gboolean ret;
468 ret = g_hash_table_remove(maps->metadata_maps,
469 (gpointer) in_trace_class);
470 BT_ASSERT(ret);
471 }
472 }
473
474 static
475 void trace_ir_data_maps_remove_func(const bt_trace *in_trace, void *data)
476 {
477 struct trace_ir_maps *maps = (struct trace_ir_maps *) data;
478 if (maps->data_maps) {
479 gboolean ret;
480 ret = g_hash_table_remove(maps->data_maps, (gpointer) in_trace);
481 BT_ASSERT(ret);
482 }
483 }
484
485 struct trace_ir_data_maps *trace_ir_data_maps_create(struct trace_ir_maps *ir_maps,
486 const bt_trace *in_trace)
487 {
488 struct trace_ir_data_maps *d_maps =
489 g_new0(struct trace_ir_data_maps, 1);
490 if (!d_maps) {
491 BT_LOGE_STR("Error allocating trace_ir_maps");
492 goto error;
493 }
494
495 d_maps->input_trace = in_trace;
496
497 /* Create the hashtables used to map data objects. */
498 d_maps->stream_map = g_hash_table_new_full(g_direct_hash,
499 g_direct_equal, NULL,(GDestroyNotify) bt_stream_put_ref);
500 d_maps->packet_map = g_hash_table_new_full(g_direct_hash,
501 g_direct_equal, NULL,(GDestroyNotify) bt_packet_put_ref);
502
503 bt_trace_add_destruction_listener(in_trace, trace_ir_data_maps_remove_func,
504 ir_maps, &d_maps->destruction_listener_id);
505 error:
506 return d_maps;
507 }
508
509 struct trace_ir_metadata_maps *trace_ir_metadata_maps_create(
510 struct trace_ir_maps *ir_maps,
511 const bt_trace_class *in_trace_class)
512 {
513 struct trace_ir_metadata_maps *md_maps =
514 g_new0(struct trace_ir_metadata_maps, 1);
515 if (!md_maps) {
516 BT_LOGE_STR("Error allocating trace_ir_maps");
517 goto error;
518 }
519
520 md_maps->input_trace_class = in_trace_class;
521 /*
522 * Create the field class resolving context. This is needed to keep
523 * track of the field class already copied in order to do the field
524 * path resolution correctly.
525 */
526 md_maps->fc_resolving_ctx =
527 g_new0(struct field_class_resolving_context, 1);
528 if (!md_maps->fc_resolving_ctx) {
529 BT_LOGE_STR("Error allocating field_class_resolving_context");
530 goto error;
531 }
532
533 /* Create the hashtables used to map metadata objects. */
534 md_maps->stream_class_map = g_hash_table_new_full(g_direct_hash,
535 g_direct_equal, NULL, (GDestroyNotify) bt_stream_class_put_ref);
536 md_maps->event_class_map = g_hash_table_new_full(g_direct_hash,
537 g_direct_equal, NULL, (GDestroyNotify) bt_event_class_put_ref);
538 md_maps->field_class_map = g_hash_table_new_full(g_direct_hash,
539 g_direct_equal, NULL, (GDestroyNotify) bt_field_class_put_ref);
540 md_maps->clock_class_map = g_hash_table_new_full(g_direct_hash,
541 g_direct_equal, NULL, (GDestroyNotify) bt_clock_class_put_ref);
542
543 bt_trace_class_add_destruction_listener(in_trace_class,
544 trace_ir_metadata_maps_remove_func,
545 ir_maps, &md_maps->destruction_listener_id);
546 error:
547 return md_maps;
548 }
549
550 BT_HIDDEN
551 void trace_ir_data_maps_destroy(struct trace_ir_data_maps *maps)
552 {
553 bt_trace_status status;
554 if (!maps) {
555 return;
556 }
557
558 if (maps->packet_map) {
559 g_hash_table_destroy(maps->packet_map);
560 }
561
562 if (maps->stream_map) {
563 g_hash_table_destroy(maps->stream_map);
564 }
565
566 if (maps->output_trace) {
567 bt_trace_put_ref(maps->output_trace);
568 }
569
570 status = bt_trace_remove_destruction_listener(maps->input_trace,
571 maps->destruction_listener_id);
572 if (status != BT_TRACE_STATUS_OK) {
573 BT_LOGD("Trace destruction listener removal failed.");
574 }
575
576 g_free(maps);
577 }
578
579 BT_HIDDEN
580 void trace_ir_metadata_maps_destroy(struct trace_ir_metadata_maps *maps)
581 {
582 bt_trace_class_status status;
583 if (!maps) {
584 return;
585 }
586
587 if (maps->stream_class_map) {
588 g_hash_table_destroy(maps->stream_class_map);
589 }
590
591 if (maps->event_class_map) {
592 g_hash_table_destroy(maps->event_class_map);
593 }
594
595 if (maps->field_class_map) {
596 g_hash_table_destroy(maps->field_class_map);
597 }
598
599 if (maps->clock_class_map) {
600 g_hash_table_destroy(maps->clock_class_map);
601 }
602
603 if (maps->fc_resolving_ctx) {
604 g_free(maps->fc_resolving_ctx);
605 }
606
607 if (maps->output_trace_class) {
608 bt_trace_class_put_ref(maps->output_trace_class);
609 }
610
611 status = bt_trace_class_remove_destruction_listener(maps->input_trace_class,
612 maps->destruction_listener_id);
613 if (status != BT_TRACE_CLASS_STATUS_OK) {
614 BT_LOGD("Trace destruction listener removal failed.");
615 }
616
617 g_free(maps);
618 }
619
620 void trace_ir_maps_clear(struct trace_ir_maps *maps)
621 {
622 if (maps->data_maps) {
623 g_hash_table_remove_all(maps->data_maps);
624 }
625
626 if (maps->metadata_maps) {
627 g_hash_table_remove_all(maps->metadata_maps);
628 }
629 }
630
631 BT_HIDDEN
632 void trace_ir_maps_destroy(struct trace_ir_maps *maps)
633 {
634 if (!maps) {
635 return;
636 }
637
638 if (maps->debug_info_field_class_name) {
639 g_free(maps->debug_info_field_class_name);
640 }
641
642 if (maps->data_maps) {
643 g_hash_table_destroy(maps->data_maps);
644 maps->data_maps = NULL;
645 }
646
647 if (maps->metadata_maps) {
648 g_hash_table_destroy(maps->metadata_maps);
649 maps->metadata_maps = NULL;
650 }
651
652 g_free(maps);
653 }
654
655 BT_HIDDEN
656 struct trace_ir_maps *trace_ir_maps_create(bt_self_component *self_comp,
657 const char *debug_info_field_name)
658 {
659 struct trace_ir_maps *trace_ir_maps =
660 g_new0(struct trace_ir_maps, 1);
661 if (!trace_ir_maps) {
662 BT_LOGE_STR("Error allocating trace_ir_maps");
663 goto error;
664 }
665
666 /* Copy debug info field name received from the user. */
667 trace_ir_maps->debug_info_field_class_name =
668 g_strdup(debug_info_field_name);
669 if (!trace_ir_maps->debug_info_field_class_name) {
670 BT_LOGE_STR("Cannot copy debug info field name");
671 goto error;
672 }
673
674 trace_ir_maps->self_comp = self_comp;
675
676 trace_ir_maps->data_maps = g_hash_table_new_full(g_direct_hash,
677 g_direct_equal, (GDestroyNotify) NULL,
678 (GDestroyNotify) trace_ir_data_maps_destroy);
679
680 trace_ir_maps->metadata_maps = g_hash_table_new_full(g_direct_hash,
681 g_direct_equal, (GDestroyNotify) NULL,
682 (GDestroyNotify) trace_ir_metadata_maps_destroy);
683
684 goto end;
685 error:
686 trace_ir_maps_destroy(trace_ir_maps);
687 trace_ir_maps = NULL;
688 end:
689 return trace_ir_maps;
690 }
This page took 0.04289 seconds and 4 git commands to generate.