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;
|
char *line = NULL;
|
||||||
size_t n;
|
size_t n;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
u64 prev_start = 0;
|
|
||||||
char prev_symbol_type = 0;
|
|
||||||
char *prev_symbol_name;
|
|
||||||
FILE *file = fopen(filename, "r");
|
FILE *file = fopen(filename, "r");
|
||||||
|
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
goto out_failure;
|
goto out_failure;
|
||||||
|
|
||||||
prev_symbol_name = malloc(KSYM_NAME_LEN);
|
|
||||||
if (prev_symbol_name == NULL)
|
|
||||||
goto out_close;
|
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
while (!feof(file)) {
|
while (!feof(file)) {
|
||||||
|
@ -480,24 +473,18 @@ int kallsyms__parse(const char *filename, void *arg,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prev_symbol_type) {
|
/*
|
||||||
u64 end = start;
|
* module symbols are not sorted so we add all
|
||||||
if (end != prev_start)
|
* symbols with zero length and rely on
|
||||||
--end;
|
* symbols__fixup_end() to fix it up.
|
||||||
err = process_symbol(arg, prev_symbol_name,
|
*/
|
||||||
prev_symbol_type, prev_start, end);
|
err = process_symbol(arg, symbol_name,
|
||||||
if (err)
|
symbol_type, start, start);
|
||||||
break;
|
if (err)
|
||||||
}
|
break;
|
||||||
|
|
||||||
memcpy(prev_symbol_name, symbol_name, len + 1);
|
|
||||||
prev_symbol_type = symbol_type;
|
|
||||||
prev_start = start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(prev_symbol_name);
|
|
||||||
free(line);
|
free(line);
|
||||||
out_close:
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return err;
|
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)
|
if (dso__load_all_kallsyms(dso, filename, map) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
symbols__fixup_end(&dso->symbols[map->type]);
|
||||||
|
|
||||||
if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
|
||||||
dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
|
dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
|
||||||
else
|
else
|
||||||
|
|
Loading…
Add table
Reference in a new issue