Commit 3f5a42722b9e78a434d5a4ee5e607dc33c69ac80

Authored by Anton Blanchard
Committed by Arnaldo Carvalho de Melo
1 parent adb0918463

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>

Showing 1 changed file with 11 additions and 22 deletions Side-by-side Diff

tools/perf/util/symbol.c
... ... @@ -438,18 +438,11 @@
438 438 char *line = NULL;
439 439 size_t n;
440 440 int err = -1;
441   - u64 prev_start = 0;
442   - char prev_symbol_type = 0;
443   - char *prev_symbol_name;
444 441 FILE *file = fopen(filename, "r");
445 442  
446 443 if (file == NULL)
447 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 446 err = 0;
454 447  
455 448 while (!feof(file)) {
456 449  
457 450  
... ... @@ -480,24 +473,18 @@
480 473 break;
481 474 }
482 475  
483   - if (prev_symbol_type) {
484   - u64 end = start;
485   - if (end != prev_start)
486   - --end;
487   - err = process_symbol(arg, prev_symbol_name,
488   - prev_symbol_type, prev_start, end);
489   - if (err)
490   - break;
491   - }
492   -
493   - memcpy(prev_symbol_name, symbol_name, len + 1);
494   - prev_symbol_type = symbol_type;
495   - prev_start = start;
  476 + /*
  477 + * module symbols are not sorted so we add all
  478 + * symbols with zero length and rely on
  479 + * symbols__fixup_end() to fix it up.
  480 + */
  481 + err = process_symbol(arg, symbol_name,
  482 + symbol_type, start, start);
  483 + if (err)
  484 + break;
496 485 }
497 486  
498   - free(prev_symbol_name);
499 487 free(line);
500   -out_close:
501 488 fclose(file);
502 489 return err;
503 490  
... ... @@ -702,6 +689,8 @@
702 689  
703 690 if (dso__load_all_kallsyms(dso, filename, map) < 0)
704 691 return -1;
  692 +
  693 + symbols__fixup_end(&dso->symbols[map->type]);
705 694  
706 695 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
707 696 dso->symtab_type = SYMTAB__GUEST_KALLSYMS;