Skip to content

Commit

Permalink
perf symbols: /proc/kallsyms does not sort module symbols
Browse files Browse the repository at this point in the history
kallsyms__parse assumes that /proc/kallsyms is sorted and sets the end
of the previous symbol to the start of the current one.

Unfortunately module symbols are not sorted, eg:

ffffffffa0081f30 t e1000_clean_rx_irq   [e1000e]
ffffffffa00817a0 t e1000_alloc_rx_buffers       [e1000e]

Some symbols end up with a negative length and others have a length
larger than they should. This results in confusing perf output.

We already have a function to fixup the end of zero length symbols so
use that instead.

Cc: Eric B Munson <emunson@mgebm.net>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20110824065242.969681349@samba.org
Signed-off-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Anton Blanchard authored and Arnaldo Carvalho de Melo committed Sep 23, 2011
1 parent adb0918 commit 3f5a427
Showing 1 changed file with 11 additions and 22 deletions.
33 changes: 11 additions & 22 deletions tools/perf/util/symbol.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,18 +438,11 @@ int kallsyms__parse(const char *filename, void *arg,
char *line = NULL;
size_t n;
int err = -1;
u64 prev_start = 0;
char prev_symbol_type = 0;
char *prev_symbol_name;
FILE *file = fopen(filename, "r");

if (file == NULL)
goto out_failure;

prev_symbol_name = malloc(KSYM_NAME_LEN);
if (prev_symbol_name == NULL)
goto out_close;

err = 0;

while (!feof(file)) {
Expand Down Expand Up @@ -480,24 +473,18 @@ int kallsyms__parse(const char *filename, void *arg,
break;
}

if (prev_symbol_type) {
u64 end = start;
if (end != prev_start)
--end;
err = process_symbol(arg, prev_symbol_name,
prev_symbol_type, prev_start, end);
if (err)
break;
}

memcpy(prev_symbol_name, symbol_name, len + 1);
prev_symbol_type = symbol_type;
prev_start = start;
/*
* module symbols are not sorted so we add all
* symbols with zero length and rely on
* symbols__fixup_end() to fix it up.
*/
err = process_symbol(arg, symbol_name,
symbol_type, start, start);
if (err)
break;
}

free(prev_symbol_name);
free(line);
out_close:
fclose(file);
return err;

Expand Down Expand Up @@ -703,6 +690,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename,
if (dso__load_all_kallsyms(dso, filename, map) < 0)
return -1;

symbols__fixup_end(&dso->symbols[map->type]);

if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
else
Expand Down

0 comments on commit 3f5a427

Please sign in to comment.