aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation/perf_counter/builtin-report.c
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-05-27 07:35:35 -0400
committerIngo Molnar <mingo@elte.hu>2009-05-27 08:54:29 -0400
commitb7a16eac5e679fb5f531b9eeff7db7952303e77d (patch)
tree657ba175c6f28a01bd91bf2c34931e469149fde8 /Documentation/perf_counter/builtin-report.c
parentd716fba49c7445ec87c3f045c59624fac03ee3f2 (diff)
perf_counter: tools: /usr/lib/debug%s.debug support
Some distros seem to store debuginfo in weird places. Signed-off-by: Peter 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: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'Documentation/perf_counter/builtin-report.c')
-rw-r--r--Documentation/perf_counter/builtin-report.c94
1 files changed, 76 insertions, 18 deletions
diff --git a/Documentation/perf_counter/builtin-report.c b/Documentation/perf_counter/builtin-report.c
index 6265bedcd93..a9ff49a4ede 100644
--- a/Documentation/perf_counter/builtin-report.c
+++ b/Documentation/perf_counter/builtin-report.c
@@ -190,7 +190,8 @@ static inline int elf_sym__is_function(const GElf_Sym *sym)
190{ 190{
191 return elf_sym__type(sym) == STT_FUNC && 191 return elf_sym__type(sym) == STT_FUNC &&
192 sym->st_name != 0 && 192 sym->st_name != 0 &&
193 sym->st_shndx != SHN_UNDEF; 193 sym->st_shndx != SHN_UNDEF &&
194 sym->st_size != 0;
194} 195}
195 196
196static inline const char *elf_sym__name(const GElf_Sym *sym, 197static 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 return sec; 223 return sec;
223} 224}
224 225
225static int dso__load(struct dso *self) 226static int dso__load_sym(struct dso *self, int fd, char *name)
226{ 227{
227 Elf_Data *symstrs; 228 Elf_Data *symstrs;
228 uint32_t nr_syms; 229 uint32_t nr_syms;
229 int fd, err = -1; 230 int err = -1;
230 uint32_t index; 231 uint32_t index;
231 GElf_Ehdr ehdr; 232 GElf_Ehdr ehdr;
232 GElf_Shdr shdr; 233 GElf_Shdr shdr;
@@ -234,16 +235,12 @@ static int dso__load(struct dso *self)
234 GElf_Sym sym; 235 GElf_Sym sym;
235 Elf_Scn *sec; 236 Elf_Scn *sec;
236 Elf *elf; 237 Elf *elf;
237 238 int nr = 0;
238
239 fd = open(self->name, O_RDONLY);
240 if (fd == -1)
241 return -1;
242 239
243 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL); 240 elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
244 if (elf == NULL) { 241 if (elf == NULL) {
245 fprintf(stderr, "%s: cannot read %s ELF file.\n", 242 fprintf(stderr, "%s: cannot read %s ELF file.\n",
246 __func__, self->name); 243 __func__, name);
247 goto out_close; 244 goto out_close;
248 } 245 }
249 246
@@ -292,16 +289,63 @@ static int dso__load(struct dso *self)
292 goto out_elf_end; 289 goto out_elf_end;
293 290
294 dso__insert_symbol(self, f); 291 dso__insert_symbol(self, f);
292
293 nr++;
295 } 294 }
296 295
297 err = 0; 296 err = nr;
298out_elf_end: 297out_elf_end:
299 elf_end(elf); 298 elf_end(elf);
300out_close: 299out_close:
301 close(fd);
302 return err; 300 return err;
303} 301}
304 302
303static int dso__load(struct dso *self)
304{
305 int size = strlen(self->name) + sizeof("/usr/lib/debug%s.debug");
306 char *name = malloc(size);
307 int variant = 0;
308 int ret = -1;
309 int fd;
310
311 if (!name)
312 return -1;
313
314more:
315 do {
316 switch (variant) {
317 case 0: /* Fedora */
318 snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
319 break;
320 case 1: /* Ubuntu */
321 snprintf(name, size, "/usr/lib/debug%s", self->name);
322 break;
323 case 2: /* Sane people */
324 snprintf(name, size, "%s", self->name);
325 break;
326
327 default:
328 goto out;
329 }
330 variant++;
331
332 fd = open(name, O_RDONLY);
333 } while (fd < 0);
334
335 ret = dso__load_sym(self, fd, name);
336 close(fd);
337
338 /*
339 * Some people seem to have debuginfo files _WITHOUT_ debug info!?!?
340 */
341 if (!ret)
342 goto more;
343
344out:
345 free(name);
346 return ret;
347}
348
305static size_t dso__fprintf(struct dso *self, FILE *fp) 349static size_t dso__fprintf(struct dso *self, FILE *fp)
306{ 350{
307 size_t ret = fprintf(fp, "dso: %s\n", self->name); 351 size_t ret = fprintf(fp, "dso: %s\n", self->name);
@@ -336,11 +380,23 @@ static struct dso *dsos__find(const char *name)
336static struct dso *dsos__findnew(const char *name) 380static struct dso *dsos__findnew(const char *name)
337{ 381{
338 struct dso *dso = dsos__find(name); 382 struct dso *dso = dsos__find(name);
383 int nr;
339 384
340 if (dso == NULL) { 385 if (dso == NULL) {
341 dso = dso__new(name); 386 dso = dso__new(name);
342 if (dso != NULL && dso__load(dso) < 0) 387 if (!dso)
388 goto out_delete_dso;
389
390 nr = dso__load(dso);
391 if (nr < 0) {
392 fprintf(stderr, "Failed to open: %s\n", name);
343 goto out_delete_dso; 393 goto out_delete_dso;
394 }
395 if (!nr) {
396 fprintf(stderr,
397 "Failed to find debug symbols for: %s, maybe install a debug package?\n",
398 name);
399 }
344 400
345 dsos__add(dso); 401 dsos__add(dso);
346 } 402 }
@@ -547,9 +603,9 @@ symhist__fprintf(struct symhist *self, uint64_t total_samples, FILE *fp)
547 size_t ret; 603 size_t ret;
548 604
549 if (total_samples) 605 if (total_samples)
550 ret = fprintf(fp, "%5.2f", (self->count * 100.0) / total_samples); 606 ret = fprintf(fp, "%5.2f%% ", (self->count * 100.0) / total_samples);
551 else 607 else
552 ret = fprintf(fp, "%12d", self->count); 608 ret = fprintf(fp, "%12d ", self->count);
553 609
554 ret += fprintf(fp, "%14s [%c] ", 610 ret += fprintf(fp, "%14s [%c] ",
555 thread__name(self->thread, bf, sizeof(bf)), 611 thread__name(self->thread, bf, sizeof(bf)),
@@ -922,10 +978,12 @@ more:
922 } 978 }
923 default: { 979 default: {
924broken_event: 980broken_event:
925 fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n", 981 if (dump_trace)
926 (void *)(offset + head), 982 fprintf(stderr, "%p [%p]: skipping unknown header type: %d\n",
927 (void *)(long)(event->header.size), 983 (void *)(offset + head),
928 event->header.type); 984 (void *)(long)(event->header.size),
985 event->header.type);
986
929 total_unknown++; 987 total_unknown++;
930 988
931 /* 989 /*