diff options
author | Anton Blanchard <anton@samba.org> | 2011-08-24 02:40:15 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-09-23 13:36:12 -0400 |
commit | 3f5a42722b9e78a434d5a4ee5e607dc33c69ac80 (patch) | |
tree | 9e6afedc145ecb85a3cd80916cac5717547e9755 /tools | |
parent | adb091846318f86e4f46c7d6a7b40d2f478abdbe (diff) |
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>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/symbol.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index bb5d32f38af2..f119e85dc6c2 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -438,18 +438,11 @@ int kallsyms__parse(const char *filename, void *arg, | |||
438 | char *line = NULL; | 438 | char *line = NULL; |
439 | size_t n; | 439 | size_t n; |
440 | int err = -1; | 440 | int err = -1; |
441 | u64 prev_start = 0; | ||
442 | char prev_symbol_type = 0; | ||
443 | char *prev_symbol_name; | ||
444 | FILE *file = fopen(filename, "r"); | 441 | FILE *file = fopen(filename, "r"); |
445 | 442 | ||
446 | if (file == NULL) | 443 | if (file == NULL) |
447 | goto out_failure; | 444 | goto out_failure; |
448 | 445 | ||
449 | prev_symbol_name = malloc(KSYM_NAME_LEN); | ||
450 | if (prev_symbol_name == NULL) | ||
451 | goto out_close; | ||
452 | |||
453 | err = 0; | 446 | err = 0; |
454 | 447 | ||
455 | while (!feof(file)) { | 448 | while (!feof(file)) { |
@@ -480,24 +473,18 @@ int kallsyms__parse(const char *filename, void *arg, | |||
480 | break; | 473 | break; |
481 | } | 474 | } |
482 | 475 | ||
483 | if (prev_symbol_type) { | 476 | /* |
484 | u64 end = start; | 477 | * module symbols are not sorted so we add all |
485 | if (end != prev_start) | 478 | * symbols with zero length and rely on |
486 | --end; | 479 | * symbols__fixup_end() to fix it up. |
487 | err = process_symbol(arg, prev_symbol_name, | 480 | */ |
488 | prev_symbol_type, prev_start, end); | 481 | err = process_symbol(arg, symbol_name, |
489 | if (err) | 482 | symbol_type, start, start); |
490 | break; | 483 | if (err) |
491 | } | 484 | break; |
492 | |||
493 | memcpy(prev_symbol_name, symbol_name, len + 1); | ||
494 | prev_symbol_type = symbol_type; | ||
495 | prev_start = start; | ||
496 | } | 485 | } |
497 | 486 | ||
498 | free(prev_symbol_name); | ||
499 | free(line); | 487 | free(line); |
500 | out_close: | ||
501 | fclose(file); | 488 | fclose(file); |
502 | return err; | 489 | return err; |
503 | 490 | ||
@@ -703,6 +690,8 @@ int dso__load_kallsyms(struct dso *dso, const char *filename, | |||
703 | if (dso__load_all_kallsyms(dso, filename, map) < 0) | 690 | if (dso__load_all_kallsyms(dso, filename, map) < 0) |
704 | return -1; | 691 | return -1; |
705 | 692 | ||
693 | symbols__fixup_end(&dso->symbols[map->type]); | ||
694 | |||
706 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) | 695 | if (dso->kernel == DSO_TYPE_GUEST_KERNEL) |
707 | dso->symtab_type = SYMTAB__GUEST_KALLSYMS; | 696 | dso->symtab_type = SYMTAB__GUEST_KALLSYMS; |
708 | else | 697 | else |