aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/symbol.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-08-06 13:43:17 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-09 06:54:36 -0400
commit94cb9e385d5b4d55a5ae389baa10ad2835ea39bb (patch)
treeb089b9d5a20e9f35ced28880f6a98c511c89040e /tools/perf/util/symbol.c
parent8f18aec535b5ca513dd13b531730177d35175ffa (diff)
perf report: Add debug help for the finding of symbol bugs - show the symtab origin (DSO, build-id, kernel, etc)
Used with perf report --verbose: [acme@doppio linux-2.6-tip]$ perf report -v | head -16 5.17% firefox /usr/lib64/xulrunner-1.9.1/libxul.so 0x00000000005d8eee f [.] imgContainer::DrawFrameTo(gfxIImageFrame*, gfxIImageFrame*, nsRect&) 2.56% firefox /lib64/libpthread-2.10.1.so 0x0000000000008e02 d [.] __pthread_mutex_lock_internal 1.94% firefox /usr/lib64/xulrunner-1.9.1/libxul.so 0x0000000000d0af8f f [.] SearchTable 1.75% firefox [kernel] 0xffffffffff60013b k [.] vread_hpet 1.63% firefox /lib64/libpthread-2.10.1.so 0x000000000000a404 d [.] __pthread_mutex_unlock 1.47% firefox /usr/lib64/xulrunner-1.9.1/libmozjs.so 0x00000000000482ea f [.] js_Interpret 1.42% firefox /usr/lib64/xulrunner-1.9.1/libmozjs.so 0x000000000003eda3 f [.] JS_CallTracer 1.24% firefox [kernel] 0xffffffff8102ca4a k [k] read_hpet 1.16% firefox [kernel] 0xffffffff810f3dd4 k [k] fget_light 1.11% firefox /usr/lib64/xulrunner-1.9.1/libmozjs.so 0x00000000000567ff f [.] js_TraceObject 0.98% firefox /usr/lib64/firefox-3.5.2/firefox 0x000000000000dd23 b [.] arena_ralloc [acme@doppio linux-2.6-tip]$ The new field is just after the symbol address. To help in figuring out symbol resolution bugs. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/symbol.c')
-rw-r--r--tools/perf/util/symbol.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 16ddca202948..f1dcede14307 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -24,6 +24,16 @@ const char *sym_hist_filter;
24#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ 24#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
25#endif 25#endif
26 26
27enum dso_origin {
28 DSO__ORIG_KERNEL = 0,
29 DSO__ORIG_JAVA_JIT,
30 DSO__ORIG_FEDORA,
31 DSO__ORIG_UBUNTU,
32 DSO__ORIG_BUILDID,
33 DSO__ORIG_DSO,
34 DSO__ORIG_NOT_FOUND,
35};
36
27static struct symbol *symbol__new(u64 start, u64 len, 37static struct symbol *symbol__new(u64 start, u64 len,
28 const char *name, unsigned int priv_size, 38 const char *name, unsigned int priv_size,
29 u64 obj_start, int verbose) 39 u64 obj_start, int verbose)
@@ -81,6 +91,7 @@ struct dso *dso__new(const char *name, unsigned int sym_priv_size)
81 self->sym_priv_size = sym_priv_size; 91 self->sym_priv_size = sym_priv_size;
82 self->find_symbol = dso__find_symbol; 92 self->find_symbol = dso__find_symbol;
83 self->slen_calculated = 0; 93 self->slen_calculated = 0;
94 self->origin = DSO__ORIG_NOT_FOUND;
84 } 95 }
85 96
86 return self; 97 return self;
@@ -710,7 +721,7 @@ static char *dso__read_build_id(struct dso *self, int verbose)
710 ++raw; 721 ++raw;
711 bid += 2; 722 bid += 2;
712 } 723 }
713 if (verbose) 724 if (verbose >= 2)
714 printf("%s(%s): %s\n", __func__, self->name, build_id); 725 printf("%s(%s): %s\n", __func__, self->name, build_id);
715out_elf_end: 726out_elf_end:
716 elf_end(elf); 727 elf_end(elf);
@@ -720,11 +731,26 @@ out:
720 return build_id; 731 return build_id;
721} 732}
722 733
734char dso__symtab_origin(const struct dso *self)
735{
736 static const char origin[] = {
737 [DSO__ORIG_KERNEL] = 'k',
738 [DSO__ORIG_JAVA_JIT] = 'j',
739 [DSO__ORIG_FEDORA] = 'f',
740 [DSO__ORIG_UBUNTU] = 'u',
741 [DSO__ORIG_BUILDID] = 'b',
742 [DSO__ORIG_DSO] = 'd',
743 };
744
745 if (self == NULL || self->origin == DSO__ORIG_NOT_FOUND)
746 return '!';
747 return origin[self->origin];
748}
749
723int dso__load(struct dso *self, symbol_filter_t filter, int verbose) 750int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
724{ 751{
725 int size = PATH_MAX; 752 int size = PATH_MAX;
726 char *name = malloc(size), *build_id = NULL; 753 char *name = malloc(size), *build_id = NULL;
727 int variant = 0;
728 int ret = -1; 754 int ret = -1;
729 int fd; 755 int fd;
730 756
@@ -733,19 +759,26 @@ int dso__load(struct dso *self, symbol_filter_t filter, int verbose)
733 759
734 self->adjust_symbols = 0; 760 self->adjust_symbols = 0;
735 761
736 if (strncmp(self->name, "/tmp/perf-", 10) == 0) 762 if (strncmp(self->name, "/tmp/perf-", 10) == 0) {
737 return dso__load_perf_map(self, filter, verbose); 763 ret = dso__load_perf_map(self, filter, verbose);
764 self->origin = ret > 0 ? DSO__ORIG_JAVA_JIT :
765 DSO__ORIG_NOT_FOUND;
766 return ret;
767 }
768
769 self->origin = DSO__ORIG_FEDORA - 1;
738 770
739more: 771more:
740 do { 772 do {
741 switch (variant) { 773 self->origin++;
742 case 0: /* Fedora */ 774 switch (self->origin) {
775 case DSO__ORIG_FEDORA:
743 snprintf(name, size, "/usr/lib/debug%s.debug", self->name); 776 snprintf(name, size, "/usr/lib/debug%s.debug", self->name);
744 break; 777 break;
745 case 1: /* Ubuntu */ 778 case DSO__ORIG_UBUNTU:
746 snprintf(name, size, "/usr/lib/debug%s", self->name); 779 snprintf(name, size, "/usr/lib/debug%s", self->name);
747 break; 780 break;
748 case 2: 781 case DSO__ORIG_BUILDID:
749 build_id = dso__read_build_id(self, verbose); 782 build_id = dso__read_build_id(self, verbose);
750 if (build_id != NULL) { 783 if (build_id != NULL) {
751 snprintf(name, size, 784 snprintf(name, size,
@@ -754,16 +787,15 @@ more:
754 free(build_id); 787 free(build_id);
755 break; 788 break;
756 } 789 }
757 variant++; 790 self->origin++;
758 /* Fall thru */ 791 /* Fall thru */
759 case 3: /* Sane people */ 792 case DSO__ORIG_DSO:
760 snprintf(name, size, "%s", self->name); 793 snprintf(name, size, "%s", self->name);
761 break; 794 break;
762 795
763 default: 796 default:
764 goto out; 797 goto out;
765 } 798 }
766 variant++;
767 799
768 fd = open(name, O_RDONLY); 800 fd = open(name, O_RDONLY);
769 } while (fd < 0); 801 } while (fd < 0);
@@ -899,6 +931,9 @@ int dso__load_kernel(struct dso *self, const char *vmlinux,
899 if (err <= 0) 931 if (err <= 0)
900 err = dso__load_kallsyms(self, filter, verbose); 932 err = dso__load_kallsyms(self, filter, verbose);
901 933
934 if (err > 0)
935 self->origin = DSO__ORIG_KERNEL;
936
902 return err; 937 return err;
903} 938}
904 939