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