Commit b7a16eac authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

perf_counter: tools: /usr/lib/debug%s.debug support

Some distros seem to store debuginfo in weird places.
Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: John Kacur <jkacur@redhat.com>
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent d716fba4
...@@ -190,7 +190,8 @@ static inline int elf_sym__is_function(const GElf_Sym *sym) ...@@ -190,7 +190,8 @@ static inline int elf_sym__is_function(const GElf_Sym *sym)
{ {
return elf_sym__type(sym) == STT_FUNC && return elf_sym__type(sym) == STT_FUNC &&
sym->st_name != 0 && sym->st_name != 0 &&
sym->st_shndx != SHN_UNDEF; sym->st_shndx != SHN_UNDEF &&
sym->st_size != 0;
} }
static inline const char *elf_sym__name(const GElf_Sym *sym, static inline const char *elf_sym__name(const GElf_Sym *sym,
...@@ -222,11 +223,11 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, ...@@ -222,11 +223,11 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
return sec; return sec;
} }
static int dso__load(struct dso *self) static int dso__load_sym(struct dso *self, int fd, char *name)
{ {
Elf_Data *symstrs; Elf_Data *symstrs;
uint32_t nr_syms; uint32_t nr_syms;
int fd, err = -1; int err = -1;
uint32_t index; uint32_t index;
GElf_Ehdr ehdr; GElf_Ehdr ehdr;
GElf_Shdr shdr; GElf_Shdr shdr;
...@@ -234,16 +235,12 @@ static int dso__load(struct dso *self) ...@@ -234,16 +235,12 @@ static int dso__load(struct dso *self)
GElf_Sym sym; GElf_Sym sym;
Elf_Scn *sec; Elf_Scn *sec;
Elf *elf; Elf *elf;
int nr = 0;
fd = open(self->name, O_RDONLY);
if (fd == -1)
return -1;
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
if (elf == NULL) { if (elf == NULL) {
fprintf(stderr, "%s: cannot read %s ELF file.\n", fprintf(stderr, "%s: cannot read %s ELF file.\n",
__func__, self->name); __func__, name);
goto out_close; goto out_close;
} }
...@@ -292,16 +289,63 @@ static int dso__load(struct dso *self) ...@@ -292,16 +289,63 @@ static int dso__load(struct dso *self)
goto out_elf_end; goto out_elf_end;
dso__insert_symbol(self, f); dso__insert_symbol(self, f);
nr++;
} }
err = 0; err = nr;
out_elf_end: out_elf_end:
elf_end(elf); elf_end(elf);
out_close: out_close:
close(fd);
return err; return err;
} }
static int dso__load(struct dso *self)
{
int size = strlen(self->name) + sizeof("/usr/lib/debug%s.debug");
char *name = malloc(size);
int variant = 0;
int ret = -1;
int fd;
if (!name)
return -1;
more:
do {
switch (variant) {
case 0: /* Fedora */
snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
break;
case 1: /* Ubuntu */
snprintf(name, size, "/usr/lib/debug%s", self->name);
break;
case 2: /* Sane people */
snprintf(name, size, "%s", self->name);
break;
default:
goto out;
}
variant++;
fd = open(name, O_RDONLY);
} while (fd < 0);
ret = dso__load_sym(self, fd, name);
close(fd);
/*
* Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
*/
if (!ret)
goto more;
out:
free(name);
return ret;
}
static size_t dso__fprintf(struct dso *self, FILE *fp) static size_t dso__fprintf(struct dso *self, FILE *fp)
{ {
size_t ret = fprintf(fp, "dso: %s\n", self->name); size_t ret = fprintf(fp, "dso: %s\n", self->name);
...@@ -336,11 +380,23 @@ static struct dso *dsos__find(const char *name) ...@@ -336,11 +380,23 @@ static struct dso *dsos__find(const char *name)
static struct dso *dsos__findnew(const char *name) static struct dso *dsos__findnew(const char *name)
{ {
struct dso *dso = dsos__find(name); struct dso *dso = dsos__find(name);
int nr;
if (dso == NULL) { if (dso == NULL) {
dso = dso__new(name); dso = dso__new(name);
if (dso != NULL && dso__load(dso) < 0) if (!dso)
goto out_delete_dso;
nr = dso__load(dso);
if (nr < 0) {
fprintf(stderr, "Failed to open: %s\n", name);
goto out_delete_dso; goto out_delete_dso;
}
if (!nr) {
fprintf(stderr,
"Failed to find debug symbols for: %s, maybe install a debug package?\n",
name);
}
dsos__add(dso); dsos__add(dso);
} }
...@@ -547,9 +603,9 @@ symhist__fprintf(struct symhist *self, uint64_t total_samples, FILE *fp) ...@@ -547,9 +603,9 @@ symhist__fprintf(struct symhist *self, uint64_t total_samples, FILE *fp)
size_t ret; size_t ret;
if (total_samples) if (total_samples)
ret = fprintf(fp, "%5.2f", (self->count * 100.0) / total_samples); ret = fprintf(fp, "%5.2f%% ", (self->count * 100.0) / total_samples);
else else
ret = fprintf(fp, "%12d", self->count); ret = fprintf(fp, "%12d ", self->count);
ret += fprintf(fp, "%14s [%c] ", ret += fprintf(fp, "%14s [%c] ",
thread__name(self->thread, bf, sizeof(bf)), thread__name(self->thread, bf, sizeof(bf)),
...@@ -922,10 +978,12 @@ static int __cmd_report(void) ...@@ -922,10 +978,12 @@ static int __cmd_report(void)
} }
default: { default: {
broken_event: broken_event:
if (dump_trace)
fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n", fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n",
(void *)(offset + head), (void *)(offset + head),
(void *)(long)(event->header.size), (void *)(long)(event->header.size),
event->header.type); event->header.type);
total_unknown++; total_unknown++;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment