2009-09-25 00:02:18 +08:00
|
|
|
#ifndef __PERF_SYMBOL
|
|
|
|
#define __PERF_SYMBOL 1
|
2009-05-29 01:55:04 +08:00
|
|
|
|
|
|
|
#include <linux/types.h>
|
2009-10-21 00:25:40 +08:00
|
|
|
#include <stdbool.h>
|
2009-06-25 23:05:54 +08:00
|
|
|
#include "types.h"
|
2009-07-02 01:46:08 +08:00
|
|
|
#include <linux/list.h>
|
2009-07-01 23:28:37 +08:00
|
|
|
#include <linux/rbtree.h>
|
2009-08-12 17:07:25 +08:00
|
|
|
#include "event.h"
|
2009-05-29 01:55:04 +08:00
|
|
|
|
2009-08-12 03:22:11 +08:00
|
|
|
#ifdef HAVE_CPLUS_DEMANGLE
|
|
|
|
extern char *cplus_demangle(const char *, int);
|
|
|
|
|
|
|
|
static inline char *bfd_demangle(void __used *v, const char *c, int i)
|
|
|
|
{
|
|
|
|
return cplus_demangle(c, i);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#ifdef NO_DEMANGLE
|
|
|
|
static inline char *bfd_demangle(void __used *v, const char __used *c,
|
|
|
|
int __used i)
|
|
|
|
{
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#include <bfd.h>
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2009-10-25 00:10:36 +08:00
|
|
|
/*
|
|
|
|
* libelf 0.8.x and earlier do not support ELF_C_READ_MMAP;
|
|
|
|
* for newer versions we can use mmap to reduce memory usage:
|
|
|
|
*/
|
|
|
|
#ifdef LIBELF_NO_MMAP
|
|
|
|
# define PERF_ELF_C_READ_MMAP ELF_C_READ
|
|
|
|
#else
|
|
|
|
# define PERF_ELF_C_READ_MMAP ELF_C_READ_MMAP
|
|
|
|
#endif
|
|
|
|
|
2009-08-12 03:22:11 +08:00
|
|
|
#ifndef DMGL_PARAMS
|
|
|
|
#define DMGL_PARAMS (1 << 0) /* Include function args */
|
|
|
|
#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
|
|
|
|
#endif
|
|
|
|
|
2009-05-29 01:55:04 +08:00
|
|
|
struct symbol {
|
|
|
|
struct rb_node rb_node;
|
perf_counter tools: Define and use our own u64, s64 etc. definitions
On 64-bit powerpc, __u64 is defined to be unsigned long rather than
unsigned long long. This causes compiler warnings every time we
print a __u64 value with %Lx.
Rather than changing __u64, we define our own u64 to be unsigned long
long on all architectures, and similarly s64 as signed long long.
For consistency we also define u32, s32, u16, s16, u8 and s8. These
definitions are put in a new header, types.h, because these definitions
are needed in util/string.h and util/symbol.h.
The main change here is the mechanical change of __[us]{64,32,16,8}
to remove the "__". The other changes are:
* Create types.h
* Include types.h in perf.h, util/string.h and util/symbol.h
* Add types.h to the LIB_H definition in Makefile
* Added (u64) casts in process_overflow_event() and print_sym_table()
to kill two remaining warnings.
Signed-off-by: Paul Mackerras <paulus@samba.org>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: benh@kernel.crashing.org
LKML-Reference: <19003.33494.495844.956580@cargo.ozlabs.ibm.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-06-19 20:21:42 +08:00
|
|
|
u64 start;
|
|
|
|
u64 end;
|
2009-05-29 01:55:04 +08:00
|
|
|
char name[0];
|
|
|
|
};
|
|
|
|
|
2009-11-24 22:05:15 +08:00
|
|
|
struct symbol_conf {
|
|
|
|
unsigned short priv_size;
|
|
|
|
bool try_vmlinux_path,
|
perf symbols: Allow lookups by symbol name too
Configurable via symbol_conf.sort_by_name, so that the cost of an
extra rb_node on all 'struct symbol' instances is not paid by tools
that only want to decode addresses.
How to use it:
symbol_conf.sort_by_name = true;
symbol_init(&symbol_conf);
struct map *map = map_groups__find_by_name(kmaps, MAP__VARIABLE, "[kernel.kallsyms]");
if (map == NULL) {
pr_err("couldn't find map!\n");
kernel_maps__fprintf(stdout);
} else {
struct symbol *sym = map__find_symbol_by_name(map, sym_filter, NULL);
if (sym == NULL)
pr_err("couldn't find symbol %s!\n", sym_filter);
else
pr_info("symbol %s: %#Lx-%#Lx \n", sym_filter, sym->start, sym->end);
}
Looking over the vmlinux/kallsyms is common enough that I'll add a
variable to the upcoming struct perf_session to avoid the need to
use map_groups__find_by_name to get the main vmlinux/kallsyms map.
The above example looks on the 'variable' symtab, but it is just
like that for the functions one.
Also the sort operation is done when we first use
map__find_symbol_by_name, in a lazy way.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260564622-12392-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-12 04:50:22 +08:00
|
|
|
use_modules,
|
|
|
|
sort_by_name;
|
2009-11-24 22:05:15 +08:00
|
|
|
const char *vmlinux_name;
|
|
|
|
};
|
|
|
|
|
2009-12-16 06:04:39 +08:00
|
|
|
extern struct symbol_conf symbol_conf;
|
2009-10-31 02:28:24 +08:00
|
|
|
|
|
|
|
static inline void *symbol__priv(struct symbol *self)
|
|
|
|
{
|
2009-12-16 06:04:39 +08:00
|
|
|
return ((void *)self) - symbol_conf.priv_size;
|
2009-10-31 02:28:24 +08:00
|
|
|
}
|
|
|
|
|
perf tools: Consolidate symbol resolving across all tools
Now we have a very high level routine for simple tools to
process IP sample events:
int event__preprocess_sample(const event_t *self,
struct addr_location *al,
symbol_filter_t filter)
It receives the event itself and will insert new threads in the
global threads list and resolve the map and symbol, filling all
this info into the new addr_location struct, so that tools like
annotate and report can further process the event by creating
hist_entries in their specific way (with or without callgraphs,
etc).
It in turn uses the new next layer function:
void thread__find_addr_location(struct thread *self, u8 cpumode,
enum map_type type, u64 addr,
struct addr_location *al,
symbol_filter_t filter)
This one will, given a thread (userspace or the kernel kthread
one), will find the given type (MAP__FUNCTION now, MAP__VARIABLE
too in the near future) at the given cpumode, taking vdsos into
account (userspace hit, but kernel symbol) and will fill all
these details in the addr_location given.
Tools that need a more compact API for plain function
resolution, like 'kmem', can use this other one:
struct symbol *thread__find_function(struct thread *self, u64 addr,
symbol_filter_t filter)
So, to resolve a kernel symbol, that is all the 'kmem' tool
needs, its just a matter of calling:
sym = thread__find_function(kthread, addr, NULL);
The 'filter' parameter is needed because we do lazy
parsing/loading of ELF symtabs or /proc/kallsyms.
With this we remove more code duplication all around, which is
always good, huh? :-)
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: John Kacur <jkacur@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1259346563-12568-12-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-28 02:29:23 +08:00
|
|
|
struct addr_location {
|
|
|
|
struct thread *thread;
|
|
|
|
struct map *map;
|
|
|
|
struct symbol *sym;
|
|
|
|
u64 addr;
|
|
|
|
char level;
|
|
|
|
};
|
|
|
|
|
2009-05-29 01:55:04 +08:00
|
|
|
struct dso {
|
|
|
|
struct list_head node;
|
2009-11-28 02:29:17 +08:00
|
|
|
struct rb_root symbols[MAP__NR_TYPES];
|
perf symbols: Allow lookups by symbol name too
Configurable via symbol_conf.sort_by_name, so that the cost of an
extra rb_node on all 'struct symbol' instances is not paid by tools
that only want to decode addresses.
How to use it:
symbol_conf.sort_by_name = true;
symbol_init(&symbol_conf);
struct map *map = map_groups__find_by_name(kmaps, MAP__VARIABLE, "[kernel.kallsyms]");
if (map == NULL) {
pr_err("couldn't find map!\n");
kernel_maps__fprintf(stdout);
} else {
struct symbol *sym = map__find_symbol_by_name(map, sym_filter, NULL);
if (sym == NULL)
pr_err("couldn't find symbol %s!\n", sym_filter);
else
pr_info("symbol %s: %#Lx-%#Lx \n", sym_filter, sym->start, sym->end);
}
Looking over the vmlinux/kallsyms is common enough that I'll add a
variable to the upcoming struct perf_session to avoid the need to
use map_groups__find_by_name to get the main vmlinux/kallsyms map.
The above example looks on the 'variable' symtab, but it is just
like that for the functions one.
Also the sort operation is done when we first use
map__find_symbol_by_name, in a lazy way.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260564622-12392-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-12 04:50:22 +08:00
|
|
|
struct rb_root symbol_names[MAP__NR_TYPES];
|
perf symbols: Use the buildids if present
With this change 'perf record' will intercept PERF_RECORD_MMAP
calls, creating a linked list of DSOs, then when the session
finishes, it will traverse this list and read the buildids,
stashing them at the end of the file and will set up a new
feature bit in the header bitmask.
'perf report' will then notice this feature and populate the
'dsos' list and set the build ids.
When reading the symtabs it will refuse to load from a file that
doesn't have the same build id. This improves the
reliability of the profiler output, as symbols and profiling
data is more guaranteed to match.
Example:
[root@doppio ~]# perf report | head
/home/acme/bin/perf with build id b1ea544ac3746e7538972548a09aadecc5753868 not found, continuing without symbols
# Samples: 2621434559
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ......
#
7.91% init [kernel] [k] read_hpet
7.64% init [kernel] [k] mwait_idle_with_hints
7.60% swapper [kernel] [k] read_hpet
7.60% swapper [kernel] [k] mwait_idle_with_hints
3.65% init [kernel] [k] 0xffffffffa02339d9
[root@doppio ~]#
In this case the 'perf' binary was an older one, vanished,
so its symbols probably wouldn't match or would cause subtly
different (and misleading) output.
Next patches will support the kernel as well, reading the build
id notes for it and the modules from /sys.
Another patch should also introduce a new plumbing command:
'perf list-buildids'
that will then be used in porcelain that is distro specific to
fetch -debuginfo packages where such buildids are present. This
will in turn allow for one to run 'perf record' in one machine
and 'perf report' in another.
Future work on having the buildid sent directly from the kernel
in the PERF_RECORD_MMAP event is needed to close races, as the
DSO can be changed during a 'perf record' session, but this
patch at least helps with non-corner cases and current/older
kernels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K. Prasad <prasad@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1257367843-26224-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-05 04:50:43 +08:00
|
|
|
u8 adjust_symbols:1;
|
|
|
|
u8 slen_calculated:1;
|
|
|
|
u8 has_build_id:1;
|
2009-11-21 06:51:27 +08:00
|
|
|
u8 kernel:1;
|
2009-08-07 01:43:17 +08:00
|
|
|
unsigned char origin;
|
perf symbols: Allow lookups by symbol name too
Configurable via symbol_conf.sort_by_name, so that the cost of an
extra rb_node on all 'struct symbol' instances is not paid by tools
that only want to decode addresses.
How to use it:
symbol_conf.sort_by_name = true;
symbol_init(&symbol_conf);
struct map *map = map_groups__find_by_name(kmaps, MAP__VARIABLE, "[kernel.kallsyms]");
if (map == NULL) {
pr_err("couldn't find map!\n");
kernel_maps__fprintf(stdout);
} else {
struct symbol *sym = map__find_symbol_by_name(map, sym_filter, NULL);
if (sym == NULL)
pr_err("couldn't find symbol %s!\n", sym_filter);
else
pr_info("symbol %s: %#Lx-%#Lx \n", sym_filter, sym->start, sym->end);
}
Looking over the vmlinux/kallsyms is common enough that I'll add a
variable to the upcoming struct perf_session to avoid the need to
use map_groups__find_by_name to get the main vmlinux/kallsyms map.
The above example looks on the 'variable' symtab, but it is just
like that for the functions one.
Also the sort operation is done when we first use
map__find_symbol_by_name, in a lazy way.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260564622-12392-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-12 04:50:22 +08:00
|
|
|
u8 sorted_by_name;
|
2009-11-28 02:29:16 +08:00
|
|
|
u8 loaded;
|
perf symbols: Use the buildids if present
With this change 'perf record' will intercept PERF_RECORD_MMAP
calls, creating a linked list of DSOs, then when the session
finishes, it will traverse this list and read the buildids,
stashing them at the end of the file and will set up a new
feature bit in the header bitmask.
'perf report' will then notice this feature and populate the
'dsos' list and set the build ids.
When reading the symtabs it will refuse to load from a file that
doesn't have the same build id. This improves the
reliability of the profiler output, as symbols and profiling
data is more guaranteed to match.
Example:
[root@doppio ~]# perf report | head
/home/acme/bin/perf with build id b1ea544ac3746e7538972548a09aadecc5753868 not found, continuing without symbols
# Samples: 2621434559
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ......
#
7.91% init [kernel] [k] read_hpet
7.64% init [kernel] [k] mwait_idle_with_hints
7.60% swapper [kernel] [k] read_hpet
7.60% swapper [kernel] [k] mwait_idle_with_hints
3.65% init [kernel] [k] 0xffffffffa02339d9
[root@doppio ~]#
In this case the 'perf' binary was an older one, vanished,
so its symbols probably wouldn't match or would cause subtly
different (and misleading) output.
Next patches will support the kernel as well, reading the build
id notes for it and the modules from /sys.
Another patch should also introduce a new plumbing command:
'perf list-buildids'
that will then be used in porcelain that is distro specific to
fetch -debuginfo packages where such buildids are present. This
will in turn allow for one to run 'perf record' in one machine
and 'perf report' in another.
Future work on having the buildid sent directly from the kernel
in the PERF_RECORD_MMAP event is needed to close races, as the
DSO can be changed during a 'perf record' session, but this
patch at least helps with non-corner cases and current/older
kernels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K. Prasad <prasad@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1257367843-26224-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-05 04:50:43 +08:00
|
|
|
u8 build_id[BUILD_ID_SIZE];
|
2009-11-18 01:40:53 +08:00
|
|
|
u16 long_name_len;
|
2009-10-02 14:29:58 +08:00
|
|
|
const char *short_name;
|
|
|
|
char *long_name;
|
2009-05-29 01:55:04 +08:00
|
|
|
char name[0];
|
|
|
|
};
|
|
|
|
|
2009-10-31 02:28:24 +08:00
|
|
|
struct dso *dso__new(const char *name);
|
2009-05-29 01:55:04 +08:00
|
|
|
void dso__delete(struct dso *self);
|
|
|
|
|
2009-11-28 02:29:16 +08:00
|
|
|
bool dso__loaded(const struct dso *self, enum map_type type);
|
perf symbols: Allow lookups by symbol name too
Configurable via symbol_conf.sort_by_name, so that the cost of an
extra rb_node on all 'struct symbol' instances is not paid by tools
that only want to decode addresses.
How to use it:
symbol_conf.sort_by_name = true;
symbol_init(&symbol_conf);
struct map *map = map_groups__find_by_name(kmaps, MAP__VARIABLE, "[kernel.kallsyms]");
if (map == NULL) {
pr_err("couldn't find map!\n");
kernel_maps__fprintf(stdout);
} else {
struct symbol *sym = map__find_symbol_by_name(map, sym_filter, NULL);
if (sym == NULL)
pr_err("couldn't find symbol %s!\n", sym_filter);
else
pr_info("symbol %s: %#Lx-%#Lx \n", sym_filter, sym->start, sym->end);
}
Looking over the vmlinux/kallsyms is common enough that I'll add a
variable to the upcoming struct perf_session to avoid the need to
use map_groups__find_by_name to get the main vmlinux/kallsyms map.
The above example looks on the 'variable' symtab, but it is just
like that for the functions one.
Also the sort operation is done when we first use
map__find_symbol_by_name, in a lazy way.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260564622-12392-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-12 04:50:22 +08:00
|
|
|
bool dso__sorted_by_name(const struct dso *self, enum map_type type);
|
|
|
|
|
|
|
|
void dso__sort_by_name(struct dso *self, enum map_type type);
|
2009-11-28 02:29:16 +08:00
|
|
|
|
perf session: Move kmaps to perf_session
There is still some more work to do to disentangle map creation
from DSO loading, but this happens only for the kernel, and for
the early adopters of perf diff, where this disentanglement
matters most, we'll be testing different kernels, so no problem
here.
Further clarification: right now we create the kernel maps for
the various modules and discontiguous kernel text maps when
loading the DSO, we should do it as a two step process, first
creating the maps, for multiple mappings with the same DSO
store, then doing the dso load just once, for the first hit on
one of the maps sharing this DSO backing store.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260741029-4430-6-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-14 05:50:29 +08:00
|
|
|
struct perf_session;
|
|
|
|
|
2009-10-31 02:28:24 +08:00
|
|
|
struct dso *dsos__findnew(const char *name);
|
perf session: Move kmaps to perf_session
There is still some more work to do to disentangle map creation
from DSO loading, but this happens only for the kernel, and for
the early adopters of perf diff, where this disentanglement
matters most, we'll be testing different kernels, so no problem
here.
Further clarification: right now we create the kernel maps for
the various modules and discontiguous kernel text maps when
loading the DSO, we should do it as a two step process, first
creating the maps, for multiple mappings with the same DSO
store, then doing the dso load just once, for the first hit on
one of the maps sharing this DSO backing store.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260741029-4430-6-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-14 05:50:29 +08:00
|
|
|
int dso__load(struct dso *self, struct map *map, struct perf_session *session,
|
|
|
|
symbol_filter_t filter);
|
2009-08-12 16:03:49 +08:00
|
|
|
void dsos__fprintf(FILE *fp);
|
2009-11-17 02:32:44 +08:00
|
|
|
size_t dsos__fprintf_buildid(FILE *fp);
|
2009-05-29 01:55:04 +08:00
|
|
|
|
2009-11-17 02:32:44 +08:00
|
|
|
size_t dso__fprintf_buildid(struct dso *self, FILE *fp);
|
2009-11-28 02:29:20 +08:00
|
|
|
size_t dso__fprintf(struct dso *self, enum map_type type, FILE *fp);
|
2009-08-07 01:43:17 +08:00
|
|
|
char dso__symtab_origin(const struct dso *self);
|
perf symbols: Use the buildids if present
With this change 'perf record' will intercept PERF_RECORD_MMAP
calls, creating a linked list of DSOs, then when the session
finishes, it will traverse this list and read the buildids,
stashing them at the end of the file and will set up a new
feature bit in the header bitmask.
'perf report' will then notice this feature and populate the
'dsos' list and set the build ids.
When reading the symtabs it will refuse to load from a file that
doesn't have the same build id. This improves the
reliability of the profiler output, as symbols and profiling
data is more guaranteed to match.
Example:
[root@doppio ~]# perf report | head
/home/acme/bin/perf with build id b1ea544ac3746e7538972548a09aadecc5753868 not found, continuing without symbols
# Samples: 2621434559
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ......
#
7.91% init [kernel] [k] read_hpet
7.64% init [kernel] [k] mwait_idle_with_hints
7.60% swapper [kernel] [k] read_hpet
7.60% swapper [kernel] [k] mwait_idle_with_hints
3.65% init [kernel] [k] 0xffffffffa02339d9
[root@doppio ~]#
In this case the 'perf' binary was an older one, vanished,
so its symbols probably wouldn't match or would cause subtly
different (and misleading) output.
Next patches will support the kernel as well, reading the build
id notes for it and the modules from /sys.
Another patch should also introduce a new plumbing command:
'perf list-buildids'
that will then be used in porcelain that is distro specific to
fetch -debuginfo packages where such buildids are present. This
will in turn allow for one to run 'perf record' in one machine
and 'perf report' in another.
Future work on having the buildid sent directly from the kernel
in the PERF_RECORD_MMAP event is needed to close races, as the
DSO can be changed during a 'perf record' session, but this
patch at least helps with non-corner cases and current/older
kernels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K. Prasad <prasad@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1257367843-26224-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-05 04:50:43 +08:00
|
|
|
void dso__set_build_id(struct dso *self, void *build_id);
|
2009-12-12 04:56:39 +08:00
|
|
|
struct symbol *dso__find_symbol(struct dso *self, enum map_type type, u64 addr);
|
perf symbols: Allow lookups by symbol name too
Configurable via symbol_conf.sort_by_name, so that the cost of an
extra rb_node on all 'struct symbol' instances is not paid by tools
that only want to decode addresses.
How to use it:
symbol_conf.sort_by_name = true;
symbol_init(&symbol_conf);
struct map *map = map_groups__find_by_name(kmaps, MAP__VARIABLE, "[kernel.kallsyms]");
if (map == NULL) {
pr_err("couldn't find map!\n");
kernel_maps__fprintf(stdout);
} else {
struct symbol *sym = map__find_symbol_by_name(map, sym_filter, NULL);
if (sym == NULL)
pr_err("couldn't find symbol %s!\n", sym_filter);
else
pr_info("symbol %s: %#Lx-%#Lx \n", sym_filter, sym->start, sym->end);
}
Looking over the vmlinux/kallsyms is common enough that I'll add a
variable to the upcoming struct perf_session to avoid the need to
use map_groups__find_by_name to get the main vmlinux/kallsyms map.
The above example looks on the 'variable' symtab, but it is just
like that for the functions one.
Also the sort operation is done when we first use
map__find_symbol_by_name, in a lazy way.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260564622-12392-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-12-12 04:50:22 +08:00
|
|
|
struct symbol *dso__find_symbol_by_name(struct dso *self, enum map_type type,
|
|
|
|
const char *name);
|
2009-05-29 01:55:04 +08:00
|
|
|
|
2009-11-04 07:46:10 +08:00
|
|
|
int filename__read_build_id(const char *filename, void *bf, size_t size);
|
2009-11-19 06:20:52 +08:00
|
|
|
int sysfs__read_build_id(const char *filename, void *bf, size_t size);
|
2009-11-19 06:20:51 +08:00
|
|
|
bool dsos__read_build_ids(void);
|
perf symbols: Use the buildids if present
With this change 'perf record' will intercept PERF_RECORD_MMAP
calls, creating a linked list of DSOs, then when the session
finishes, it will traverse this list and read the buildids,
stashing them at the end of the file and will set up a new
feature bit in the header bitmask.
'perf report' will then notice this feature and populate the
'dsos' list and set the build ids.
When reading the symtabs it will refuse to load from a file that
doesn't have the same build id. This improves the
reliability of the profiler output, as symbols and profiling
data is more guaranteed to match.
Example:
[root@doppio ~]# perf report | head
/home/acme/bin/perf with build id b1ea544ac3746e7538972548a09aadecc5753868 not found, continuing without symbols
# Samples: 2621434559
#
# Overhead Command Shared Object Symbol
# ........ ............... ............................. ......
#
7.91% init [kernel] [k] read_hpet
7.64% init [kernel] [k] mwait_idle_with_hints
7.60% swapper [kernel] [k] read_hpet
7.60% swapper [kernel] [k] mwait_idle_with_hints
3.65% init [kernel] [k] 0xffffffffa02339d9
[root@doppio ~]#
In this case the 'perf' binary was an older one, vanished,
so its symbols probably wouldn't match or would cause subtly
different (and misleading) output.
Next patches will support the kernel as well, reading the build
id notes for it and the modules from /sys.
Another patch should also introduce a new plumbing command:
'perf list-buildids'
that will then be used in porcelain that is distro specific to
fetch -debuginfo packages where such buildids are present. This
will in turn allow for one to run 'perf record' in one machine
and 'perf report' in another.
Future work on having the buildid sent directly from the kernel
in the PERF_RECORD_MMAP event is needed to close races, as the
DSO can be changed during a 'perf record' session, but this
patch at least helps with non-corner cases and current/older
kernels.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Christoph Hellwig <hch@infradead.org>
Cc: Frank Ch. Eigler <fche@redhat.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jason Baron <jbaron@redhat.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: K. Prasad <prasad@linux.vnet.ibm.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Roland McGrath <roland@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1257367843-26224-1-git-send-email-acme@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
2009-11-05 04:50:43 +08:00
|
|
|
int build_id__sprintf(u8 *self, int len, char *bf);
|
2009-11-04 07:46:10 +08:00
|
|
|
|
2009-12-16 06:04:39 +08:00
|
|
|
int symbol__init(void);
|
|
|
|
int perf_session__create_kernel_maps(struct perf_session *self);
|
2009-08-12 16:03:49 +08:00
|
|
|
|
2009-11-28 02:29:14 +08:00
|
|
|
extern struct list_head dsos__user, dsos__kernel;
|
2009-08-12 16:03:49 +08:00
|
|
|
extern struct dso *vdso;
|
2009-09-25 00:02:18 +08:00
|
|
|
#endif /* __PERF_SYMBOL */
|