Skip to content

Commit

Permalink
libbpf-tools/profile: add dso info and symbol offset to backtrace
Browse files Browse the repository at this point in the history
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
      iovisor#1  0xffffffc01009a93c el0_svc_handler+0x34
      iovisor#2  0xffffffc010084a08 el0_svc+0x8
      iovisor#3  0xffffffc01018b7e8 __arm64_sys_clock_nanosleep+0x0
      --
      iovisor#4  0x0000007fa0bffd14 clock_nanosleep+0x94 (/usr/lib/libc-2.31.so+0x9ed14)
      iovisor#5  0x0000007fa0c0530c nanosleep+0x1c (/usr/lib/libc-2.31.so+0xa430c)
      iovisor#6  0x0000007fa0c051e4 sleep+0x34 (/usr/lib/libc-2.31.so+0xa41e4)
      iovisor#7  0x000000558a5a9608 flb_loop+0x28 (/usr/bin/fluent-bit+0x52608)
      iovisor#8  0x000000558a59f1c4 flb_main+0xa84 (/usr/bin/fluent-bit+0x481c4)
      iovisor#9  0x0000007fa0b85124 __libc_start_main+0xe4 (/usr/lib/libc-2.31.so+0x24124)
      iovisor#10 0x000000558a59d828 _start+0x34 (/usr/bin/fluent-bit+0x46828)
      -                fluent-bit (1238)
          1

      #0  0xffffffc01027daa4 generic_copy_file_checks+0x334
      iovisor#1  0xffffffc0102ba634 __handle_mm_fault+0x8dc
      iovisor#2  0xffffffc0102baa20 handle_mm_fault+0x168
      iovisor#3  0xffffffc010ad23c0 do_page_fault+0x148
      iovisor#4  0xffffffc010ad27c0 do_translation_fault+0xb0
      iovisor#5  0xffffffc0100816b0 do_mem_abort+0x50
      iovisor#6  0xffffffc0100843b0 el0_da+0x1c
      iovisor#7  0xffffffc01027daa4 generic_copy_file_checks+0x334
      --
      iovisor#8  0x0000007f8dc12648 [unknown]
      iovisor#9  0x0000007f8dc0aef8 [unknown]
      iovisor#10 0x0000007f8dc1c990 [unknown]
      iovisor#11 0x0000007f8dc08b0c [unknown]
      iovisor#12 0x0000007f8dc08e48 [unknown]
      iovisor#13 0x0000007f8dc081c8 [unknown]
      -                PmLogCtl (2412)
          1

Signed-off-by: Eunseon Lee <[email protected]>
  • Loading branch information
ekyooo committed Mar 12, 2022
1 parent 454d708 commit d2e0054
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 6 deletions.
31 changes: 26 additions & 5 deletions libbpf-tools/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -360,18 +361,29 @@ 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");
else if (k->kern_stack_id >= 0 &&
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++;
}
}
}
Expand All @@ -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");
}
}
}
Expand Down
21 changes: 20 additions & 1 deletion libbpf-tools/trace_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions libbpf-tools/trace_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct sym {
const char *name;
unsigned long start;
unsigned long size;
unsigned long offset;
};

struct syms;
Expand All @@ -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;

Expand Down

0 comments on commit d2e0054

Please sign in to comment.