aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lutomirski <luto@mit.edu>2011-03-24 00:36:56 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-03-28 13:44:15 -0400
commit6c6804fb2cef2d6aceb38b0eb0803210d77ff390 (patch)
treebb5a8a79c24f7f9f41b0ca076b9800cb3a840d7a
parent18bcd0c8cb7d85a9063b88ec810dc1cdc0974518 (diff)
perf symbols: Fix vsyscall symbol lookup
Perf can't currently trace into the vsyscall page. It looks like it was meant to work. Tested on 2.6.38 and today's -git. The bug is easy to reproduce. Compile this: int main() { int i; struct timespec t; for(i = 0; i < 10000000; i++) clock_gettime(CLOCK_MONOTONIC, &t); return 0; } and run it through perf record; perf report. The top entry shows "[unknown]" and you can't zoom in. It looks like there are two issues. The first is a that a test for user mode executing in kernel space is backwards. (That's the first hunk below). The second (I think) is that something's wrong with the code that generates lots of little struct dso objects for different sections -- when it runs on vmlinux it results in bogus long_name values which cause objdump to fail. Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> LPU-Reference: <AANLkTikxSw5+wJZUWNz++nL7mgivCh_Zf=2Kq6=f9Ce_@mail.gmail.com> Signed-off-by: Andy Lutomirski <luto@mit.edu> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r--tools/perf/util/event.c2
-rw-r--r--tools/perf/util/symbol.c3
2 files changed, 4 insertions, 1 deletions
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2b15c362ef56..1023f67633a4 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -710,7 +710,7 @@ try_again:
710 * in the whole kernel symbol list. 710 * in the whole kernel symbol list.
711 */ 711 */
712 if ((long long)al->addr < 0 && 712 if ((long long)al->addr < 0 &&
713 cpumode == PERF_RECORD_MISC_KERNEL && 713 cpumode == PERF_RECORD_MISC_USER &&
714 machine && mg != &machine->kmaps) { 714 machine && mg != &machine->kmaps) {
715 mg = &machine->kmaps; 715 mg = &machine->kmaps;
716 goto try_again; 716 goto try_again;
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 17df793c8924..8f73907a959e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
1196 if (curr_dso == NULL) 1196 if (curr_dso == NULL)
1197 goto out_elf_end; 1197 goto out_elf_end;
1198 curr_dso->kernel = self->kernel; 1198 curr_dso->kernel = self->kernel;
1199 curr_dso->long_name = self->long_name;
1200 curr_dso->long_name_len = self->long_name_len;
1199 curr_map = map__new2(start, curr_dso, 1201 curr_map = map__new2(start, curr_dso,
1200 map->type); 1202 map->type);
1201 if (curr_map == NULL) { 1203 if (curr_map == NULL) {
@@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
1842 if (fd < 0) 1844 if (fd < 0)
1843 return -1; 1845 return -1;
1844 1846
1847 dso__set_long_name(self, (char *)vmlinux);
1845 dso__set_loaded(self, map->type); 1848 dso__set_loaded(self, map->type);
1846 err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0); 1849 err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
1847 close(fd); 1850 close(fd);