From 6a5c5733431fc166fe802d1b41278a580ccde771 Mon Sep 17 00:00:00 2001 From: Eunseon Lee Date: Fri, 21 Oct 2022 12:22:37 +0900 Subject: [PATCH] libbpf-tools/offcputime: Add dso info and symbol offset to backtrace for -v option 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: # offcputime -v 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: # offcputime -v #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 Fixed: #3884 Signed-off-by: Eunseon Lee --- libbpf-tools/offcputime.c | 42 ++++++++++++++++++++++++++++++------ libbpf-tools/trace_helpers.c | 21 +++++++++++++++++- libbpf-tools/trace_helpers.h | 3 +++ 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/libbpf-tools/offcputime.c b/libbpf-tools/offcputime.c index 37a8ec2c065b..46ff11ed3c10 100644 --- a/libbpf-tools/offcputime.c +++ b/libbpf-tools/offcputime.c @@ -197,6 +197,9 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, int err, i, ifd, sfd; unsigned long *ip; struct val_t val; + char *dso_name; + unsigned long dso_offset; + int idx; ip = calloc(env.perf_max_stack_depth, sizeof(*ip)); if (!ip) { @@ -207,6 +210,8 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, ifd = bpf_map__fd(obj->maps.info); sfd = bpf_map__fd(obj->maps.stackmap); while (!bpf_map_get_next_key(ifd, &lookup_key, &next_key)) { + idx = 0; + err = bpf_map_lookup_elem(ifd, &next_key, &val); if (err < 0) { fprintf(stderr, "failed to lookup info: %d\n", err); @@ -219,9 +224,17 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, fprintf(stderr, " [Missed Kernel Stack]\n"); goto print_ustack; } + for (i = 0; i < env.perf_max_stack_depth && ip[i]; i++) { ksym = ksyms__map_addr(ksyms, ip[i]); - printf(" %s\n", ksym ? ksym->name : "Unknown"); + if (!env.verbose) { + printf(" %s\n", ksym ? ksym->name : "unknown"); + } else { + if (ksym) + printf(" #%-2d 0x%lx %s+0x%lx\n", idx++, ip[i], ksym->name, ip[i] - ksym->addr); + else + printf(" #%-2d 0x%lx [unknown]\n", idx++, ip[i]); + } } print_ustack: @@ -235,15 +248,30 @@ static void print_map(struct ksyms *ksyms, struct syms_cache *syms_cache, syms = syms_cache__get_syms(syms_cache, next_key.tgid); if (!syms) { - fprintf(stderr, "failed to get syms\n"); + if (!env.verbose) { + fprintf(stderr, "failed to get syms\n"); + } else { + for (i = 0; i < env.perf_max_stack_depth && ip[i]; i++) + printf(" #%-2d 0x%016lx [unknown]\n", idx++, ip[i]); + } goto skip_ustack; } for (i = 0; i < env.perf_max_stack_depth && ip[i]; i++) { - sym = syms__map_addr(syms, ip[i]); - if (sym) - printf(" %s\n", sym->name); - else - printf(" [unknown]\n"); + if (!env.verbose) { + sym = syms__map_addr(syms, ip[i]); + if (sym) + printf(" %s\n", sym->name); + else + printf(" [unknown]\n"); + } else { + sym = syms__map_addr_dso(syms, ip[i], &dso_name, &dso_offset); + printf(" #%-2d 0x%016lx", idx++, ip[i]); + if (sym) + printf(" %s+0x%lx", sym->name, sym->offset); + if (dso_name) + printf(" (%s+0x%lx)", dso_name, dso_offset); + printf("\n"); + } } skip_ustack: diff --git a/libbpf-tools/trace_helpers.c b/libbpf-tools/trace_helpers.c index 192979fa5ea5..773b6af95502 100644 --- a/libbpf-tools/trace_helpers.c +++ b/libbpf-tools/trace_helpers.c @@ -423,6 +423,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; } @@ -635,8 +636,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; } @@ -721,6 +724,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, unsigned long *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 e46c0f83312e..20791a864ab4 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, unsigned long *dso_offset); struct syms_cache;