Fix: Don't skip binary path print-out in ELF-only case
[babeltrace.git] / lib / debuginfo.c
CommitLineData
b5a8598f
AB
1/*
2 * Babeltrace - Debug Information State Tracker
3 *
4 * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation
5 * Copyright (c) 2015 Philippe Proulx <pproulx@efficios.com>
6 * Copyright (c) 2015 Antoine Busque <abusque@efficios.com>
458af89d 7 * Copyright (c) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
b5a8598f
AB
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#include <assert.h>
29#include <glib.h>
30#include <babeltrace/types.h>
31#include <babeltrace/ctf-ir/metadata.h>
32#include <babeltrace/debuginfo.h>
33#include <babeltrace/so-info.h>
458af89d 34#include <babeltrace/babeltrace-internal.h>
b5a8598f
AB
35
36struct proc_debug_info_sources {
37 /*
71235b6d 38 * Hash table: base address (pointer to uint64_t) to so info; owned by
b5a8598f
AB
39 * proc_debug_info_sources.
40 */
41 GHashTable *baddr_to_so_info;
42
43 /*
71235b6d
JG
44 * Hash table: IP (pointer to uint64_t) to (struct debug_info_source *);
45 * owned by proc_debug_info_sources.
b5a8598f
AB
46 */
47 GHashTable *ip_to_debug_info_src;
48};
49
50struct debug_info {
51 /*
71235b6d
JG
52 * Hash table of VPIDs (pointer to int64_t) to
53 * (struct ctf_proc_debug_infos*); owned by debug_info.
b5a8598f
AB
54 */
55 GHashTable *vpid_to_proc_dbg_info_src;
56 GQuark q_statedump_soinfo;
57 GQuark q_statedump_debug_link;
58 GQuark q_statedump_build_id;
59 GQuark q_statedump_start;
60 GQuark q_dl_open;
61};
62
63static
64int debug_info_init(struct debug_info *info)
65{
66 info->q_statedump_soinfo = g_quark_from_string(
67 "lttng_ust_statedump:soinfo");
68 info->q_statedump_debug_link = g_quark_from_string(
69 "lttng_ust_statedump:debug_link)");
70 info->q_statedump_build_id = g_quark_from_string(
71 "lttng_ust_statedump:build_id");
72 info->q_statedump_start = g_quark_from_string(
73 "lttng_ust_statedump:start");
74 info->q_dl_open = g_quark_from_string("lttng_ust_dl:dlopen");
75
76 return so_info_init();
77}
78
79static
80void debug_info_source_destroy(struct debug_info_source *debug_info_src)
81{
82 if (!debug_info_src) {
83 return;
84 }
85
86 free(debug_info_src->func);
ad2b5b38
JG
87 free(debug_info_src->src_path);
88 free(debug_info_src->bin_path);
b5a8598f
AB
89 g_free(debug_info_src);
90}
91
458af89d
JG
92/*
93 * Returns the location of a path's file (the last element of the path).
94 * Returns the original path on error.
95 */
96static
97const char *get_filename_from_path(const char *path)
98{
99 size_t i = strlen(path);
100
101 if (i == 0) {
102 goto end;
103 }
104
105 if (path[i - 1] == '/') {
106 /*
107 * Path ends with a trailing slash, no filename to return.
108 * Return the original path.
109 */
110 goto end;
111 }
112
113 while (i-- > 0) {
114 if (path[i] == '/') {
115 path = &path[i + 1];
116 goto end;
117 }
118 }
119end:
120 return path;
121}
122
b5a8598f
AB
123static
124struct debug_info_source *debug_info_source_create_from_so(struct so_info *so,
125 uint64_t ip)
126{
127 int ret;
128 struct debug_info_source *debug_info_src = NULL;
129 struct source_location *src_loc = NULL;
130
131 debug_info_src = g_new0(struct debug_info_source, 1);
132
133 if (!debug_info_src) {
134 goto end;
135 }
136
137 /* Lookup function name */
138 ret = so_info_lookup_function_name(so, ip, &debug_info_src->func);
139 if (ret) {
140 goto error;
141 }
142
143 /* Can't retrieve src_loc from ELF only, skip it */
306dbb33
JG
144 if (!so->is_elf_only) {
145 /* Lookup source location */
146 ret = so_info_lookup_source_location(so, ip, &src_loc);
147 if (ret) {
148 goto error;
149 }
b5a8598f
AB
150 }
151
152 if (src_loc) {
153 debug_info_src->line_no = src_loc->line_no;
154
155 if (src_loc->filename) {
ad2b5b38
JG
156 debug_info_src->src_path = strdup(src_loc->filename);
157 if (!debug_info_src->src_path) {
b5a8598f
AB
158 goto error;
159 }
458af89d 160
ad2b5b38 161 debug_info_src->short_src_path = get_filename_from_path(
458af89d
JG
162 src_loc->filename);
163
b5a8598f
AB
164 }
165
166 source_location_destroy(src_loc);
167 }
168
ad2b5b38
JG
169 if (so->elf_path) {
170 debug_info_src->bin_path = strdup(so->elf_path);
171 if (!debug_info_src->bin_path) {
172 goto error;
173 }
174
175 debug_info_src->short_bin_path = get_filename_from_path(
176 debug_info_src->bin_path);
177 }
178
b5a8598f
AB
179end:
180 return debug_info_src;
181
182error:
183 debug_info_source_destroy(debug_info_src);
184 return NULL;
185}
186
187static
188void proc_debug_info_sources_destroy(
189 struct proc_debug_info_sources *proc_dbg_info_src)
190{
191 if (!proc_dbg_info_src) {
192 return;
193 }
194
195 if (proc_dbg_info_src->baddr_to_so_info) {
196 g_hash_table_destroy(proc_dbg_info_src->baddr_to_so_info);
197 }
198
199 if (proc_dbg_info_src->ip_to_debug_info_src) {
200 g_hash_table_destroy(proc_dbg_info_src->ip_to_debug_info_src);
201 }
202
203 g_free(proc_dbg_info_src);
204}
205
206static
207struct proc_debug_info_sources *proc_debug_info_sources_create(void)
208{
209 struct proc_debug_info_sources *proc_dbg_info_src = NULL;
210
211 proc_dbg_info_src = g_new0(struct proc_debug_info_sources, 1);
212 if (!proc_dbg_info_src) {
213 goto end;
214 }
215
216 proc_dbg_info_src->baddr_to_so_info = g_hash_table_new_full(
71235b6d
JG
217 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
218 (GDestroyNotify) so_info_destroy);
b5a8598f
AB
219 if (!proc_dbg_info_src->baddr_to_so_info) {
220 goto error;
221 }
222
223 proc_dbg_info_src->ip_to_debug_info_src = g_hash_table_new_full(
71235b6d 224 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
b5a8598f
AB
225 (GDestroyNotify) debug_info_source_destroy);
226 if (!proc_dbg_info_src->ip_to_debug_info_src) {
227 goto error;
228 }
229
230end:
231 return proc_dbg_info_src;
232
233error:
234 proc_debug_info_sources_destroy(proc_dbg_info_src);
235 return NULL;
236}
237
238static
239struct proc_debug_info_sources *proc_debug_info_sources_ht_get_entry(
240 GHashTable *ht, int64_t vpid)
241{
71235b6d 242 gpointer key = g_new0(int64_t, 1);
b5a8598f
AB
243 struct proc_debug_info_sources *proc_dbg_info_src = NULL;
244
71235b6d
JG
245 if (!key) {
246 goto end;
247 }
248
249 *((int64_t *) key) = vpid;
250
b5a8598f
AB
251 /* Exists? Return it */
252 proc_dbg_info_src = g_hash_table_lookup(ht, key);
253 if (proc_dbg_info_src) {
254 goto end;
255 }
256
257 /* Otherwise, create and return it */
258 proc_dbg_info_src = proc_debug_info_sources_create();
259 if (!proc_dbg_info_src) {
260 goto end;
261 }
262
263 g_hash_table_insert(ht, key, proc_dbg_info_src);
71235b6d
JG
264 /* Ownership passed to ht */
265 key = NULL;
b5a8598f 266end:
71235b6d 267 g_free(key);
b5a8598f
AB
268 return proc_dbg_info_src;
269}
270
271static
272struct debug_info_source *proc_debug_info_sources_get_entry(
273 struct proc_debug_info_sources *proc_dbg_info_src, uint64_t ip)
274{
275 struct debug_info_source *debug_info_src = NULL;
71235b6d 276 gpointer key = g_new0(uint64_t, 1);
b5a8598f
AB
277 GHashTableIter iter;
278 gpointer baddr, value;
279
71235b6d
JG
280 if (!key) {
281 goto end;
282 }
283
284 *((uint64_t *) key) = ip;
285
b5a8598f
AB
286 /* Look in IP to debug infos hash table first. */
287 debug_info_src = g_hash_table_lookup(
288 proc_dbg_info_src->ip_to_debug_info_src,
71235b6d 289 key);
b5a8598f
AB
290 if (debug_info_src) {
291 goto end;
292 }
293
294 /* Check in all so_infos. */
295 g_hash_table_iter_init(&iter, proc_dbg_info_src->baddr_to_so_info);
296
297 while (g_hash_table_iter_next(&iter, &baddr, &value))
298 {
299 struct so_info *so = value;
300
301 if (!so_info_has_address(value, ip)) {
302 continue;
303 }
304
71235b6d
JG
305 /*
306 * Found; add it to cache.
307 *
308 * FIXME: this should be bounded in size (and implement
309 * a caching policy), and entries should be prunned when
310 * libraries are unmapped.
311 */
b5a8598f
AB
312 debug_info_src = debug_info_source_create_from_so(so, ip);
313 if (debug_info_src) {
314 g_hash_table_insert(
315 proc_dbg_info_src->ip_to_debug_info_src,
71235b6d
JG
316 key, debug_info_src);
317 /* Ownership passed to ht. */
318 key = NULL;
b5a8598f
AB
319 }
320 break;
321 }
322
323end:
71235b6d 324 free(key);
b5a8598f
AB
325 return debug_info_src;
326}
327
328BT_HIDDEN
329struct debug_info_source *debug_info_query(struct debug_info *debug_info,
330 int64_t vpid, uint64_t ip)
331{
332 struct debug_info_source *dbg_info_src = NULL;
333 struct proc_debug_info_sources *proc_dbg_info_src;
334
335 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
336 debug_info->vpid_to_proc_dbg_info_src, vpid);
337 if (!proc_dbg_info_src) {
338 goto end;
339 }
340
341 dbg_info_src = proc_debug_info_sources_get_entry(
342 proc_dbg_info_src, ip);
343 if (!dbg_info_src) {
344 goto end;
345 }
346
347end:
348 return dbg_info_src;
349}
350
351BT_HIDDEN
352struct debug_info *debug_info_create(void)
353{
354 int ret;
355 struct debug_info *debug_info;
356
357 debug_info = g_new0(struct debug_info, 1);
358 if (!debug_info) {
359 goto end;
360 }
361
71235b6d
JG
362 debug_info->vpid_to_proc_dbg_info_src = g_hash_table_new_full(
363 g_int64_hash, g_int64_equal, (GDestroyNotify) g_free,
b5a8598f
AB
364 (GDestroyNotify) proc_debug_info_sources_destroy);
365 if (!debug_info->vpid_to_proc_dbg_info_src) {
366 goto error;
367 }
368
369 ret = debug_info_init(debug_info);
370 if (ret) {
371 goto error;
372 }
373
374end:
375 return debug_info;
376error:
377 g_free(debug_info);
378 return NULL;
379}
380
381BT_HIDDEN
382void debug_info_destroy(struct debug_info *debug_info)
383{
384 if (!debug_info) {
385 goto end;
386 }
387
388 if (debug_info->vpid_to_proc_dbg_info_src) {
389 g_hash_table_destroy(debug_info->vpid_to_proc_dbg_info_src);
390 }
391
392 g_free(debug_info);
393end:
394 return;
395}
396
397static
398void handle_statedump_build_id_event(struct debug_info *debug_info,
399 struct ctf_event_definition *event_def)
400{
401 struct proc_debug_info_sources *proc_dbg_info_src;
402 struct bt_definition *event_fields_def = NULL;
403 struct bt_definition *sec_def = NULL;
404 struct bt_definition *baddr_def = NULL;
405 struct bt_definition *vpid_def = NULL;
406 struct bt_definition *build_id_def = NULL;
407 struct definition_sequence *build_id_seq;
408 struct so_info *so = NULL;
409 int i;
410 int64_t vpid;
411 uint64_t baddr;
412 uint8_t *build_id = NULL;
413 uint64_t build_id_len;
414
415 event_fields_def = (struct bt_definition *) event_def->event_fields;
416 sec_def = (struct bt_definition *)
417 event_def->stream->stream_event_context;
418
419 if (!event_fields_def || !sec_def) {
420 goto end;
421 }
422
423 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
424 if (!baddr_def) {
425 goto end;
426 }
427
428 vpid_def = bt_lookup_definition(sec_def, "_vpid");
429 if (!vpid_def) {
430 goto end;
431 }
432
433 build_id_def = bt_lookup_definition(event_fields_def, "_build_id");
434 if (!build_id_def) {
435 goto end;
436 }
437
438 if (baddr_def->declaration->id != CTF_TYPE_INTEGER) {
439 goto end;
440 }
441
442 if (vpid_def->declaration->id != CTF_TYPE_INTEGER) {
443 goto end;
444 }
445
446 if (build_id_def->declaration->id != CTF_TYPE_SEQUENCE) {
447 goto end;
448 }
449
450 baddr = bt_get_unsigned_int(baddr_def);
451 vpid = bt_get_signed_int(vpid_def);
452 build_id_seq = container_of(build_id_def,
453 struct definition_sequence, p);
454 build_id_len = build_id_seq->length->value._unsigned;
455
456 build_id = g_malloc(build_id_len);
457 if (!build_id) {
458 goto end;
459 }
460
461 for (i = 0; i < build_id_len; ++i) {
462 struct bt_definition **field;
463
464 field = (struct bt_definition **) &g_ptr_array_index(
465 build_id_seq->elems, i);
466 build_id[i] = bt_get_unsigned_int(*field);
467 }
468
469 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
470 debug_info->vpid_to_proc_dbg_info_src, vpid);
471 if (!proc_dbg_info_src) {
472 goto end;
473 }
474
475 so = g_hash_table_lookup(proc_dbg_info_src->baddr_to_so_info,
476 (gpointer) &baddr);
477 if (!so) {
478 /*
479 * The build_id event comes after the so has been
480 * created. If it isn't found, just ignore this event.
481 */
482 goto end;
483 }
484
485 so_info_set_build_id(so, build_id, build_id_len);
486
487end:
488 free(build_id);
489 return;
490}
491
492static
493void handle_statedump_debug_link_event(struct debug_info *debug_info,
494 struct ctf_event_definition *event_def)
495{
496 struct proc_debug_info_sources *proc_dbg_info_src;
497 struct bt_definition *event_fields_def = NULL;
498 struct bt_definition *sec_def = NULL;
499 struct bt_definition *baddr_def = NULL;
500 struct bt_definition *vpid_def = NULL;
501 struct bt_definition *filename_def = NULL;
502 struct bt_definition *crc32_def = NULL;
503 struct so_info *so = NULL;
504 int64_t vpid;
505 uint64_t baddr;
506 char *filename = NULL;
507 uint32_t crc32;
508
509 event_fields_def = (struct bt_definition *) event_def->event_fields;
510 sec_def = (struct bt_definition *)
511 event_def->stream->stream_event_context;
512
513 if (!event_fields_def || !sec_def) {
514 goto end;
515 }
516
517 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
518 if (!baddr_def) {
519 goto end;
520 }
521
522 vpid_def = bt_lookup_definition(sec_def, "_vpid");
523 if (!vpid_def) {
524 goto end;
525 }
526
527 filename_def = bt_lookup_definition(event_fields_def, "_filename");
528 if (!filename_def) {
529 goto end;
530 }
531
532 crc32_def = bt_lookup_definition(event_fields_def, "_crc32");
533 if (!crc32_def) {
534 goto end;
535 }
536
537 if (baddr_def->declaration->id != CTF_TYPE_INTEGER) {
538 goto end;
539 }
540
541 if (vpid_def->declaration->id != CTF_TYPE_INTEGER) {
542 goto end;
543 }
544
545 if (filename_def->declaration->id != CTF_TYPE_STRING) {
546 goto end;
547 }
548
549 if (crc32_def->declaration->id != CTF_TYPE_INTEGER) {
550 goto end;
551 }
552
553 baddr = bt_get_unsigned_int(baddr_def);
554 vpid = bt_get_signed_int(vpid_def);
555
556 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
557 debug_info->vpid_to_proc_dbg_info_src, vpid);
558 if (!proc_dbg_info_src) {
559 goto end;
560 }
561
562 so = g_hash_table_lookup(proc_dbg_info_src->baddr_to_so_info,
563 (gpointer) &baddr);
564 if (!so) {
565 /*
566 * The debug_link event comes after the so has been
567 * created. If it isn't found, just ignore this event.
568 */
569 goto end;
570 }
571
572 filename = bt_get_string(filename_def);
573 crc32 = bt_get_unsigned_int(crc32_def);
574
575 so_info_set_debug_link(so, filename, crc32);
576
577end:
578 return;
579}
580
581static
582void handle_statedump_soinfo_event(struct debug_info *debug_info,
583 struct ctf_event_definition *event_def)
584{
585 struct bt_definition *baddr_def = NULL;
586 struct bt_definition *memsz_def = NULL;
587 struct bt_definition *sopath_def = NULL;
588 struct bt_definition *vpid_def = NULL;
589 struct bt_definition *event_fields_def = NULL;
590 struct bt_definition *sec_def = NULL;
591 struct proc_debug_info_sources *proc_dbg_info_src;
592 struct so_info *so;
593 uint64_t baddr, memsz;
594 int64_t vpid;
595 const char *sopath;
71235b6d 596 gpointer key = NULL;
b5a8598f
AB
597
598 event_fields_def = (struct bt_definition *) event_def->event_fields;
599 sec_def = (struct bt_definition *)
600 event_def->stream->stream_event_context;
601
602 if (!event_fields_def || !sec_def) {
603 goto end;
604 }
605
606 baddr_def = bt_lookup_definition(event_fields_def, "_baddr");
607 if (!baddr_def) {
608 goto end;
609 }
610
611 memsz_def = bt_lookup_definition(event_fields_def, "_memsz");
612 if (!memsz_def) {
613 goto end;
614 }
615
616 sopath_def = bt_lookup_definition(event_fields_def, "_sopath");
617 if (!sopath_def) {
618 goto end;
619 }
620
621 vpid_def = bt_lookup_definition(sec_def, "_vpid");
622 if (!vpid_def) {
623 goto end;
624 }
625
626 if (baddr_def->declaration->id != CTF_TYPE_INTEGER) {
627 goto end;
628 }
629
630 if (memsz_def->declaration->id != CTF_TYPE_INTEGER) {
631 goto end;
632 }
633
634 if (sopath_def->declaration->id != CTF_TYPE_STRING) {
635 goto end;
636 }
637
638 if (vpid_def->declaration->id != CTF_TYPE_INTEGER) {
639 goto end;
640 }
641
642 baddr = bt_get_unsigned_int(baddr_def);
643 memsz = bt_get_unsigned_int(memsz_def);
644 sopath = bt_get_string(sopath_def);
645 vpid = bt_get_signed_int(vpid_def);
646
647 if (!sopath) {
648 goto end;
649 }
650
651 if (memsz == 0) {
652 /* Ignore VDSO. */
653 goto end;
654 }
655
656 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
657 debug_info->vpid_to_proc_dbg_info_src, vpid);
658 if (!proc_dbg_info_src) {
659 goto end;
660 }
661
71235b6d
JG
662 key = g_new0(uint64_t, 1);
663 if (!key) {
664 goto end;
665 }
666
667 *((uint64_t *) key) = baddr;
668
b5a8598f 669 so = g_hash_table_lookup(proc_dbg_info_src->baddr_to_so_info,
71235b6d 670 key);
b5a8598f
AB
671 if (so) {
672 goto end;
673 }
674
675 so = so_info_create(sopath, baddr, memsz);
676 if (!so) {
677 goto end;
678 }
679
680 g_hash_table_insert(proc_dbg_info_src->baddr_to_so_info,
71235b6d
JG
681 key, so);
682 /* Ownership passed to ht. */
683 key = NULL;
b5a8598f
AB
684
685end:
71235b6d 686 g_free(key);
b5a8598f
AB
687 return;
688}
689
690static
691void handle_statedump_start(struct debug_info *debug_info,
692 struct ctf_event_definition *event_def)
693{
694 struct bt_definition *vpid_def = NULL;
695 struct bt_definition *sec_def = NULL;
696 struct proc_debug_info_sources *proc_dbg_info_src;
697 int64_t vpid;
698
699 sec_def = (struct bt_definition *)
700 event_def->stream->stream_event_context;
701 if (!sec_def) {
702 goto end;
703 }
704
705 vpid_def = bt_lookup_definition(sec_def, "_vpid");
706 if (!vpid_def) {
707 goto end;
708 }
709
710 vpid = bt_get_signed_int(vpid_def);
711
712 proc_dbg_info_src = proc_debug_info_sources_ht_get_entry(
713 debug_info->vpid_to_proc_dbg_info_src, vpid);
714 if (!proc_dbg_info_src) {
715 goto end;
716 }
717
718 g_hash_table_remove_all(proc_dbg_info_src->baddr_to_so_info);
719 g_hash_table_remove_all(proc_dbg_info_src->ip_to_debug_info_src);
720
721end:
722 return;
723}
724
725static
726void register_event_debug_infos(struct debug_info *debug_info,
727 struct ctf_event_definition *event)
728{
729 struct bt_definition *ip_def, *vpid_def;
730 int64_t vpid;
731 uint64_t ip;
732 struct bt_definition *sec_def;
733
734 /* Get stream event context definition. */
735 sec_def = (struct bt_definition *) event->stream->stream_event_context;
736 if (!sec_def) {
737 goto end;
738 }
739
740 /* Get "ip" and "vpid" definitions. */
741 vpid_def = bt_lookup_definition((struct bt_definition *) sec_def,
742 "_vpid");
743 ip_def = bt_lookup_definition((struct bt_definition *) sec_def, "_ip");
744
745 if (!vpid_def || !ip_def) {
746 goto end;
747 }
748
749 vpid = bt_get_signed_int(vpid_def);
750 ip = bt_get_unsigned_int(ip_def);
751
752 /* Get debug info for this context. */
753 ((struct definition_integer *) ip_def)->debug_info_src =
754 debug_info_query(debug_info, vpid, ip);
755
756end:
757 return;
758}
759
760BT_HIDDEN
761void debug_info_handle_event(struct debug_info *debug_info,
762 struct ctf_event_definition *event)
763{
764 struct ctf_event_declaration *event_class;
765 struct ctf_stream_declaration *stream_class;
766
767 if (!debug_info || !event) {
768 goto end;
769 }
770
771 stream_class = event->stream->stream_class;
772 event_class = g_ptr_array_index(stream_class->events_by_id,
773 event->stream->event_id);
774
775 if (event_class->name == debug_info->q_statedump_soinfo ||
776 event_class->name == debug_info->q_dl_open) {
777 /* State dump/dlopen() */
778 handle_statedump_soinfo_event(debug_info, event);
779 } else if (event_class->name == debug_info->q_statedump_start) {
780 /* Start state dump */
781 handle_statedump_start(debug_info, event);
782 } else if (event_class->name == debug_info->q_statedump_debug_link) {
783 /* Debug link info */
784 handle_statedump_debug_link_event(debug_info, event);
785 } else if (event_class->name == debug_info->q_statedump_build_id) {
786 /* Build ID info */
787 handle_statedump_build_id_event(debug_info, event);
788 } else {
789 /* Other events: register debug infos */
790 register_event_debug_infos(debug_info, event);
791 }
792
793end:
794 return;
795}
This page took 0.05198 seconds and 4 git commands to generate.