Skip to content

Commit

Permalink
perf symbols: Fix vsyscall symbol lookup
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Andrew Lutomirski authored and Arnaldo Carvalho de Melo committed Mar 28, 2011
1 parent 18bcd0c commit 6c6804f
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tools/perf/util/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ void thread__find_addr_map(struct thread *self,
* in the whole kernel symbol list.
*/
if ((long long)al->addr < 0 &&
cpumode == PERF_RECORD_MISC_KERNEL &&
cpumode == PERF_RECORD_MISC_USER &&
machine && mg != &machine->kmaps) {
mg = &machine->kmaps;
goto try_again;
Expand Down
3 changes: 3 additions & 0 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name,
if (curr_dso == NULL)
goto out_elf_end;
curr_dso->kernel = self->kernel;
curr_dso->long_name = self->long_name;
curr_dso->long_name_len = self->long_name_len;
curr_map = map__new2(start, curr_dso,
map->type);
if (curr_map == NULL) {
Expand Down Expand Up @@ -1842,6 +1844,7 @@ int dso__load_vmlinux(struct dso *self, struct map *map,
if (fd < 0)
return -1;

dso__set_long_name(self, (char *)vmlinux);
dso__set_loaded(self, map->type);
err = dso__load_sym(self, map, symfs_vmlinux, fd, filter, 0, 0);
close(fd);
Expand Down

0 comments on commit 6c6804f

Please sign in to comment.