From 6a1efc23943d5a56ca2e1c212bfaa42a30192aed Mon Sep 17 00:00:00 2001 From: Eunseon Lee Date: Sun, 20 Feb 2022 19:16:50 +0900 Subject: [PATCH] libbpf-tools/profile: Add module info and symbol offset to backtrace Add additional information and change format of backtrace - add symbol base offset, dso name, dso base offset - symbol and dso info is included if it's available in target binary - changed format: INDEX ADDR [SYMBOL+OFFSET] [(MODULE+OFFSET)] Print backtrace of ip if it failed to get syms. Before: # profile -d psiginfo vscanf __snprintf_chk [unknown] [unknown] [unknown] [unknown] [unknown] sd_event_exit sd_event_dispatch sd_event_run [unknown] __libc_start_main [unknown] - systemd-journal (204) 1 xas_load xas_find filemap_map_pages __handle_mm_fault handle_mm_fault do_page_fault do_translation_fault do_mem_abort do_el0_ia_bp_hardening el0_ia xas_load -- failed to get syms - PmLogCtl (138757) 1 After: # profile -d #0 0xffffffc01018b7e8 __arm64_sys_clock_nanosleep+0x0 #1 0xffffffc01009a93c el0_svc_handler+0x34 #2 0xffffffc010084a08 el0_svc+0x8 #3 0xffffffc01018b7e8 __arm64_sys_clock_nanosleep+0x0 -- #4 0x0000007fa0bffd14 clock_nanosleep+0x94 (/usr/lib/libc-2.31.so+0x9ed14) #5 0x0000007fa0c0530c nanosleep+0x1c (/usr/lib/libc-2.31.so+0xa430c) #6 0x0000007fa0c051e4 sleep+0x34 (/usr/lib/libc-2.31.so+0xa41e4) #7 0x000000558a5a9608 flb_loop+0x28 (/usr/bin/fluent-bit+0x52608) #8 0x000000558a59f1c4 flb_main+0xa84 (/usr/bin/fluent-bit+0x481c4) #9 0x0000007fa0b85124 __libc_start_main+0xe4 (/usr/lib/libc-2.31.so+0x24124) #10 0x000000558a59d828 _start+0x34 (/usr/bin/fluent-bit+0x46828) - fluent-bit (1238) 1 #0 0xffffffc01027daa4 generic_copy_file_checks+0x334 #1 0xffffffc0102ba634 __handle_mm_fault+0x8dc #2 0xffffffc0102baa20 handle_mm_fault+0x168 #3 0xffffffc010ad23c0 do_page_fault+0x148 #4 0xffffffc010ad27c0 do_translation_fault+0xb0 #5 0xffffffc0100816b0 do_mem_abort+0x50 #6 0xffffffc0100843b0 el0_da+0x1c #7 0xffffffc01027daa4 generic_copy_file_checks+0x334 -- #8 0x0000007f8dc12648 [unknown] #9 0x0000007f8dc0aef8 [unknown] #10 0x0000007f8dc1c990 [unknown] #11 0x0000007f8dc08b0c [unknown] #12 0x0000007f8dc08e48 [unknown] #13 0x0000007f8dc081c8 [unknown] - PmLogCtl (2412) 1 Signed-off-by: Eunseon Lee --- libbpf-tools/profile.c | 31 ++++++++++++++++++++++++++----- libbpf-tools/trace_helpers.c | 21 ++++++++++++++++++++- libbpf-tools/trace_helpers.h | 3 +++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/libbpf-tools/profile.c b/libbpf-tools/profile.c index c57eb7c12165..60cf4f1e9a6d 100644 --- a/libbpf-tools/profile.c +++ b/libbpf-tools/profile.c @@ -289,6 +289,7 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, bool has_collision = false; unsigned int missing_stacks = 0; struct key_ext_t counts[MAX_ENTRIES]; + int nr_kern_elem = 0; ip = calloc(env.perf_max_stack_depth, sizeof(*ip)); if (!ip) { @@ -360,6 +361,8 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, printf(" %lld\n", v); } else { // print default multi-line stack output + nr_kern_elem = 0; + if (!env.user_stacks_only) { if (stack_id_err(k->kern_stack_id)) printf(" [Missed Kernel Stack]\n"); @@ -367,11 +370,20 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, bpf_map_lookup_elem(sfd, &k->kern_stack_id, ip) == 0) { for (j = 0; j < env.perf_max_stack_depth && ip[j]; j++) { ksym = ksyms__map_addr(ksyms, ip[j]); - printf(" %s\n", ksym ? ksym->name : "[unknown]"); + if (ksym) + printf(" #%-2d 0x%lx %s+0x%lx\n", j, ip[j], ksym->name, ip[j] - ksym->addr); + else + printf(" #%-2d 0x%lx [unknown]\n", j, ip[j]); } + nr_kern_elem = j; + if (k->kernel_ip) { ksym = ksyms__map_addr(ksyms, k->kernel_ip); - printf(" %s\n", ksym ? ksym->name : "[unknown]"); + if (ksym) + printf(" #%-2d 0x%llx %s+0x%llx\n", j, k->kernel_ip, ksym->name, k->kernel_ip - ksym->addr); + else + printf(" #%-2d 0x%llx [unknown]\n", j, k->kernel_ip); + nr_kern_elem++; } } } @@ -386,11 +398,20 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, bpf_map_lookup_elem(sfd, &k->user_stack_id, ip) == 0) { syms = syms_cache__get_syms(syms_cache, k->pid); if (!syms) { - fprintf(stderr, "failed to get syms\n"); + for (j = 0; j < env.perf_max_stack_depth && ip[j]; j++) + printf(" #%-2d 0x%016lx [unknown]\n", j + nr_kern_elem, ip[j]); } else { for (j = 0; j < env.perf_max_stack_depth && ip[j]; j++) { - sym = syms__map_addr(syms, ip[j]); - printf(" %s\n", sym ? sym->name : "[unknown]"); + char *dso_name; + uint64_t dso_offset; + sym = syms__map_addr_dso(syms, ip[j], &dso_name, &dso_offset); + + printf(" #%-2d 0x%016lx", j + nr_kern_elem, ip[j]); + if (sym) + printf(" %s+0x%lx", sym->name, sym->offset); + if (dso_name) + printf(" (%s+0x%lx)", dso_name, dso_offset); + printf("\n"); } } } diff --git a/libbpf-tools/trace_helpers.c b/libbpf-tools/trace_helpers.c index 322b3c4fbc68..34b9cf4ee739 100644 --- a/libbpf-tools/trace_helpers.c +++ b/libbpf-tools/trace_helpers.c @@ -422,6 +422,7 @@ static int dso__add_sym(struct dso *dso, const char *name, uint64_t start, sym->name = (void*)(unsigned long)off; sym->start = start; sym->size = size; + sym->offset = 0; return 0; } @@ -634,8 +635,10 @@ static struct sym *dso__find_sym(struct dso *dso, uint64_t offset) end = mid - 1; } - if (start == end && dso->syms[start].start <= offset) + if (start == end && dso->syms[start].start <= offset) { + (dso->syms[start]).offset = offset - dso->syms[start].start; return &dso->syms[start]; + } return NULL; } @@ -720,6 +723,22 @@ const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr) return dso__find_sym(dso, offset); } +const struct sym *syms__map_addr_dso(const struct syms *syms, unsigned long addr, + char **dso_name, uint64_t *dso_offset) +{ + struct dso *dso; + uint64_t offset; + + dso = syms__find_dso(syms, addr, &offset); + if (!dso) + return NULL; + + *dso_name = dso->name; + *dso_offset = offset; + + return dso__find_sym(dso, offset); +} + struct syms_cache { struct { struct syms *syms; diff --git a/libbpf-tools/trace_helpers.h b/libbpf-tools/trace_helpers.h index 98fd640ffb09..4e87ffb05a7e 100644 --- a/libbpf-tools/trace_helpers.h +++ b/libbpf-tools/trace_helpers.h @@ -24,6 +24,7 @@ struct sym { const char *name; unsigned long start; unsigned long size; + unsigned long offset; }; struct syms; @@ -32,6 +33,8 @@ struct syms *syms__load_pid(int tgid); struct syms *syms__load_file(const char *fname); void syms__free(struct syms *syms); const struct sym *syms__map_addr(const struct syms *syms, unsigned long addr); +const struct sym *syms__map_addr_dso(const struct syms *syms, unsigned long addr, + char **dso_name, uint64_t *dso_offset); struct syms_cache;