perf tools: Allow vmlinux to fallback to kallsyms on NO_LIBELF=1
Namhyung Kim
maintainerPATCH 1/3 perf tools: Allow vmlinux to fallback to kallsyms on NO_LIBELF=1
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
# Overhead Command Shared Object Symbol
# ........ ....... ................. ........................
#
34.51% swapper [kernel.kallsyms] [k] intel_idle
12.54% perf [kernel.kallsyms] [k] generic_exec_single
10.11% swapper [kernel.kallsyms] [k] int_sqrt
9.83% swapper [kernel.kallsyms] [k] hrtimer_interrupt
7.25% emacs [kernel.kallsyms] [k] __switch_to
7.06% sleep [kernel.kallsyms] [k] find_next_iomem_res
7.02% swapper [kernel.kallsyms] [k] run_timer_softirq
2.55% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq
1.90% swapper [kernel.kallsyms] [k] lapic_next_deadline
1.75% swapper [kernel.kallsyms] [k] native_sched_clock
1.49% swapper [kernel.kallsyms] [k] __schedule
1.20% swapper [kernel.kallsyms] [k] read_tsc
1.10% sleep [kernel.kallsyms] [k] current_kernel_time
0.99% swapper [kernel.kallsyms] [k] pick_next_task_rt
0.36% swapper [kernel.kallsyms] [k] group_sched_in
0.24% swapper [kernel.kallsyms] [k] x86_pmu_commit_txn
0.06% swapper [kernel.kallsyms] [k] intel_pmu_enable_all
0.03% perf [kernel.kallsyms] [k] intel_pmu_enable_all--- tools/perf/util/symbol-minimal.c | 3 +++ 1 file changed, 3 insertions(+)
tools/perf/util/symbol-minimal.c +3 -0
@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,unsigned char *build_id[BUILD_ID_SIZE ];int ret; +if (dso->kernel) +return 0 ;/* always use kallsyms */ + ret =fd__is_64_bit (ss->fd);if (ret >=0 ) dso->is_64_bit = ret;
Signature · 1 line
2.1.2
Namhyung Kim
maintainerPATCH 2/3 perf symbol: Implement a very simple ELF symbol parser
It'll be used to show (userspace) symbol names when libelf isn't (or cannot be) linked.
# Overhead Command Shared Object Symbol
# ........ .......... ................. .........................
#
37.01% mem-memcpy libc-2.17.so [.] __memcpy_ssse3_back
24.25% perf ld-2.17.so [.] _dl_relocate_object
22.16% perf [kernel.kallsyms] [k] kmem_cache_alloc
14.29% mem-memset libc-2.17.so [.] __memset_sse2
2.21% perf [kernel.kallsyms] [k] flush_signal_handlers
0.07% perf [kernel.kallsyms] [k] intel_pmu_enable_all--- tools/perf/util/symbol-minimal.c | 143 ++++++++++++++++++++++++++++++++++++--- tools/perf/util/symbol-minimal.h | 64 ++++++++++++++++++ tools/perf/util/symbol.h | 10 ++- 3 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 tools/perf/util/symbol-minimal.h
tools/perf/util/symbol-minimal.c +135 -8
@@ -1,11 +1,13 @@#include "symbol.h" #include "util.h" +#include "debug.h" #include <stdio.h> #include <fcntl.h> #include <string.h> #include <byteswap.h> #include <sys/stat.h> +#include <sys/mman.h> static bool check_need_swap (int file_endian)
@@ -242,22 +244,81 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size)return ret; } +static const char *symsrc__symname (struct symsrc *ss,Elf_Shdr *strsec,int idx) +{ +return ss->ptr + strsec->sh_offset + idx; +} +int symsrc__init (struct symsrc *ss,struct dso *dso__maybe_unused ,const char *name,enum dso_binary_type type) { -int fd =open (name,O_RDONLY ); +int fd; +unsigned i; +Elf_Ehdr ehdr; +struct stat stbuf; +void *ptr; + + fd =open (name,O_RDONLY );if (fd <0 )return -1 ; ss->name =strdup (name); -if (!ss->name) - goto out_close; +if (!ss->name) { +close (fd); +return -1 ; + } ss->fd = fd; ss->type = type; +/* only consider native case (no swap) */ +if (read (fd, &ehdr,sizeof (ehdr)) <0 ) + goto out_close; + +if (memcmp (ehdr.e_ident,ELFMAG ,SELFMAG ) || + ehdr.e_ident[EI_VERSION ] !=EV_CURRENT ) + goto out_close; + +if (ehdr.e_ident[EI_CLASS ] !=ELFCLASS ) + goto out_close; + +if (check_need_swap (ehdr.e_ident[EI_DATA ])) + goto out_close; + +if (ehdr.e_shentsize !=sizeof (Elf_Shdr)) + goto out_close; + +if (fstat (fd, &stbuf) <0 ) + goto out_close; + + ptr =mmap (NULL , stbuf.st_size,PROT_READ ,MAP_PRIVATE , fd,0 ); +if (ptr ==MAP_FAILED ) + goto out_close; + + ss->ptr = ptr; + ss->len = stbuf.st_size; + ss->sec = ptr + ehdr.e_shoff; + + ss->symtab =NULL ; +for (i =0 ; i < ehdr.e_shnum; i++) { +Elf_Shdr *shdrp = &ss->sec[i]; +const char *shname; + + shname =symsrc__symname (ss, &ss->sec[ehdr.e_shstrndx], + shdrp->sh_name); + +if (!strcmp (shname,".text" )) + ss->adjust_offset = shdrp->sh_addr - shdrp->sh_offset; + +if (shdrp->sh_type ==SHT_SYMTAB ) { + ss->symtab = shdrp; + ss->strtab = &ss->sec[shdrp->sh_link]; + } + } +return 0 ; + out_close:close (fd);return -1 ;
@@ -276,6 +337,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)void symsrc__destroy (struct symsrc *ss) { +munmap (ss->ptr, ss->len);zfree (&ss->name);close (ss->fd); }
@@ -332,7 +394,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, symbol_filter_t filter __maybe_unused, int kmodule __maybe_unused) { -unsigned char *build_id[BUILD_ID_SIZE ]; +Elf_Ehdr *ehdr = ss->ptr; +Elf_Sym *symtab; +size_t i, nr_sym;int ret;if (dso->kernel)
@@ -342,11 +406,74 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (ret >=0 ) dso->is_64_bit = ret; -if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) { -dso__set_build_id (dso, build_id); -return 1 ; +if (dso->has_build_id) { +u8 build_id[BUILD_ID_SIZE ]; + +if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) <0 ) +return -1 ; + +if (!dso__build_id_equal (dso, build_id)) +return -1 ; } -return 0 ; + +if (map->type !=MAP__FUNCTION ) +return 0 ; + +if (!ss->symtab) +return 0 ; + + symtab = ss->ptr + ss->symtab->sh_offset; + nr_sym = ss->symtab->sh_size / ss->symtab->sh_entsize; + +pr_debug4 ("loading symbols from %s\n" , ss->name); + ret =0 ; +for (i =0 ; i < nr_sym; i++) { +struct symbol *s; +Elf_Sym *sym = &symtab[i]; +const char *symname =symsrc__symname (ss, ss->strtab, sym->st_name); +unsigned long sym_addr = sym->st_value; + +if (ELF_ST_TYPE (sym->st_info) !=STT_FUNC ) +continue ; + +if (sym->st_shndx ==SHN_UNDEF ) +continue ; + +if (ehdr->e_machine ==EM_ARM ) { +/* Reject ARM ELF "mapping symbols": these aren't unique +* and don't identify functions, so will confuse the +* profile output: */ +if (!strcmp (symname,"$a" ) || + !strcmp (symname,"$d" ) || + !strcmp (symname,"$t" )) +continue ; + +/* On ARM, symbols for thumb functions have 1 added to +* the symbol address as a flag - remove it */ +if (sym->st_value &1 ) + sym_addr--; + } + sym_addr -= ss->adjust_offset; + +pr_debug4 ("sym: %s (%lx+%lu)\n" , symname, sym_addr, sym->st_size); + s =symbol__new (sym_addr, sym->st_size, +ELF_ST_BIND (sym->st_info), symname); +if (!s) +break ; + +if (filter &&filter (map, s)) +symbol__delete (s); +else { +symbols__insert (&dso->symbols[map->type], s); + ret++; + } + } + +if (ret >0 ) { +symbols__fixup_duplicate (&dso->symbols[map->type]); +symbols__fixup_end (&dso->symbols[map->type]); + } +return ret; } int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,
tools/perf/util/symbol-minimal.h new file +64 -0
64 lines not on this page · raw message
tools/perf/util/symbol.h +9 -1
@@ -18,8 +18,9 @@#ifdef HAVE_LIBELF_SUPPORT #include <libelf.h> #include <gelf.h> +#else +#include "symbol-minimal.h" #endif -#include <elf.h> #include "dso.h"
@@ -229,6 +230,13 @@ struct symsrc {bool adjust_symbols;bool is_64_bit; +#else +void *ptr; +size_t len; +Elf_Shdr *sec; +Elf_Shdr *symtab; +Elf_Shdr *strtab; +long adjust_offset;#endif };
Signature · 1 line
2.1.2
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 2/3] perf symbol: Implement a very simple ELF symbol parser
Em Fri, Nov 07, 2014 at 02:20:05PM +0900, Namhyung Kim escreveu:
Quoted 2 lines
It'll be used to show (userspace) symbol names when libelf isn't (or cannot be) linked.
Does this deals with prelink, etc?
- Arnaldo
Quoted 321 lines
# Overhead Command Shared Object Symbol # ........ .......... ................. ......................... # 37.01% mem-memcpy libc-2.17.so [.] __memcpy_ssse3_back 24.25% perf ld-2.17.so [.] _dl_relocate_object 22.16% perf [kernel.kallsyms] [k] kmem_cache_alloc 14.29% mem-memset libc-2.17.so [.] __memset_sse2 2.21% perf [kernel.kallsyms] [k] flush_signal_handlers 0.07% perf [kernel.kallsyms] [k] intel_pmu_enable_allCc Adrian Hunter <[email protected]>Signed-off-by Namhyung Kim <[email protected]>--- tools/perf/util/symbol-minimal.c | 143 ++++++++++++++++++++++++++++++++++++--- tools/perf/util/symbol-minimal.h | 64 ++++++++++++++++++ tools/perf/util/symbol.h | 10 ++- 3 files changed, 208 insertions(+), 9 deletions(-) create mode 100644 tools/perf/util/symbol-minimal.htools/perf/util/symbol-minimal.c +135
-8@@ -1,11 +1,13 @@#include "symbol.h" #include "util.h" +#include "debug.h" #include <stdio.h> #include <fcntl.h> #include <string.h> #include <byteswap.h> #include <sys/stat.h> +#include <sys/mman.h> static bool check_need_swap (int file_endian)@@ -242,22 +244,81 @@ int sysfs__read_build_id(const char *filename, void *build_id, size_t size)return ret; } +static const char *symsrc__symname (struct symsrc *ss,Elf_Shdr *strsec,int idx) +{ +return ss->ptr + strsec->sh_offset + idx; +} +int symsrc__init (struct symsrc *ss,struct dso *dso__maybe_unused ,const char *name,enum dso_binary_type type) { -int fd =open (name,O_RDONLY ); +int fd; +unsigned i; +Elf_Ehdr ehdr; +struct stat stbuf; +void *ptr; + + fd =open (name,O_RDONLY );if (fd <0 )return -1 ; ss->name =strdup (name); -if (!ss->name) - goto out_close; +if (!ss->name) { +close (fd); +return -1 ; + } ss->fd = fd; ss->type = type; +/* only consider native case (no swap) */ +if (read (fd, &ehdr,sizeof (ehdr)) <0 ) + goto out_close; + +if (memcmp (ehdr.e_ident,ELFMAG ,SELFMAG ) || + ehdr.e_ident[EI_VERSION ] !=EV_CURRENT ) + goto out_close; + +if (ehdr.e_ident[EI_CLASS ] !=ELFCLASS ) + goto out_close; + +if (check_need_swap (ehdr.e_ident[EI_DATA ])) + goto out_close; + +if (ehdr.e_shentsize !=sizeof (Elf_Shdr)) + goto out_close; + +if (fstat (fd, &stbuf) <0 ) + goto out_close; + + ptr =mmap (NULL , stbuf.st_size,PROT_READ ,MAP_PRIVATE , fd,0 ); +if (ptr ==MAP_FAILED ) + goto out_close; + + ss->ptr = ptr; + ss->len = stbuf.st_size; + ss->sec = ptr + ehdr.e_shoff; + + ss->symtab =NULL ; +for (i =0 ; i < ehdr.e_shnum; i++) { +Elf_Shdr *shdrp = &ss->sec[i]; +const char *shname; + + shname =symsrc__symname (ss, &ss->sec[ehdr.e_shstrndx], + shdrp->sh_name); + +if (!strcmp (shname,".text" )) + ss->adjust_offset = shdrp->sh_addr - shdrp->sh_offset; + +if (shdrp->sh_type ==SHT_SYMTAB ) { + ss->symtab = shdrp; + ss->strtab = &ss->sec[shdrp->sh_link]; + } + } +return 0 ; + out_close:close (fd);return -1 ;@@ -276,6 +337,7 @@ bool symsrc__has_symtab(struct symsrc *ss __maybe_unused)void symsrc__destroy (struct symsrc *ss) { +munmap (ss->ptr, ss->len);zfree (&ss->name);close (ss->fd); }@@ -332,7 +394,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, symbol_filter_t filter __maybe_unused, int kmodule __maybe_unused) { -unsigned char *build_id[BUILD_ID_SIZE ]; +Elf_Ehdr *ehdr = ss->ptr; +Elf_Sym *symtab; +size_t i, nr_sym;int ret;if (dso->kernel)@@ -342,11 +406,74 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (ret >=0 ) dso->is_64_bit = ret; -if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) { -dso__set_build_id (dso, build_id); -return 1 ; +if (dso->has_build_id) { +u8 build_id[BUILD_ID_SIZE ]; + +if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) <0 ) +return -1 ; + +if (!dso__build_id_equal (dso, build_id)) +return -1 ; } -return 0 ; + +if (map->type !=MAP__FUNCTION ) +return 0 ; + +if (!ss->symtab) +return 0 ; + + symtab = ss->ptr + ss->symtab->sh_offset; + nr_sym = ss->symtab->sh_size / ss->symtab->sh_entsize; + +pr_debug4 ("loading symbols from %s\n" , ss->name); + ret =0 ; +for (i =0 ; i < nr_sym; i++) { +struct symbol *s; +Elf_Sym *sym = &symtab[i]; +const char *symname =symsrc__symname (ss, ss->strtab, sym->st_name); +unsigned long sym_addr = sym->st_value; + +if (ELF_ST_TYPE (sym->st_info) !=STT_FUNC ) +continue ; + +if (sym->st_shndx ==SHN_UNDEF ) +continue ; + +if (ehdr->e_machine ==EM_ARM ) { +/* Reject ARM ELF "mapping symbols": these aren't unique +* and don't identify functions, so will confuse the +* profile output: */ +if (!strcmp (symname,"$a" ) || + !strcmp (symname,"$d" ) || + !strcmp (symname,"$t" )) +continue ; + +/* On ARM, symbols for thumb functions have 1 added to +* the symbol address as a flag - remove it */ +if (sym->st_value &1 ) + sym_addr--; + } + sym_addr -= ss->adjust_offset; + +pr_debug4 ("sym: %s (%lx+%lu)\n" , symname, sym_addr, sym->st_size); + s =symbol__new (sym_addr, sym->st_size, +ELF_ST_BIND (sym->st_info), symname); +if (!s) +break ; + +if (filter &&filter (map, s)) +symbol__delete (s); +else { +symbols__insert (&dso->symbols[map->type], s); + ret++; + } + } + +if (ret >0 ) { +symbols__fixup_duplicate (&dso->symbols[map->type]); +symbols__fixup_end (&dso->symbols[map->type]); + } +return ret; } int file__read_maps(int fd __maybe_unused, bool exe __maybe_unused,tools/perf/util/symbol-minimal.h new file +64
-0@@ -0,0 +1,64 @@ +#ifndef __PERF_SYMBOL_MINIMAL_H +#define __PERF_SYMBOL_MINIMAL_H + +#include <elf.h> +#include <linux/bitops.h> + +#if BITS_PER_LONG ==32 + +# define ELFCLASS ELFCLASS32 + +# define Elf_Half Elf32_Half +# define Elf_Word Elf32_Word +# define Elf_Sword Elf32_Sword +# define Elf_Xword Elf32_Xword +# define Elf_Sxword Elf32_Sxword +# define Elf_Addr Elf32_Addr +# define Elf_Off Elf32_Off +# define Elf_Section Elf32_Section +# define Elf_Versym Elf32_Versym + +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Shdr Elf32_Shdr +# define Elf_Nhdr Elf32_Nhdr +# define Elf_Sym Elf32_Sym +# define Elf_Syminfo Elf32_Syminfo +# define Elf_Rel Elf32_Rel +# define Elf_Rela Elf32_Rela +# define Elf_Dyn Elf32_Dyn + +# define ELF_ST_BIND (val) ELF32_ST_BIND(val) +# define ELF_ST_TYPE (val) ELF32_ST_TYPE(val) +# define ELF_ST_INFO (bind, type) ELF32_ST_INFO(bind, type) + +#else /* BITS_PER_LONG == 64 */ + +# define ELFCLASS ELFCLASS64 + +# define Elf_Half Elf64_Half +# define Elf_Word Elf64_Word +# define Elf_Sword Elf64_Sword +# define Elf_Xword Elf64_Xword +# define Elf_Sxword Elf64_Sxword +# define Elf_Addr Elf64_Addr +# define Elf_Off Elf64_Off +# define Elf_Section Elf64_Section +# define Elf_Versym Elf64_Versym + +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Shdr Elf64_Shdr +# define Elf_Nhdr Elf64_Nhdr +# define Elf_Sym Elf64_Sym +# define Elf_Syminfo Elf64_Syminfo +# define Elf_Rel Elf64_Rel +# define Elf_Rela Elf64_Rela +# define Elf_Dyn Elf64_Dyn + +# define ELF_ST_BIND (val) ELF64_ST_BIND(val) +# define ELF_ST_TYPE (val) ELF64_ST_TYPE(val) +# define ELF_ST_INFO (bind, type) ELF64_ST_INFO(bind, type) + +#endif /* BITS_PER_LONG == 64 */ +#endif /* __PERF_SYMBOL_MINIMAL_H */ tools/perf/util/symbol.h +9
-1@@ -18,8 +18,9 @@#ifdef HAVE_LIBELF_SUPPORT #include <libelf.h> #include <gelf.h> +#else +#include "symbol-minimal.h" #endif -#include <elf.h> #include "dso.h" @@ -229,6 +230,13 @@ struct symsrc {bool adjust_symbols;bool is_64_bit; +#else +void *ptr; +size_t len; +Elf_Shdr *sec; +Elf_Shdr *symtab; +Elf_Shdr *strtab; +long adjust_offset;#endif };Signature · 1 line
2.1.2
Namhyung Kim
maintainerRe: [PATCH 2/3] perf symbol: Implement a very simple ELF symbol parser
Hi Arnaldo,
Quoted 5 lines · Arnaldo Carvalho de Melo
Em Fri, Nov 07, 2014 at 02:20:05PM +0900, Namhyung Kim escreveu:
Quoted 2 lines
It'll be used to show (userspace) symbol names when libelf isn't (or cannot be) linked.
Does this deals with prelink, etc?
I believe so. :)
Quoted 5 lines
Quoted 5 lines
# Overhead Command Shared Object Symbol # ........ .......... ................. ......................... # 37.01% mem-memcpy libc-2.17.so [.] __memcpy_ssse3_back
namhyung@sejong:linux$ readelf -WS /lib64/libc-2.17.so | grep prelink
[41] .gnu.prelink_undo PROGBITS 0000000000000000 200368 000c30 01 0 0 8namhyung@sejong:linux$ nm /lib64/libc-2.17.so | grep __memcpy_ssse3_back 0000003153f46f40 t __memcpy_ssse3_back
Thanks,
Namhyung
Quoted 5 lines
Quoted 5 lines
24.25% perf ld-2.17.so [.] _dl_relocate_object 22.16% perf [kernel.kallsyms] [k] kmem_cache_alloc 14.29% mem-memset libc-2.17.so [.] __memset_sse2 2.21% perf [kernel.kallsyms] [k] flush_signal_handlers 0.07% perf [kernel.kallsyms] [k] intel_pmu_enable_all
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 2/3] perf symbol: Implement a very simple ELF symbol parser
Em Mon, Nov 10, 2014 at 03:36:48PM +0900, Namhyung Kim escreveu:
Quoted 17 lines
Hi Arnaldo,
Quoted 5 lines · Arnaldo Carvalho de Melo
Em Fri, Nov 07, 2014 at 02:20:05PM +0900, Namhyung Kim escreveu:
Quoted 2 lines
It'll be used to show (userspace) symbol names when libelf isn't (or cannot be) linked.
Does this deals with prelink, etc?
I believe so. :)
Quoted 5 lines
Quoted 5 lines
# Overhead Command Shared Object Symbol # ........ .......... ................. ......................... # 37.01% mem-memcpy libc-2.17.so [.] __memcpy_ssse3_back
Quoted 5 lines
namhyung@sejong:linux$ readelf -WS /lib64/libc-2.17.so | grep prelink [41] .gnu.prelink_undo PROGBITS 0000000000000000 200368 000c30 01 0 0 8namhyung@sejong:linux$ nm /lib64/libc-2.17.so | grep __memcpy_ssse3_back 0000003153f46f40 t __memcpy_ssse3_back
Right, in this case most of the samples seems to map to what is expected for that workload, and the binary was prelinked. Good.
What about binaries that are not prelinked? IIRC there is code in the full blown ELF symbol-elf.c file to detect that and act accordingly, from a _very_ quick look I didn't saw it in this minimalistic ELF symtab reader, hence my question.
- Arnaldo
Quoted 10 lines
Thanks,
NamhyungQuoted 5 lines
Quoted 5 lines
24.25% perf ld-2.17.so [.] _dl_relocate_object 22.16% perf [kernel.kallsyms] [k] kmem_cache_alloc 14.29% mem-memset libc-2.17.so [.] __memset_sse2 2.21% perf [kernel.kallsyms] [k] flush_signal_handlers 0.07% perf [kernel.kallsyms] [k] intel_pmu_enable_all
Namhyung Kim
maintainerRe: [PATCH 2/3] perf symbol: Implement a very simple ELF symbol parser
Quoted 24 lines · Arnaldo Carvalho de Melo
Em Mon, Nov 10, 2014 at 03:36:48PM +0900, Namhyung Kim escreveu:
Quoted 17 lines
Hi Arnaldo,
Quoted 5 lines · Arnaldo Carvalho de Melo
Em Fri, Nov 07, 2014 at 02:20:05PM +0900, Namhyung Kim escreveu:
Quoted 2 lines
It'll be used to show (userspace) symbol names when libelf isn't (or cannot be) linked.
Does this deals with prelink, etc?
I believe so. :)
Quoted 5 lines
Quoted 5 lines
# Overhead Command Shared Object Symbol # ........ .......... ................. ......................... # 37.01% mem-memcpy libc-2.17.so [.] __memcpy_ssse3_backQuoted 5 lines
namhyung@sejong:linux$ readelf -WS /lib64/libc-2.17.so | grep prelink [41] .gnu.prelink_undo PROGBITS 0000000000000000 200368 000c30 01 0 0 8namhyung@sejong:linux$ nm /lib64/libc-2.17.so | grep __memcpy_ssse3_back 0000003153f46f40 t __memcpy_ssse3_back
Quoted 7 lines
Right, in this case most of the samples seems to map to what is expected for that workload, and the binary was prelinked. Good.
What about binaries that are not prelinked? IIRC there is code in the full blown ELF
symbol-elf.cfile to detect that and act accordingly, from a _very_ quick look I didn't saw it in this minimalistic ELF symtab reader, hence my question.
AFAIK we deal with prelink'ed binary and normal binary as same way - we only cares about the file offsets.
$ perf top --stdio
PerfTop: 110 irqs/sec kernel:70.0% exact: 0.0% [4000Hz cycles], (all, 12 CPUs)
--------------------------------------------------------------------------------------------
9.42% perf [.] map__process_kallsym_symbol
8.91% [kernel] [k] kallsyms_expand_symbol.constprop.1
6.80% [kernel] [k] memcpy
6.08% [kernel] [k] vsnprintf
...Thanks,
Namhyung
Namhyung Kim
maintainerPATCH 3/3 perf tools: Clean up libelf feature support code
In reply to Namhyung KimCurrent EXTLIBS contains -lelf by default and removes it when libelf is not detected. This is little bit confusing since we can now build perf without libelf so there's no need to handle it differently than other libraries.
--- tools/perf/Makefile.perf | 2 -- tools/perf/config/Makefile | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-)
tools/perf/Makefile.perf +0 -2
@@ -495,8 +495,6 @@ ifneq ($(OUTPUT),) endif ifdef NO_LIBELF -EXTLIBS := $(filter-out -lelf,$(EXTLIBS)) - # Remove ELF/DWARF dependent codes LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS)) LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
tools/perf/config/Makefile +3 -2
@@ -150,7 +150,7 @@ CFLAGS += -std=gnu99 # adding assembler files missing the .GNU-stack linker note. LDFLAGS += -Wl,-z,noexecstack -EXTLIBS = -lelf -lpthread -lrt -lm -ldl +EXTLIBS = -lpthread -lrt -lm -ldl ifneq ($(OUTPUT),) OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
@@ -354,6 +354,7 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT + EXTLIBS += -lelf ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
@@ -373,7 +374,7 @@ ifndef NO_LIBELF else CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) - EXTLIBS += -lelf -ldw + EXTLIBS += -ldw endif # PERF_HAVE_DWARF_REGS endif # NO_DWARF endif # NO_LIBELF
Signature · 1 line
2.1.2
tip-bot for Namhyung Kim
merge bot[tip:perf/core] perf tools: Clean up libelf feature support code
perf tools: Clean up libelf feature support code
Commit-ID: 5e2d4d0e88dac4003cf96aca00d63aff2314391e Gitweb: http://git.kernel.org/tip/5e2d4d0e88dac4003cf96aca00d63aff2314391e Author: Namhyung Kim <[email protected]> AuthorDate: Fri, 7 Nov 2014 14:20:06 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 19 Nov 2014 12:33:46 -0300
perf tools: Clean up libelf feature support code
Current EXTLIBS contains -lelf by default and removes it when libelf is not detected.
This is little bit confusing since we can now build perf without libelf so there's no need to handle it differently than other libraries.
--- tools/perf/Makefile.perf | 2 -- tools/perf/config/Makefile | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-)
tools/perf/Makefile.perf +0 -2
@@ -497,8 +497,6 @@ ifneq ($(OUTPUT),) endif ifdef NO_LIBELF -EXTLIBS := $(filter-out -lelf,$(EXTLIBS)) - # Remove ELF/DWARF dependent codes LIB_OBJS := $(filter-out $(OUTPUT)util/symbol-elf.o,$(LIB_OBJS)) LIB_OBJS := $(filter-out $(OUTPUT)util/dwarf-aux.o,$(LIB_OBJS))
tools/perf/config/Makefile +3 -2
@@ -150,7 +150,7 @@ CFLAGS += -std=gnu99 # adding assembler files missing the .GNU-stack linker note. LDFLAGS += -Wl,-z,noexecstack -EXTLIBS = -lelf -lpthread -lrt -lm -ldl +EXTLIBS = -lpthread -lrt -lm -ldl ifneq ($(OUTPUT),) OUTPUT_FEATURES = $(OUTPUT)config/feature-checks/
@@ -354,6 +354,7 @@ endif # NO_LIBELF ifndef NO_LIBELF CFLAGS += -DHAVE_LIBELF_SUPPORT + EXTLIBS += -lelf ifeq ($(feature-libelf-mmap), 1) CFLAGS += -DHAVE_LIBELF_MMAP_SUPPORT
@@ -373,7 +374,7 @@ ifndef NO_LIBELF else CFLAGS += -DHAVE_DWARF_SUPPORT $(LIBDW_CFLAGS) LDFLAGS += $(LIBDW_LDFLAGS) - EXTLIBS += -lelf -ldw + EXTLIBS += -ldw endif # PERF_HAVE_DWARF_REGS endif # NO_DWARF endif # NO_LIBELF
Peter Zijlstra
maintainerQuoted 43 lines · Namhyung Kim
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
# Overhead Command Shared Object Symbol # ........ ....... ................. ........................ # 34.51% swapper [kernel.kallsyms] [k] intel_idle 12.54% perf [kernel.kallsyms] [k] generic_exec_single 10.11% swapper [kernel.kallsyms] [k] int_sqrt 9.83% swapper [kernel.kallsyms] [k] hrtimer_interrupt 7.25% emacs [kernel.kallsyms] [k] __switch_to 7.06% sleep [kernel.kallsyms] [k] find_next_iomem_res 7.02% swapper [kernel.kallsyms] [k] run_timer_softirq 2.55% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq 1.90% swapper [kernel.kallsyms] [k] lapic_next_deadline 1.75% swapper [kernel.kallsyms] [k] native_sched_clock 1.49% swapper [kernel.kallsyms] [k] __schedule 1.20% swapper [kernel.kallsyms] [k] read_tsc 1.10% sleep [kernel.kallsyms] [k] current_kernel_time 0.99% swapper [kernel.kallsyms] [k] pick_next_task_rt 0.36% swapper [kernel.kallsyms] [k] group_sched_in 0.24% swapper [kernel.kallsyms] [k] x86_pmu_commit_txn 0.06% swapper [kernel.kallsyms] [k] intel_pmu_enable_all 0.03% perf [kernel.kallsyms] [k] intel_pmu_enable_allReported-by Peter Zijlstra <[email protected]>Cc Adrian Hunter <[email protected]>Signed-off-by Namhyung Kim <[email protected]>--- tools/perf/util/symbol-minimal.c | 3 +++ 1 file changed, 3 insertions(+)tools/perf/util/symbol-minimal.c +0
-0
tools/perf/util/symbol-minimal.c int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, · line 343
Quoted 9 lines
tools/perf/util/symbol-minimal.c +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,unsigned char *build_id[BUILD_ID_SIZE ];int ret; +if (dso->kernel) +return 0 ;/* always use kallsyms */ + ret =fd__is_64_bit (ss->fd);if (ret >=0 ) dso->is_64_bit = ret;
Why does this live in the minimal implementation; should we not always discard ELF files with 0 symbols?
Suppose I have a vmlinux but removed all symbols from it; I want it to fall back to kallsyms too.
Namhyung Kim
maintainerHi Peter,
2014-11-07 (금), 09:27 +0100, Peter Zijlstra:
Quoted 57 lines · Namhyung Kim
Quoted 43 lines
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
# Overhead Command Shared Object Symbol # ........ ....... ................. ........................ # 34.51% swapper [kernel.kallsyms] [k] intel_idle 12.54% perf [kernel.kallsyms] [k] generic_exec_single 10.11% swapper [kernel.kallsyms] [k] int_sqrt 9.83% swapper [kernel.kallsyms] [k] hrtimer_interrupt 7.25% emacs [kernel.kallsyms] [k] __switch_to 7.06% sleep [kernel.kallsyms] [k] find_next_iomem_res 7.02% swapper [kernel.kallsyms] [k] run_timer_softirq 2.55% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq 1.90% swapper [kernel.kallsyms] [k] lapic_next_deadline 1.75% swapper [kernel.kallsyms] [k] native_sched_clock 1.49% swapper [kernel.kallsyms] [k] __schedule 1.20% swapper [kernel.kallsyms] [k] read_tsc 1.10% sleep [kernel.kallsyms] [k] current_kernel_time 0.99% swapper [kernel.kallsyms] [k] pick_next_task_rt 0.36% swapper [kernel.kallsyms] [k] group_sched_in 0.24% swapper [kernel.kallsyms] [k] x86_pmu_commit_txn 0.06% swapper [kernel.kallsyms] [k] intel_pmu_enable_all 0.03% perf [kernel.kallsyms] [k] intel_pmu_enable_allReported-by Peter Zijlstra <[email protected]>Cc Adrian Hunter <[email protected]>Signed-off-by Namhyung Kim <[email protected]>--- tools/perf/util/symbol-minimal.c | 3 +++ 1 file changed, 3 insertions(+)tools/perf/util/symbol-minimal.c +0
-0tools/perf/util/symbol-minimal.c int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, · line 343
Quoted 9 lines
tools/perf/util/symbol-minimal.c +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,unsigned char *build_id[BUILD_ID_SIZE ];int ret; +if (dso->kernel) +return 0 ;/* always use kallsyms */ + ret =fd__is_64_bit (ss->fd);if (ret >=0 ) dso->is_64_bit = ret;Why does this live in the minimal implementation; should we not always discard ELF files with 0 symbols?
Quoted 2 lines
Suppose I have a vmlinux but removed all symbols from it; I want it to fall back to kallsyms too.
I'm not sure I understood what you said correctly. With this change, dso__load_kernel_sym() always ends up calling dso__load_kallsyms() since dso__load_vmlinux() will always return 0;
So I think you'll fall back to kallsyms even though you have a vmlinux with symbol. This makes dso__load_sym() in the patch 2/3 simpler IMHO.
Thanks,
Namhyung
Peter Zijlstra
maintainerQuoted 6 lines · Namhyung Kim
Quoted 5 lines
Why does this live in the minimal implementation; should we not always discard ELF files with 0 symbols?
Suppose I have a vmlinux but removed all symbols from it; I want it to fall back to kallsyms too.
Quoted 6 lines
I'm not sure I understood what you said correctly. With this change,
dso__load_kernel_sym()always ends up callingdso__load_kallsyms()sincedso__load_vmlinux()will always return 0;So I think you'll fall back to kallsyms even though you have a vmlinux with symbol. This makes
dso__load_sym()in the patch 2/3 simpler IMHO.
But why have it specific to the minimal elf thing? Why not discard any DSO with 0 symbols and try the next option to acquire symbols?
Namhyung Kim
maintainerHi Peter,
Quoted 12 lines · Peter Zijlstra
Quoted 10 lines · Namhyung Kim
Quoted 5 lines
Why does this live in the minimal implementation; should we not always discard ELF files with 0 symbols?
Suppose I have a vmlinux but removed all symbols from it; I want it to fall back to kallsyms too.
I'm not sure I understood what you said correctly. With this change,
dso__load_kernel_sym()always ends up callingdso__load_kallsyms()sincedso__load_vmlinux()will always return 0;
Quoted 5 lines
Quoted 2 lines
So I think you'll fall back to kallsyms even though you have a vmlinux with symbol. This makes
dso__load_sym()in the patch 2/3 simpler IMHO.But why have it specific to the minimal elf thing? Why not discard any DSO with 0 symbols and try the next option to acquire symbols?
Hmm.. I don't think it's specific to the minimal elf parser. The return value of dso__load_sym() is a number of symbols found so when it sees a dso with 0 symbols it'll fall back to the next option IMHO (not tested). Did you see a problem with the current code?
Thanks,
Namhyung
Peter Zijlstra
maintainerQuoted 4 lines · Namhyung Kim
Hmm.. I don't think it's specific to the minimal elf parser. The return value of
dso__load_sym()is a number of symbols found so when it sees a dso with 0 symbols it'll fall back to the next option IMHO (not tested). Did you see a problem with the current code?
So your patch:
+++ b/tools/perf/util/symbol-minimal.c
@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,
unsigned char *build_id[BUILD_ID_SIZE];
int ret;+ if (dso->kernel)
+ return 0; /* always use kallsyms */
+
changes the symbol-minimal.c file to add this exception. That is very much specific to the minimal elf parser, or am I just seeing things?
What I was saying, why not have a util/symbol.c change that disregards all DSOs with 0 symbols in.
Namhyung Kim
maintainerHi Peter,
Quoted 17 lines · Peter Zijlstra
Quoted 4 lines · Namhyung Kim
Hmm.. I don't think it's specific to the minimal elf parser. The return value of
dso__load_sym()is a number of symbols found so when it sees a dso with 0 symbols it'll fall back to the next option IMHO (not tested). Did you see a problem with the current code?So your patch:
+++
b/tools/perf/util/symbol-minimal.ctools/perf/util/symbol-minimal.c +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,unsigned char *build_id[BUILD_ID_SIZE ];int ret; +if (dso->kernel) +return 0 ;/* always use kallsyms */ +
Quoted 2 lines
changes the
symbol-minimal.cfile to add this exception. That is very much specific to the minimal elf parser, or am I just seeing things?
What minimal parser does here is just skip kernel dsos (vmlinux) since it didn't deal with all the details of parsing vmlinux currently.
Quoted 3 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.
The util/symbol.c doesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.
Signature · 2 lines
Thanks, Namhyung
Peter Zijlstra
maintainerQuoted 7 lines · Namhyung Kim
Quoted 2 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.The
util/symbol.cdoesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.
Well, it could not could it.. it readily proceeded with 0 symbols in my case. It did _not_ fallback to kallsyms.
Arnaldo Carvalho de Melo
maintainerEm Tue, Nov 11, 2014 at 11:27:45AM +0100, Peter Zijlstra escreveu:
Quoted 11 lines · Namhyung Kim
Quoted 7 lines
Quoted 2 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.The
util/symbol.cdoesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.Well, it could not could it.. it readily proceeded with 0 symbols in my case. It did _not_ fallback to kallsyms.
Right, testing a fix for the problem I described on my last message.
- Arnaldo
Arnaldo Carvalho de Melo
maintainerEm Tue, Nov 11, 2014 at 10:03:26AM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 10 lines
Em Tue, Nov 11, 2014 at 11:27:45AM +0100, Peter Zijlstra escreveu:
Quoted 8 lines · Namhyung Kim
Quoted 7 lines
Quoted 2 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.The
util/symbol.cdoesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.
Quoted 4 lines
Quoted 2 lines
Well, it could not could it.. it readily proceeded with 0 symbols in my case. It did _not_ fallback to kallsyms.
Right, testing a fix for the problem I described on my last message.
Can you try the patch below?
- Arnaldo
tools/perf/util/symbol-minimal.c +1 -1
@@ -341,7 +341,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) {dso__set_build_id (dso, build_id); -return 1 ; +return 0 ; }return 0 ; }
Peter Zijlstra
maintainerQuoted 8 lines · Arnaldo Carvalho de Melo
Can you try the patch below?
tools/perf/util/symbol-minimal.c +0
-0
tools/perf/util/symbol-minimal.c int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, · line 347
Quoted 8 lines
tools/perf/util/symbol-minimal.c +1
-1@@ -341,7 +341,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) {dso__set_build_id (dso, build_id); -return 1 ; +return 0 ; }return 0 ; }
removing libelf-dev and recompiling to verify its broken again, then I made this change, recompiled and tried again and that seems to work.
Control flow seems redundant though, might as well remove the entire return stmt.
Still wondering why the generic code accepts DSOs without symbols though. But whatever ;-)
tip-bot for Arnaldo Carvalho de Melo
merge bot[tip:perf/core] perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader
In reply to Arnaldo Carvalho de Meloperf symbols: Fallback to kallsyms when using the minimal 'ELF' loader
Commit-ID: 162bcc17bb876772793ca070ebd6488cfdae09bf Gitweb: http://git.kernel.org/tip/162bcc17bb876772793ca070ebd6488cfdae09bf Author: Arnaldo Carvalho de Melo <[email protected]> AuthorDate: Tue, 11 Nov 2014 11:25:28 -0300 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 19 Nov 2014 12:33:46 -0300
perf symbols: Fallback to kallsyms when using the minimal 'ELF' loader
The minimal ELF loader should not return 1 when it manages to read the vmlinux build-id, it should instead return 0, meaning that it hasn't loaded any symbols, since it doesn't parses ELF at all.
That way, the main symbol.c routines will understand that it is necessary to continue looking for a file with symbols, and when no libelf is linked, that means it will eventually try kallsyms.
--- tools/perf/util/symbol-minimal.c | 1 - 1 file changed, 1 deletion(-)
tools/perf/util/symbol-minimal.c +0 -1
@@ -341,7 +341,6 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,if (filename__read_build_id (ss->name, build_id,BUILD_ID_SIZE ) >0 ) {dso__set_build_id (dso, build_id); -return 1 ; }return 0 ; }
Arnaldo Carvalho de Melo
maintainerEm Tue, Nov 11, 2014 at 01:24:38PM +0900, Namhyung Kim escreveu:
Quoted 28 lines
Hi Peter,
Quoted 17 lines · Peter Zijlstra
Quoted 4 lines · Namhyung Kim
Hmm.. I don't think it's specific to the minimal elf parser. The return value of
dso__load_sym()is a number of symbols found so when it sees a dso with 0 symbols it'll fall back to the next option IMHO (not tested). Did you see a problem with the current code?So your patch:
+++
b/tools/perf/util/symbol-minimal.c(quoted diff) +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, unsigned char *build_id[BUILD_ID_SIZE]; int ret; + if (dso->kernel) + return 0; /* always use kallsyms */ +Quoted 2 lines
changes the
symbol-minimal.cfile to add this exception. That is very much specific to the minimal elf parser, or am I just seeing things?What minimal parser does here is just skip kernel dsos (vmlinux) since it didn't deal with all the details of parsing vmlinux currently.
Quoted 1 line
Quoted 5 lines
Quoted 2 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.The
util/symbol.cdoesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it
symbol.c should not be able to handle anything, since the actual ELF loader is in symbol-elf.c or simbol-minimal.c, no?
I.e.:
symbol.c::dso__load() symbol.c::dso__load_kernel_sym() symbol.c::dso__load_vmlinux()
And then it heads into one of the ELF loaders, right now, without your patch, I see, when the minimal loader is used:
symbol-minimal.c::dso__load_sym()
reads the build-id and if it works, returns 1, which is a bug, it should return 0 in this case, possibly -1 if it doesn't read the build-id :-\
I.e. it should return 0, because that way it signals: "I can't read it, thus no symbols were loaded, symbol.c: please go on looking for them somewhere else, kallsyms perhaps?".
And this is the bug, probably. Now to look at your patches to see if this is touched somehow...
Quoted 2 lines
actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.
See above.
Quoted 3 lines
Signature · 2 lines
Thanks, Namhyung
Namhyung Kim
maintainerHi Arnaldo,
Sorry for late reply. I was offline last week.
Quoted 29 lines · Arnaldo Carvalho de Melo
Em Tue, Nov 11, 2014 at 01:24:38PM +0900, Namhyung Kim escreveu:
Quoted 28 lines
Hi Peter,
Quoted 17 lines · Peter Zijlstra
Quoted 4 lines · Namhyung Kim
Hmm.. I don't think it's specific to the minimal elf parser. The return value of
dso__load_sym()is a number of symbols found so when it sees a dso with 0 symbols it'll fall back to the next option IMHO (not tested). Did you see a problem with the current code?So your patch:
+++
b/tools/perf/util/symbol-minimal.c(quoted diff) +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused, unsigned char *build_id[BUILD_ID_SIZE]; int ret; + if (dso->kernel) + return 0; /* always use kallsyms */ +Quoted 2 lines
changes the
symbol-minimal.cfile to add this exception. That is very much specific to the minimal elf parser, or am I just seeing things?What minimal parser does here is just skip kernel dsos (vmlinux) since it didn't deal with all the details of parsing vmlinux currently.
Quoted 1 line
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
What I was saying, why not have a
util/symbol.cchange that disregards all DSOs with 0 symbols in.The
util/symbol.cdoesn't need this because it can handle vmlinux reliably. So after reading symbol table, it'll use the dso if it
symbol.cshould not be able to handle anything, since the actual ELF loader is insymbol-elf.corsimbol-minimal.c, no?
Ah right, I was confused with symbol.c and symbol-elf.c - so I believe the generic logic in symbol.c already handles DSOs with 0 symbol. The problem was symbol-minimal.c didn't return 0 for the DSOs.
Quoted 10 lines
I.e.:
symbol.c::dso__load() symbol.c::dso__load_kernel_sym() symbol.c::dso__load_vmlinux()And then it heads into one of the ELF loaders, right now, without your patch, I see, when the minimal loader is used:
Quoted 8 lines
symbol-minimal.c::dso__load_sym()reads the build-id and if it works, returns 1, which is a bug, it should return 0 in this case, possibly -1 if it doesn't read the build-id :-\
I.e. it should return 0, because that way it signals: "I can't read it, thus no symbols were loaded,
symbol.c: please go on looking for them somewhere else, kallsyms perhaps?".
Right. It's a bug for vmlinux. But by returning 0, it'll iterate over the candidate binaries in dso__load(). I'm afraid that this *might* overwrite the build-id of the DSO with different one. So I think it also needs to add a check for valid build-id.
I'll update this patch with above.
Thanks,
Namhyung
Quoted 12 lines
And this is the bug, probably. Now to look at your patches to see if this is touched somehow...
Quoted 2 lines
actually contains symbols or fallback to next dso if it has 0 symbols. IOW it already disregards all dsos with 0 symbols in.
See above.
Quoted 3 lines
Signature · 2 lines
Thanks, Namhyung
Quoted 2 lines · Namhyung Kim
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
Do you know the recent change (commit id) that broke it?
David
Namhyung Kim
maintainerHi David,
Quoted 5 lines · David Ahern
Quoted 2 lines · Namhyung Kim
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
Do you know the recent change (commit id) that broke it?
Nope. I tried to find it but failed - older versions seems also have the problem and some of them could not run perf record. Anyway it looks like depending some external condition and broken for a while. :(
Thanks,
Namhyung
Quoted 4 lines · Namhyung Kim
Hi David,
Quoted 1 line · David Ahern
On 11/6/14, 10:20 PM, Namhyung Kim wrote:
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
Do you know the recent change (commit id) that broke it?
Nope. I tried to find it but failed - older versions seems also have the problem and some of them could not run perf record. Anyway it looks like depending some external condition and broken for a while. :(
OK. I have a segfault issue when analyzing a mips file offbox and it is related to kernel symbol processing. I was not able to find past version of perf that worked - though limited by the file version checks added around v3.6.
David
Arnaldo Carvalho de Melo
maintainerEm Fri, Nov 07, 2014 at 02:20:04PM +0900, Namhyung Kim escreveu:
Quoted 8 lines
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
Ok, but since you added that minimal ELF symtab loading, isn't better to try that first, i.e. if we find a vmlinux file with a build-id and with symbols in it...
If that isn't the case, i.e. no vmlinux was found, then we fallback to kallsyms, to check if that is available.
I.e. with your new minimalistic ELF symtab loader if we have a suitable vmlinux but no kallsyms, we end up resolving no symbols even having that nice vmlinux :-)
Ah, I applied the feature test one (2/3, I think)
- Arnaldo
Quoted 45 lines
# Overhead Command Shared Object Symbol # ........ ....... ................. ........................ # 34.51% swapper [kernel.kallsyms] [k] intel_idle 12.54% perf [kernel.kallsyms] [k] generic_exec_single 10.11% swapper [kernel.kallsyms] [k] int_sqrt 9.83% swapper [kernel.kallsyms] [k] hrtimer_interrupt 7.25% emacs [kernel.kallsyms] [k] __switch_to 7.06% sleep [kernel.kallsyms] [k] find_next_iomem_res 7.02% swapper [kernel.kallsyms] [k] run_timer_softirq 2.55% swapper [kernel.kallsyms] [k] _raw_spin_unlock_irq 1.90% swapper [kernel.kallsyms] [k] lapic_next_deadline 1.75% swapper [kernel.kallsyms] [k] native_sched_clock 1.49% swapper [kernel.kallsyms] [k] __schedule 1.20% swapper [kernel.kallsyms] [k] read_tsc 1.10% sleep [kernel.kallsyms] [k] current_kernel_time 0.99% swapper [kernel.kallsyms] [k] pick_next_task_rt 0.36% swapper [kernel.kallsyms] [k] group_sched_in 0.24% swapper [kernel.kallsyms] [k] x86_pmu_commit_txn 0.06% swapper [kernel.kallsyms] [k] intel_pmu_enable_all 0.03% perf [kernel.kallsyms] [k] intel_pmu_enable_allReported-by Peter Zijlstra <[email protected]>Cc Adrian Hunter <[email protected]>Signed-off-by Namhyung Kim <[email protected]>--- tools/perf/util/symbol-minimal.c | 3 +++ 1 file changed, 3 insertions(+)tools/perf/util/symbol-minimal.c +3
-0@@ -335,6 +335,9 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,unsigned char *build_id[BUILD_ID_SIZE ];int ret; +if (dso->kernel) +return 0 ;/* always use kallsyms */ + ret =fd__is_64_bit (ss->fd);if (ret >=0 ) dso->is_64_bit = ret;Signature · 1 line
2.1.2
Namhyung Kim
maintainerQuoted 14 lines · Arnaldo Carvalho de Melo
Em Fri, Nov 07, 2014 at 02:20:04PM +0900, Namhyung Kim escreveu:
Quoted 8 lines
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
Ok, but since you added that minimal ELF symtab loading, isn't better to try that first, i.e. if we find a vmlinux file with a build-id and with symbols in it...
Quoted 6 lines
If that isn't the case, i.e. no vmlinux was found, then we fallback to kallsyms, to check if that is available.
I.e. with your new minimalistic ELF symtab loader if we have a suitable vmlinux but no kallsyms, we end up resolving no symbols even having that nice vmlinux :-)
Yeah, maybe. But it'd add a substantial complexity also and I tried to make it simple and small only to show usual userspace symbols.
I think that about a half of the complexity of the dso__load_sym() in symbol-elf.c came from the kernel (and module) support. And expecting kallsyms on the system is not a high barrier IMHO. So I decided to just fall back to kallsyms for kernel dsos. Mayby we can add the kernel support incrementally later.
Thanks,
Namhyung
Arnaldo Carvalho de Melo
maintainerEm Mon, Nov 10, 2014 at 03:53:06PM +0900, Namhyung Kim escreveu:
Quoted 22 lines · Arnaldo Carvalho de Melo
Quoted 14 lines
Em Fri, Nov 07, 2014 at 02:20:04PM +0900, Namhyung Kim escreveu:
Quoted 8 lines
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
Ok, but since you added that minimal ELF symtab loading, isn't better to try that first, i.e. if we find a vmlinux file with a build-id and with symbols in it...
Quoted 6 lines
If that isn't the case, i.e. no vmlinux was found, then we fallback to kallsyms, to check if that is available.
I.e. with your new minimalistic ELF symtab loader if we have a suitable vmlinux but no kallsyms, we end up resolving no symbols even having that nice vmlinux :-)
Quoted 5 lines
Yeah, maybe. But it'd add a substantial complexity also and I tried to make it simple and small only to show usual userspace symbols.
I think that about a half of the complexity of the
dso__load_sym()insymbol-elf.ccame from the kernel (and module) support. And expecting
Right, I agree that thing grew too complex, reducing that complexity is something we should do when we have the chance. I.e. perhaps we could separate kernel/modules handling out of it, even if just at source code level at first...
Quoted 3 lines
kallsyms on the system is not a high barrier IMHO. So I decided to just fall back to kallsyms for kernel dsos. Mayby we can add the kernel support incrementally later.
The suggestion came because you did that minimalistic reader, which if can be used for vmlinux files, would be great, as resolving vmlinux samples is such a major usecase :-)
- Arnaldo
Namhyung Kim
maintainerQuoted 26 lines · Arnaldo Carvalho de Melo
Em Mon, Nov 10, 2014 at 03:53:06PM +0900, Namhyung Kim escreveu:
Quoted 25 lines · Arnaldo Carvalho de Melo
Quoted 14 lines
Em Fri, Nov 07, 2014 at 02:20:04PM +0900, Namhyung Kim escreveu:
Quoted 8 lines
When libelf is not used, perf cannot not show symbol names since it doesn't access the ELF symbol table. But kernel is different as it can fallback to kallsyms.
It worked w/o libelf, but recent change to use vmlinux for kernel symbols break it.
With this change, it now can show kernel symbols again:
Ok, but since you added that minimal ELF symtab loading, isn't better to try that first, i.e. if we find a vmlinux file with a build-id and with symbols in it...
Quoted 6 lines
If that isn't the case, i.e. no vmlinux was found, then we fallback to kallsyms, to check if that is available.
I.e. with your new minimalistic ELF symtab loader if we have a suitable vmlinux but no kallsyms, we end up resolving no symbols even having that nice vmlinux :-)
Yeah, maybe. But it'd add a substantial complexity also and I tried to make it simple and small only to show usual userspace symbols.
Quoted 7 lines
Quoted 2 lines
I think that about a half of the complexity of the
dso__load_sym()insymbol-elf.ccame from the kernel (and module) support. And expectingRight, I agree that thing grew too complex, reducing that complexity is something we should do when we have the chance. I.e. perhaps we could separate kernel/modules handling out of it, even if just at source code level at first...
Hmm.. okay. I'll try.
Thanks,
Namhyung
Quoted 8 lines
Quoted 4 lines
kallsyms on the system is not a high barrier IMHO. So I decided to just fall back to kallsyms for kernel dsos. Mayby we can add the kernel support incrementally later.
The suggestion came because you did that minimalistic reader, which if can be used for vmlinux files, would be great, as resolving vmlinux samples is such a major usecase :-)