diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-26 23:09:33 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-26 23:09:33 +0100 |
commit | 6fa41366c1c5e8b9640baba22d2b90ec9035a889 (patch) | |
tree | ad3b2214e0c5d4774f200ab7bb08b832babb9468 /tools/perf/util | |
parent | Merge branch 'irq-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kern... (diff) | |
parent | powerpc/perf_events: Fix call-graph recording, add perf_arch_fetch_caller_regs (diff) | |
download | linux-6fa41366c1c5e8b9640baba22d2b90ec9035a889.tar.xz linux-6fa41366c1c5e8b9640baba22d2b90ec9035a889.zip |
Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
powerpc/perf_events: Fix call-graph recording, add perf_arch_fetch_caller_regs
perf top: Add missing initialization to zero
perf probe: Use original address instead of CU-based address
perf probe: Fix offset to allow signed value
perf top: Improve the autosizing of column lenghts
perf probe: Fix need_dwarf flag if lazy matching is used
perf probe: Fix probe_point buffer overrun
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/probe-event.c | 2 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 18 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.h | 1 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 18 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 3 |
5 files changed, 23 insertions, 19 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 53181dbfe4a8..7c004b6ef24f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -242,7 +242,7 @@ void parse_perf_probe_event(const char *str, struct probe_point *pp, /* Parse probe point */ parse_perf_probe_probepoint(argv[0], pp); - if (pp->file || pp->line) + if (pp->file || pp->line || pp->lazy_line) *need_dwarf = true; /* Copy arguments and ensure return probe has no C argument */ diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 1e6c65ebbd80..c171a243d05b 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -333,8 +333,8 @@ static void show_location(Dwarf_Op *op, struct probe_finder *pf) die("%u exceeds max register number.", regn); if (deref) - ret = snprintf(pf->buf, pf->len, " %s=+%ju(%s)", - pf->var, (uintmax_t)offs, regs); + ret = snprintf(pf->buf, pf->len, " %s=%+jd(%s)", + pf->var, (intmax_t)offs, regs); else ret = snprintf(pf->buf, pf->len, " %s=%s", pf->var, regs); DIE_IF(ret < 0); @@ -352,8 +352,7 @@ static void show_variable(Dwarf_Die *vr_die, struct probe_finder *pf) if (dwarf_attr(vr_die, DW_AT_location, &attr) == NULL) goto error; /* TODO: handle more than 1 exprs */ - ret = dwarf_getlocation_addr(&attr, (pf->addr - pf->cu_base), - &expr, &nexpr, 1); + ret = dwarf_getlocation_addr(&attr, pf->addr, &expr, &nexpr, 1); if (ret <= 0 || nexpr == 0) goto error; @@ -437,8 +436,7 @@ static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) /* Get the frame base attribute/ops */ dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); - ret = dwarf_getlocation_addr(&fb_attr, (pf->addr - pf->cu_base), - &pf->fb_ops, &nops, 1); + ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); if (ret <= 0 || nops == 0) pf->fb_ops = NULL; @@ -455,6 +453,9 @@ static void show_probe_point(Dwarf_Die *sp_die, struct probe_finder *pf) /* *pf->fb_ops will be cached in libdw. Don't free it. */ pf->fb_ops = NULL; + if (pp->found == MAX_PROBES) + die("Too many( > %d) probe point found.\n", MAX_PROBES); + pp->probes[pp->found] = strdup(tmp); pp->found++; } @@ -641,7 +642,6 @@ static void find_probe_point_by_func(struct probe_finder *pf) int find_probe_point(int fd, struct probe_point *pp) { struct probe_finder pf = {.pp = pp}; - int ret; Dwarf_Off off, noff; size_t cuhl; Dwarf_Die *diep; @@ -668,10 +668,6 @@ int find_probe_point(int fd, struct probe_point *pp) pf.fname = NULL; if (!pp->file || pf.fname) { - /* Save CU base address (for frame_base) */ - ret = dwarf_lowpc(&pf.cu_die, &pf.cu_base); - if (ret != 0) - pf.cu_base = 0; if (pp->function) find_probe_point_by_func(&pf); else if (pp->lazy_line) diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h index d1a651793ba6..21f7354397b4 100644 --- a/tools/perf/util/probe-finder.h +++ b/tools/perf/util/probe-finder.h @@ -71,7 +71,6 @@ struct probe_finder { /* For variable searching */ Dwarf_Op *fb_ops; /* Frame base attribute */ - Dwarf_Addr cu_base; /* Current CU base address */ const char *var; /* Current variable name */ char *buf; /* Current output buffer */ int len; /* Length of output buffer */ diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 323c0aea0a91..c458c4a371d1 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -163,9 +163,17 @@ void dso__set_long_name(struct dso *self, char *name) self->long_name_len = strlen(name); } +static void dso__set_short_name(struct dso *self, const char *name) +{ + if (name == NULL) + return; + self->short_name = name; + self->short_name_len = strlen(name); +} + static void dso__set_basename(struct dso *self) { - self->short_name = basename(self->long_name); + dso__set_short_name(self, basename(self->long_name)); } struct dso *dso__new(const char *name) @@ -176,7 +184,7 @@ struct dso *dso__new(const char *name) int i; strcpy(self->name, name); dso__set_long_name(self, self->name); - self->short_name = self->name; + dso__set_short_name(self, self->name); for (i = 0; i < MAP__NR_TYPES; ++i) self->symbols[i] = self->symbol_names[i] = RB_ROOT; self->slen_calculated = 0; @@ -897,7 +905,6 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, struct kmap *kmap = self->kernel ? map__kmap(map) : NULL; struct map *curr_map = map; struct dso *curr_dso = self; - size_t dso_name_len = strlen(self->short_name); Elf_Data *symstrs, *secstrs; uint32_t nr_syms; int err = -1; @@ -987,7 +994,8 @@ static int dso__load_sym(struct dso *self, struct map *map, const char *name, char dso_name[PATH_MAX]; if (strcmp(section_name, - curr_dso->short_name + dso_name_len) == 0) + (curr_dso->short_name + + self->short_name_len)) == 0) goto new_symbol; if (strcmp(section_name, ".text") == 0) { @@ -1782,7 +1790,7 @@ struct dso *dso__new_kernel(const char *name) struct dso *self = dso__new(name ?: "[kernel.kallsyms]"); if (self != NULL) { - self->short_name = "[kernel]"; + dso__set_short_name(self, "[kernel]"); self->kernel = 1; } diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 280dadd32a08..f30a37428919 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -110,9 +110,10 @@ struct dso { u8 sorted_by_name; u8 loaded; u8 build_id[BUILD_ID_SIZE]; - u16 long_name_len; const char *short_name; char *long_name; + u16 long_name_len; + u16 short_name_len; char name[0]; }; |