Commit 3f5a42722b9e78a434d5a4ee5e607dc33c69ac80
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; |