perf symbols: /proc/kallsyms does not sort module symbols
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>
This commit is contained in:
parent
adb0918463
commit
3f5a42722b
1 changed files with 11 additions and 22 deletions
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue