perf script: add BTS analysis features
Subsystems (2)
v4 cover perf script: add BTS analysis features
Hi Frederic, David,
This patch series adds the functions to analyze BTS logs to perf-script and, makes perf-script more informative version 4.
The patches add the following functions.
- Unify the expression to "[unknown]"
- Fix BTS record header to resolve DSOs and symbols of user-space
- Resolve DSOs and symbols for BTS's branch_from addresses
- Show the offset of symbols with the 'offs' field specifier.
- Resolve the real path of [kernel.kallsym] using '--show-kernel-path' option.
Usage:
First, get the BTS log with the following command.
# perf record -e branches:u -c 1 -d <command>
Second, analyze that trace data.
# perf script -f ip,addr,sym,offs,dso [--show-kernel-path] This command's output format is: <branch_to addr> <branch_to function+offset> <branch_to DSO> <branch_from addr> <branch_from function+offset> <branch_from DSO>
Output sample:
# perf record -e branches:u -c 1 -d ls [snip] # perf script -f ip,addr,sym,dso,offs --show-kernel-path [snip] 402c1c main+0x0 (/root/bin/ls) 3430c21399 __libc_start_main+0xe9 (/lib64/libc-2.14.so) 40b390 set_program_name+0x0 (/root/bin/ls) 402c41 main+0x25 (/root/bin/ls) 40b390 set_program_name+0x0 (/root/bin/ls) ffffffff814ac5ed irq_return+0x0 (/lib/modules/3.2.0+/build/vmlinux) 401e20 strrchr@plt+0x0 (/root/bin/ls) 40b39e set_program_name+0xe (/root/bin/ls) 401e26 strrchr@plt+0x6 (/root/bin/ls) 401e20 strrchr@plt+0x0 (/root/bin/ls) 401b80 _init+0x18 (/root/bin/ls) 401e2b strrchr@plt+0xb (/root/bin/ls) 3430813850 _dl_runtime_resolve+0x0 (/lib64/ld-2.14.so) 401b86 _init+0x1e (/root/bin/ls) [snip]
It shows the tracee application's execution path.
TODO:
- add source code path field, line number field ...etc.
- add record/report script to use easily and, show human-friendly output.
- filtering kernel functions using scripts
Changes in v4:
- add check routine to set correct perf_sample's header.
Changes in v3:
- remove the bug fix patch already fixed.
- unify the "[unknown]" expressions in perf-script.
- fix perf_event_header of BTS events.
- fix patch's descriptions
Changes in v2:
- add a bug fix patch that prints correct IP address
- output the magic word "(unknown)" as symbol name when perf-script can't resolve symbols.
- output "[unknown]" as DSO name when perf-script can't resolve DSO path.
- change the way to output offset of symbols from '--show-symbol-offset' to 'offs' field.
- clean up codes.
Thanks,
---
Akihiro Nagai (5):
perf script: add option resolving vmlinux path perf script: add the offset field specifier
perf script: enhance IP and ADDR correlate detection for BTS
perf: set correct value to perf_event_header.misc for BTS
perf-script: unify the expressions indicate "unknown"
arch/x86/kernel/cpu/perf_event_intel_ds.c | 31 +++++++++++++------- tools/perf/Documentation/perf-script.txt | 5 +++ tools/perf/builtin-script.c | 45 +++++++++++++++++++---------- tools/perf/util/map.c | 15 ++++++++++ tools/perf/util/map.h | 1 + tools/perf/util/session.c | 38 ++++++++---------------- tools/perf/util/session.h | 2 + tools/perf/util/symbol.c | 20 +++++++++++++ tools/perf/util/symbol.h | 4 +++ 9 files changed, 108 insertions(+), 53 deletions(-)
Signature · 1 line
Akihiro Nagai ([email protected])
PATCH v4 1/5 perf-script: unify the expressions indicate "unknown"
perf-script uses various expressions to indicate "unknown". It is unfriendly for user scripts to parse it. So, this patch unifies the expressions to "[unknown]".
Changes in v3:
- unify all expressions to [unknown]
Changes in v2:
- add this patch
---
tools/perf/builtin-script.c | 20 ++++++-------------- tools/perf/util/map.c | 12 ++++++++++++ tools/perf/util/map.h | 1 + tools/perf/util/session.c | 35 ++++++++++------------------------- tools/perf/util/symbol.c | 12 ++++++++++++ tools/perf/util/symbol.h | 1 + 6 files changed, 42 insertions(+), 39 deletions(-)
tools/perf/builtin-script.c +6 -14
@@ -300,7 +300,7 @@ static void print_sample_start(struct perf_sample *sample, }else evname =__event_name (attr->type, attr->config); -printf ("%s: " , evname ? evname :"(unknown)" ); +printf ("%s: " , evname ? evname :"[unknown]" ); } }
@@ -323,7 +323,6 @@ static void print_sample_addr(union perf_event *event, {struct addr_location al;u8 cpumode = event->header.misc &PERF_RECORD_MISC_CPUMODE_MASK ; -const char *symname, *dsoname;printf ("%16" PRIx64, sample->addr);
@@ -343,21 +342,14 @@ static void print_sample_addr(union perf_event *event, al.sym =map__find_symbol (al.map, al.addr,NULL );if (PRINT_FIELD (SYM )) { -if (al.sym && al.sym->name) - symname = al.sym->name; -else - symname ="" ; - -printf (" %16s" , symname); +printf (" " ); +symbol__print_symname (al.sym); }if (PRINT_FIELD (DSO )) { -if (al.map && al.map->dso && al.map->dso->name) - dsoname = al.map->dso->name; -else - dsoname ="" ; - -printf (" (%s)" , dsoname); +printf (" (" ); +map__print_dsoname (al.map); +printf (")" ); } }
tools/perf/util/map.c +12 -0
@@ -212,6 +212,18 @@ size_t map__fprintf(struct map *self, FILE *fp) self->start, self->end, self->pgoff, self->dso->name); } +void map__print_dsoname (struct map *self) +{ +const char *dsoname; + +if (self && self->dso && self->dso->name) + dsoname = self->dso->name; +else + dsoname ="[unknown]" ; + +printf ("%s" , dsoname); +} +/* * objdump wants/reports absolute IPs for ET_EXEC, and RIPs for ET_DYN. * map->dso->adjust_symbols==1 for ET_EXEC-like cases.
tools/perf/util/map.h +1 -0
@@ -118,6 +118,7 @@ void map__delete(struct map *self);struct map *map__clone (struct map *self);int map__overlap (struct map *l,struct map *r);size_t map__fprintf (struct map *self,FILE *fp); +void map__print_dsoname (struct map *self);int map__load (struct map *self,symbol_filter_t filter); struct symbol *map__find_symbol(struct map *self,
tools/perf/util/session.c +10 -25
@@ -1296,7 +1296,6 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, int print_sym, int print_dso) {struct addr_location al; -const char *symname, *dsoname;struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;struct callchain_cursor_node *node;
@@ -1324,20 +1323,13 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,printf ("\t%16" PRIx64, node->ip);if (print_sym) { -if (node->sym && node->sym->name) - symname = node->sym->name; -else - symname ="" ; - -printf (" %s" , symname); +printf (" " ); +symbol__print_symname (node->sym); }if (print_dso) { -if (node->map && node->map->dso && node->map->dso->name) - dsoname = node->map->dso->name; -else - dsoname ="" ; - -printf (" (%s)" , dsoname); +printf (" (" ); +map__print_dsoname (al.map); +printf (")" ); }printf ("\n" );
@@ -1347,21 +1339,14 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, }else {printf ("%16" PRIx64, sample->ip);if (print_sym) { -if (al.sym && al.sym->name) - symname = al.sym->name; -else - symname ="" ; - -printf (" %s" , symname); +printf (" " ); +symbol__print_symname (al.sym); }if (print_dso) { -if (al.map && al.map->dso && al.map->dso->name) - dsoname = al.map->dso->name; -else - dsoname ="" ; - -printf (" (%s)" , dsoname); +printf (" (" ); +map__print_dsoname (al.map); +printf (")" ); } } }
tools/perf/util/symbol.c +12 -0
@@ -264,6 +264,18 @@ static size_t symbol__fprintf(struct symbol *sym, FILE *fp) sym->name); } +void symbol__print_symname (const struct symbol *sym) +{ +const char *symname; + +if (sym && sym->name) + symname = sym->name; +else + symname ="[unknown]" ; + +printf ("%s" , symname); +} +void dso__set_long_name (struct dso *dso,char *name) {if (name ==NULL )
tools/perf/util/symbol.h +1 -0
@@ -241,6 +241,7 @@ void machines__destroy_guest_kernel_maps(struct rb_root *machines);int symbol__init (void );void symbol__exit (void ); +void symbol__print_symname (const struct symbol *sym);bool symbol_type__is_a (char symbol_type,enum map_type map_type);size_t machine__fprintf_vmlinux_path (struct machine *machine,FILE *fp);
Re: [PATCH -tip v4 1/5] perf-script: unify the expressions indicate "unknown"
Quoted 10 lines · Akihiro Nagai
perf-script uses various expressions to indicate "unknown". It is unfriendly for user scripts to parse it. So, this patch unifies the expressions to "[unknown]".
Changes in v3:
- unify all expressions to [unknown]Changes in v2:
- add this patch
Re: [PATCH -tip v4 1/5] perf-script: unify the expressions indicate "unknown"
In reply to Akihiro NagaiEm Mon, Jan 16, 2012 at 02:22:10PM +0900, Akihiro Nagai escreveu:
tools/perf/util/map.h void map__delete(struct map *self); · line 119
Quoted 8 lines
perf-script uses various expressions to indicate "unknown". It is unfriendly for user scripts to parse it. So, this patch unifies the expressions to "[unknown]".
tools/perf/util/map.h +1
-0@@ -118,6 +118,7 @@ void map__delete(struct map *self);size_t map__fprintf (struct map *self,FILE *fp); +void map__print_dsoname (struct map *self);
See map__fprintf(), everything that is for printing to a file like output has that form: last paramenter is a FILE pointer, then users do:
map__fprintf_dsoname(map, stdout);
or to stderr, or to something else, like in cases where tools have a 'strace -o FILENAME' like switch, like 'perf stat --log-fd N':
OPT_INTEGER(0, "log-fd", &output_fd,
"log output to fd, instead of stderr"),
That uses fdreopen(output_fd), etc.
So please convert these new __print_something methods to __fprintf_something(..., FILE *fp).
Also please don't use 'self' anymore, that was a bad decision I made in perf's early ages and that Thomas Gleixner suggested we use more descriptive names such as, in the above case, 'map', i.e.:
void map__fprintf_dsoname(struct map *map, FILE *fp);
Quoted 1 line
From time to time I convert these 'self' leftovers in areas where I
notice that are not having too much coding activity, to avoid clashing with pending patches, so lets not add more in new code :)
Thanks,
- Arnaldo
Re: [PATCH -tip v4 1/5] perf-script: unify the expressions indicate "unknown"
Quoted 30 lines · Arnaldo Carvalho de Melo
Em Mon, Jan 16, 2012 at 02:22:10PM +0900, Akihiro Nagai escreveu:
tools/perf/util/map.h void map__delete(struct map *self); · line 119
Quoted 8 lines
perf-script uses various expressions to indicate "unknown". It is unfriendly for user scripts to parse it. So, this patch unifies the expressions to "[unknown]".
tools/perf/util/map.h +1
-0@@ -118,6 +118,7 @@ void map__delete(struct map *self);size_t map__fprintf (struct map *self,FILE *fp); +void map__print_dsoname (struct map *self);See
map__fprintf(), everything that is for printing to a file like output has that form: last paramenter is a FILE pointer, then users do:map__fprintf_dsoname(map, stdout);or to stderr, or to something else, like in cases where tools have a 'strace -o FILENAME' like switch, like 'perf stat --log-fd N':
OPT_INTEGER(0, "log-fd",&output_fd,
"log output to fd, instead of stderr"),That uses
fdreopen(output_fd), etc.So please convert these new
__print_somethingmethods to__fprintf_something(..., FILE *fp).Also please don't use 'self' anymore, that was a bad decision I made in perf's early ages and that Thomas Gleixner suggested we use more descriptive names such as, in the above case, 'map', i.e.:
Quoted 5 lines
void map__fprintf_dsoname(struct map *map, FILE *fp);Quoted 1 line
From time to time I convert these 'self' leftovers in areas where I
notice that are not having too much coding activity, to avoid clashing with pending patches, so lets not add more in new code :)
I see. I'm going to fix and resend my patches,
e.g. map__print_dsoname(self) => map__fprintf_dsoname(map, fp)
Thank you.
Quoted 4 lines
Thanks,
- Arnaldo
Re: [PATCH -tip v4 1/5] perf-script: unify the expressions indicate "unknown"
Quoted 2 lines · Akihiro Nagai
I see. I'm going to fix and resend my patches,
e.g.map__print_dsoname(self)=>map__fprintf_dsoname(map, fp)
If you are going to redo the patch set I have one request: change the name of the offset field (currently offs in your patch) to symoff to mean offset for the symbol name versus offset in the DSO. It's the latter that I use locally, so symoff would allow both to coexist.
Thanks,
David
Re: [PATCH -tip v4 1/5] perf-script: unify the expressions indicate "unknown"
Quoted 8 lines · David Ahern
Quoted 2 lines · Akihiro Nagai
I see. I'm going to fix and resend my patches,
e.g.map__print_dsoname(self)=>map__fprintf_dsoname(map, fp)If you are going to redo the patch set I have one request: change the name of the offset field (currently offs in your patch) to symoff to mean offset for the symbol name versus offset in the DSO. It's the latter that I use locally, so symoff would allow both to coexist.
OK, I'm going to rename 'offs' to 'symoff'.
Thank you.
Quoted 4 lines
Thanks,
David
PATCH v4 2/5 perf: set correct value to perf_event_header.misc for BTS
In reply to Akihiro NagaiSet correct value to perf_event_headder.misc of BTS record to resolve symbols and DSOs correctly by user-space tools.
Changes in v4:
- Add check routine to set correct value
---
arch/x86/kernel/cpu/perf_event_intel_ds.c | 31 +++++++++++++++++++---------- 1 files changed, 20 insertions(+), 11 deletions(-)
arch/x86/kernel/cpu/perf_event_intel_ds.c +20 -11
@@ -285,6 +285,18 @@ void intel_pmu_disable_bts(void)update_debugctlmsr (debugctlmsr); } + +#include <asm/insn.h> + +static inline bool kernel_ip (unsigned long ip) +{ +#ifdef CONFIG_X86_32 +return ip >PAGE_OFFSET ; +#else +return (long )ip <0 ; +#endif +} +int intel_pmu_drain_bts_buffer (void ) {struct cpu_hw_events *cpuc = &__get_cpu_var (cpu_hw_events);
@@ -330,6 +342,14 @@ int intel_pmu_drain_bts_buffer(void)return 1 ;for (; at < top; at++) { +/* +* To resolve user space symbols and DSOs correctly, set +* PERF_RECORD_MISC_USER if from_addr or to_addr is user space. +*/ +if (!kernel_ip (data.ip) || !kernel_ip (data.addr)) { + header.misc &= ~PERF_RECORD_MISC_CPUMODE_MASK ; + header.misc |=PERF_RECORD_MISC_USER ; + } data.ip = at->from; data.addr = at->to;
@@ -476,17 +496,6 @@ void intel_pmu_pebs_disable_all(void)wrmsrl (MSR_IA32_PEBS_ENABLE ,0 ); } -#include <asm/insn.h> - -static inline bool kernel_ip (unsigned long ip) -{ -#ifdef CONFIG_X86_32 -return ip >PAGE_OFFSET ; -#else -return (long )ip <0 ; -#endif -} -static int intel_pmu_pebs_fixup_ip (struct pt_regs *regs) {struct cpu_hw_events *cpuc = &__get_cpu_var (cpu_hw_events);
PATCH v4 3/5 perf script: enhance IP and ADDR correlate detection for BTS
In reply to Akihiro NagaiBTS records branch_from_addr and branch_to_addr in IP and ADDR field in perf_sample. This patch detects this correlation in perf-script.
# perf script -f ip,addr,dso,sym 3f03e016b0 _start (/lib64/ld-2.14.so) ffffffff814675d2 irq_return ([kernel.kallsyms]) 3f03e016b0 _start (/lib64/ld-2.14.so) ffffffff814675d2 irq_return ([kernel.kallsyms]) 3f03e04b80 _dl_start (/lib64/ld-2.14.so) 3f03e016b3 _start (/lib64/ld-2.14.so) 3f03e04b80 _dl_start (/lib64/ld-2.14.so) ffffffff814675d2 irq_return ([kernel.kallsyms]) 3f03e04ba6 _dl_start (/lib64/ld-2.14.so) ffffffff814675d2 irq_return ([kernel.kallsyms]) 3f03e04bad _dl_start (/lib64/ld-2.14.so) ffffffff814675d2 irq_return ([kernel.kallsyms]) 3f03e04c1d _dl_start (/lib64/ld-2.14.so) 3f03e04bfb _dl_start (/lib64/ld-2.14.so) [snip]
---
tools/perf/builtin-script.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
tools/perf/builtin-script.c +6 -0
@@ -312,6 +312,12 @@ static bool sample_addr_correlates_sym(struct perf_event_attr *attr) (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))return true; +/* BTS Events */ +if ((attr->type ==PERF_TYPE_HARDWARE ) && + (attr->config &PERF_COUNT_HW_BRANCH_INSTRUCTIONS ) && + (attr->sample_period ==1 )) +return true; +return false; }
PATCH v4 4/5 perf script: add the offset field specifier
In reply to Akihiro NagaiAdd the offset field specifier 'offs' to show the offset from the symbols in the output of perf-script. We can get the more detailed address information.
Output sample:
# perf script -f ip,addr,sym,offs 301ec016b0 _start+0x0 ffffffff81467612 irq_return+0x0 301ec016b0 _start+0x0 ffffffff81467612 irq_return+0x0 301ec04b70 _dl_start+0x0 301ec016b3 _start+0x3 301ec04b70 _dl_start+0x0 ffffffff81467612 irq_return+0x0 301ec04b96 _dl_start+0x26 ffffffff81467612 irq_return+0x0 301ec04b9d _dl_start+0x2d ffffffff81467612 irq_return+0x0 301ec04c0d _dl_start+0x9d 301ec04beb _dl_start+0x7b 301ec04bf0 _dl_start+0x80 301ec04c11 _dl_start+0xa1 [snip]
Changes in v2:
- change the way to output offset from '--show-symbol-offset' to 'offs' field.
- clean up codes.
---
tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 20 +++++++++++++++++--- tools/perf/util/session.c | 7 +++++-- tools/perf/util/session.h | 2 +- tools/perf/util/symbol.c | 22 +++++++++++++++------- tools/perf/util/symbol.h | 2 ++ 6 files changed, 41 insertions(+), 14 deletions(-)
tools/perf/Documentation/perf-script.txt +1 -1
@@ -115,7 +115,7 @@ OPTIONS -f:: --fields:: Comma separated list of fields to print. Options are: - comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr. + comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, offs. Field list can be prepended with the type, trace, sw or hw, to indicate to which event type the field list applies. e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
tools/perf/builtin-script.c +17 -3
@@ -40,6 +40,7 @@ enum perf_output_field {PERF_OUTPUT_SYM =1U <<8 ,PERF_OUTPUT_DSO =1U <<9 ,PERF_OUTPUT_ADDR =1U <<10 , + PERF_OUTPUT_OFFSET = 1U << 11, }; struct output_option {
@@ -57,6 +58,7 @@ struct output_option { {.str = "sym", .field = PERF_OUTPUT_SYM}, {.str = "dso", .field = PERF_OUTPUT_DSO}, {.str = "addr", .field = PERF_OUTPUT_ADDR}, + {.str = "offs", .field = PERF_OUTPUT_OFFSET}, };/* default set to maintain compatibility with current format */
@@ -193,6 +195,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, "to symbols.\n");return -EINVAL ; } +if (PRINT_FIELD (OFFSET ) && !PRINT_FIELD (SYM )) { +pr_err ("Display of offsets requested but symbol is not" +"selected.\n" ); +return -EINVAL ; + }if (PRINT_FIELD (DSO ) && !PRINT_FIELD (IP ) && !PRINT_FIELD (ADDR )) {pr_err ("Display of DSO requested but neither sample IP nor " "sample address\nis selected. Hence, no addresses to convert "
@@ -349,7 +356,10 @@ static void print_sample_addr(union perf_event *event,if (PRINT_FIELD (SYM )) {printf (" " ); -symbol__print_symname (al.sym); +if (PRINT_FIELD (OFFSET )) +symbol__print_symname_offs (al.sym, &al); +else +symbol__print_symname (al.sym); }if (PRINT_FIELD (DSO )) {
@@ -385,7 +395,8 @@ static void process_event(union perf_event *event __unused,else printf ("\n" );perf_event__print_ip (event, sample, machine, evsel, -PRINT_FIELD (SYM ),PRINT_FIELD (DSO )); +PRINT_FIELD (SYM ),PRINT_FIELD (DSO ), +PRINT_FIELD (OFFSET )); }printf ("\n" );
@@ -1095,7 +1106,10 @@ static const struct option options[] = {OPT_STRING (0 ,"symfs" , &symbol_conf.symfs,"directory" ,"Look for files with symbols relative to this directory" ),OPT_CALLBACK ('f' ,"fields" ,NULL ,"str" , -"comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,addr" , +"comma separated output fields prepend with 'type:'. " +"Valid types: hw,sw,trace,raw. " +"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," +"addr,offs" , parse_output_fields),OPT_BOOLEAN ('a' ,"all-cpus" , &system_wide, "system-wide collection from all CPUs"),
tools/perf/util/session.c +5 -2
@@ -1293,7 +1293,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,void perf_event__print_ip (union perf_event *event,struct perf_sample *sample,struct machine *machine,struct perf_evsel *evsel, -int print_sym,int print_dso) +int print_sym,int print_dso,int print_offset) {struct addr_location al;struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
@@ -1340,7 +1340,10 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,printf ("%16" PRIx64, sample->ip);if (print_sym) {printf (" " ); -symbol__print_symname (al.sym); +if (print_offset) +symbol__print_symname_offs (al.sym, &al); +else +symbol__print_symname (al.sym); }if (print_dso) {
tools/perf/util/session.h +1 -1
@@ -147,7 +147,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,void perf_event__print_ip (union perf_event *event,struct perf_sample *sample,struct machine *machine,struct perf_evsel *evsel, -int print_sym,int print_dso); +int print_sym,int print_dso,int print_offset);int perf_session__cpu_bitmap (struct perf_session *session,const char *cpu_list,unsigned long *cpu_bitmap);
tools/perf/util/symbol.c +15 -7
@@ -264,16 +264,24 @@ static size_t symbol__fprintf(struct symbol *sym, FILE *fp) sym->name); } -void symbol__print_symname (const struct symbol *sym) +void symbol__print_symname_offs (const struct symbol *sym, +const struct addr_location *al) { -const char *symname; +unsigned long offset; -if (sym && sym->name) - symname = sym->name; -else - symname ="[unknown]" ; +if (sym && sym->name) { +printf ("%s" , sym->name); +if (al) { + offset = al->addr - sym->start; +printf ("+0x%lx" , offset); + } + }else +printf ("[unknown]" ); +} -printf ("%s" , symname); +void symbol__print_symname (const struct symbol *sym) +{ +symbol__print_symname_offs (sym,NULL ); }void dso__set_long_name (struct dso *dso,char *name)
tools/perf/util/symbol.h +2 -0
@@ -241,6 +241,8 @@ void machines__destroy_guest_kernel_maps(struct rb_root *machines);int symbol__init (void );void symbol__exit (void ); +void symbol__print_symname_offs (const struct symbol *sym, +const struct addr_location *al);void symbol__print_symname (const struct symbol *sym);bool symbol_type__is_a (char symbol_type,enum map_type map_type);
Re: [PATCH -tip v4 4/5] perf script: add the offset field specifier
Quoted 16 lines · Akihiro Nagai
Add the offset field specifier 'offs' to show the offset from the symbols in the output of perf-script. We can get the more detailed address information.
Output sample:
# perf script -f ip,addr,sym,offs 301ec016b0 _start+0x0 ffffffff81467612 irq_return+0x0 301ec016b0 _start+0x0 ffffffff81467612 irq_return+0x0 301ec04b70 _dl_start+0x0 301ec016b3 _start+0x3 301ec04b70 _dl_start+0x0 ffffffff81467612 irq_return+0x0 301ec04b96 _dl_start+0x26 ffffffff81467612 irq_return+0x0 301ec04b9d _dl_start+0x2d ffffffff81467612 irq_return+0x0 301ec04c0d _dl_start+0x9d 301ec04beb _dl_start+0x7b 301ec04bf0 _dl_start+0x80 301ec04c11 _dl_start+0xa1 [snip]
Quoted 5 lines
Changes in v2:
- change the way to output offset from '--show-symbol-offset' to 'offs' field.
- clean up codes.
PATCH v4 5/5 perf script: add option resolving vmlinux path
In reply to Akihiro NagaiAdd the option get the path of [kernel.kallsyms]. Specify '--show-kernel-path' option to use this function. This patch enables other applications to use this output easily.
Without --show-kernel-path option
# perf script -f ip,dso
ffffffff81467612 irq_return ([kernel.kallsyms])
ffffffff81467612 irq_return ([kernel.kallsyms])
7f24fc02a6b3 _start (/lib64/ld-2.14.so)
[snip]With --show-kernel-path option
# perf script -f ip,dso --show-kernel-path
ffffffff81467612 irq_return (/lib/modules/3.2.0+/build/vmlinux)
ffffffff81467612 irq_return (/lib/modules/3.2.0+/build/vmlinux)
7f24fc02a6b3 _start (/lib64/ld-2.14.so)
[snip]---
tools/perf/Documentation/perf-script.txt | 3 +++ tools/perf/builtin-script.c | 3 +++ tools/perf/util/map.c | 9 ++++++--- tools/perf/util/symbol.h | 1 + 4 files changed, 13 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-script.txt +3 -0
@@ -200,6 +200,9 @@ OPTIONS It currently includes: cpu and numa topology of the host system. It can only be used with the perf script report mode. +--show-kernel-path:: + Try to resolve the path of [kernel.kallsyms] + SEE ALSO -------- linkperf:perf-record[1], linkperf:perf-script-perl[1],
tools/perf/builtin-script.c +3 -0
@@ -1118,6 +1118,9 @@ static const struct option options[] = { "only display events for these comms"),OPT_BOOLEAN ('I' ,"show-info" , &show_full_info,"display extended information from perf.data file" ), +OPT_BOOLEAN ('\0' ,"show-kernel-path" , &symbol_conf.show_kernel_path, +"Show the path of [kernel.kallsyms]" ), + OPT_END() };
tools/perf/util/map.c +6 -3
@@ -216,9 +216,12 @@ void map__print_dsoname(struct map *self) {const char *dsoname; -if (self && self->dso && self->dso->name) - dsoname = self->dso->name; -else +if (self && self->dso && (self->dso->name || self->dso->long_name)) { +if (symbol_conf.show_kernel_path && self->dso->long_name) + dsoname = self->dso->long_name; +else if (self->dso->name) + dsoname = self->dso->name; + }else dsoname ="[unknown]" ;printf ("%s" , dsoname);
tools/perf/util/symbol.h +1 -0
@@ -70,6 +70,7 @@ struct symbol_conf {unsigned short priv_size;unsigned short nr_events;bool try_vmlinux_path, + show_kernel_path, use_modules, sort_by_name, show_nr_samples,
Quoted 21 lines · Akihiro Nagai
Hi Frederic, David,
This patch series adds the functions to analyze BTS logs to perf-script and, makes perf-script more informative version 4.
The patches add the following functions.
- Unify the expression to "[unknown]"
- Fix BTS record header to resolve DSOs and symbols of user-space
- Resolve DSOs and symbols for BTS'sbranch_fromaddresses
- Show the offset of symbols with the 'offs' field specifier.
- Resolve the real path of [kernel.kallsym] using '--show-kernel-path' option.Usage:
First, get the BTS log with the following command.# perf record -e branches:u -c 1 -d <command>Second, analyze that trace data.
# perf script -f ip,addr,sym,offs,dso [--show-kernel-path] This command's output format is: <branch_to addr> <branch_to function+offset> <branch_to DSO> <branch_from addr> <branch_from function+offset> <branch_from DSO>
Quoted 6 lines
Output sample:
# perf record -e branches:u -c 1 -d ls [snip] # perf script -f ip,addr,sym,dso,offs --show-kernel-path [snip] 402c1c main+0x0 (/root/bin/ls) 3430c21399 __libc_start_main+0xe9 (/lib64/libc-2.14.so)
I was confused first, looking for the reason why we have a so strange branch flow until I realized the format is "to from".
Can we have "from to" instead? This will be much more intuitive. "from => to" would be even better.
Thanks!
Quoted 7 lines
40b390 set_program_name+0x0 (/root/bin/ls) 402c41 main+0x25 (/root/bin/ls) 40b390 set_program_name+0x0 (/root/bin/ls) ffffffff814ac5ed irq_return+0x0 (/lib/modules/3.2.0+/build/vmlinux) 401e20 strrchr@plt+0x0 (/root/bin/ls) 40b39e set_program_name+0xe (/root/bin/ls) 401e26 strrchr@plt+0x6 (/root/bin/ls) 401e20 strrchr@plt+0x0 (/root/bin/ls) 401b80 _init+0x18 (/root/bin/ls) 401e2b strrchr@plt+0xb (/root/bin/ls) 3430813850 _dl_runtime_resolve+0x0 (/lib64/ld-2.14.so) 401b86 _init+0x1e (/root/bin/ls)[snip]
Quoted 29 lines · Frederic Weisbecker
Quoted 21 lines · Akihiro Nagai
Hi Frederic, David,
This patch series adds the functions to analyze BTS logs to perf-script and, makes perf-script more informative version 4.
The patches add the following functions.
- Unify the expression to "[unknown]"
- Fix BTS record header to resolve DSOs and symbols of user-space
- Resolve DSOs and symbols for BTS'sbranch_fromaddresses
- Show the offset of symbols with the 'offs' field specifier.
- Resolve the real path of [kernel.kallsym] using '--show-kernel-path' option.Usage:
First, get the BTS log with the following command.# perf record -e branches:u -c 1 -d<command>Second, analyze that trace data.
# perf script -f ip,addr,sym,offs,dso [--show-kernel-path] This command's output format is: <branch_to addr> <branch_to function+offset> <branch_to DSO> <branch_from addr> <branch_from function+offset> <branch_from DSO>Quoted 6 lines
Output sample:
# perf record -e branches:u -c 1 -d ls [snip] # perf script -f ip,addr,sym,dso,offs --show-kernel-path [snip] 402c1c main+0x0 (/root/bin/ls) 3430c21399 __libc_start_main+0xe9 (/lib64/libc-2.14.so)
Quoted 4 lines
I was confused first, looking for the reason why we have a so strange branch flow until I realized the format is "to from".
Can we have "from to" instead? This will be much more intuitive. "from => to" would be even better.
Exactly.
perf records branch_to information in perf_sample->addr, and branch_from in perf_sample->ip. And, currently I use the generic function: process_event() in builtin-script.c to print branch information. This function prints perf_sample->addr before it prints perf_sample->ip.
So, I'm going to add the bts specialized codes to process_event().
static void process_event(...)
{
<snip>
print_sample_start(sample, thread, attr);
if (is_bts_event(attr)) {
print_sample_bts(...);
return;
}
if (PRINT_FIELD(TRACE))
<snip>
}Thank you.
Quoted 11 lines
Thanks!
Quoted 7 lines
40b390 set_program_name+0x0 (/root/bin/ls) 402c41 main+0x25 (/root/bin/ls) 40b390 set_program_name+0x0 (/root/bin/ls) ffffffff814ac5ed irq_return+0x0 (/lib/modules/3.2.0+/build/vmlinux) 401e20 strrchr@plt+0x0 (/root/bin/ls) 40b39e set_program_name+0xe (/root/bin/ls) 401e26 strrchr@plt+0x6 (/root/bin/ls) 401e20 strrchr@plt+0x0 (/root/bin/ls) 401b80 _init+0x18 (/root/bin/ls) 401e2b strrchr@plt+0xb (/root/bin/ls) 3430813850 _dl_runtime_resolve+0x0 (/lib64/ld-2.14.so) 401b86 _init+0x1e (/root/bin/ls)[snip]
Quoted 55 lines · Akihiro Nagai
Quoted 29 lines · Frederic Weisbecker
Quoted 21 lines · Akihiro Nagai
Hi Frederic, David,
This patch series adds the functions to analyze BTS logs to perf-script and, makes perf-script more informative version 4.
The patches add the following functions.
- Unify the expression to "[unknown]"
- Fix BTS record header to resolve DSOs and symbols of user-space
- Resolve DSOs and symbols for BTS'sbranch_fromaddresses
- Show the offset of symbols with the 'offs' field specifier.
- Resolve the real path of [kernel.kallsym] using '--show-kernel-path' option.Usage:
First, get the BTS log with the following command.# perf record -e branches:u -c 1 -d<command>Second, analyze that trace data.
# perf script -f ip,addr,sym,offs,dso [--show-kernel-path] This command's output format is: <branch_to addr> <branch_to function+offset> <branch_to DSO> <branch_from addr> <branch_from function+offset> <branch_from DSO>Quoted 6 lines
Output sample:
# perf record -e branches:u -c 1 -d ls [snip] # perf script -f ip,addr,sym,dso,offs --show-kernel-path [snip] 402c1c main+0x0 (/root/bin/ls) 3430c21399 __libc_start_main+0xe9 (/lib64/libc-2.14.so)Quoted 4 lines
I was confused first, looking for the reason why we have a so strange branch flow until I realized the format is "to from".
Can we have "from to" instead? This will be much more intuitive. "from => to" would be even better.
Exactly.
perf recordsbranch_toinformation inperf_sample->addr, andbranch_frominperf_sample->ip. And, currently I use the generic function:process_event()inbuiltin-script.cto print branch information. This function printsperf_sample->addrbefore it printsperf_sample->ip.So, I'm going to add the bts specialized codes to
process_event().static void
process_event(...){ <snip> print_sample_start(sample, thread, attr); if (is_bts_event(attr)) { print_sample_bts(...); return; } if (PRINT_FIELD(TRACE)) <snip> }
Quoted 1 line
Thank you.
You're right, that's a specialization. We need to support well raw formatting like you did and then we can do the specialization incrementally.
Thanks!
Quoted 11 lines
Quoted 11 lines
Thanks!
Quoted 7 lines
40b390 set_program_name+0x0 (/root/bin/ls) 402c41 main+0x25 (/root/bin/ls) 40b390 set_program_name+0x0 (/root/bin/ls) ffffffff814ac5ed irq_return+0x0 (/lib/modules/3.2.0+/build/vmlinux) 401e20 strrchr@plt+0x0 (/root/bin/ls) 40b39e set_program_name+0xe (/root/bin/ls) 401e26 strrchr@plt+0x6 (/root/bin/ls) 401e20 strrchr@plt+0x0 (/root/bin/ls) 401b80 _init+0x18 (/root/bin/ls) 401e2b strrchr@plt+0xb (/root/bin/ls) 3430813850 _dl_runtime_resolve+0x0 (/lib64/ld-2.14.so) 401b86 _init+0x1e (/root/bin/ls)[snip]