perf, tools: Support srccode output
PATCH 1/1 perf, tools: Support srccode output
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn
...
main+22:
0000000000400543 insn: e8 ca ff ff ff # PRED
|18 f1();
f1:
0000000000400512 insn: 55
|10 {
0000000000400513 insn: 48 89 e5
0000000000400516 insn: b8 00 00 00 00
|11 f2();
000000000040051b insn: e8 d6 ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
0000000000400500 insn: 8b 0d 2a 0b 20 00
0000000000400506 insn: 99
0000000000400507 insn: f7 f9
0000000000400509 insn: 89 05 29 0b 20 00
000000000040050f insn: 90
|7 }
0000000000400510 insn: 5d
0000000000400511 insn: c3 # PRED
f1+14:
0000000000400520 insn: b8 00 00 00 00
|12 f2();
0000000000400525 insn: e8 cc ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00|6 c = a / b;
Not supported for callchains currently, would need some layout changes there.
--- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 47 +++++- tools/perf/util/Build | 1 + tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/map.c | 49 ++++++ tools/perf/util/map.h | 16 ++ tools/perf/util/srccode.c | 186 +++++++++++++++++++++++ tools/perf/util/srccode.h | 7 + tools/perf/util/srcline.c | 28 ++++ tools/perf/util/srcline.h | 1 + tools/perf/util/thread.c | 2 + tools/perf/util/thread.h | 2 + 12 files changed, 339 insertions(+), 3 deletions(-) create mode 100644 tools/perf/util/srccode.c create mode 100644 tools/perf/util/srccode.h
tools/perf/Documentation/perf-script.txt +1 -1
@@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn, - brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc. + brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode. 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 +45 -2
113 lines not on this page · raw message
tools/perf/util/Build +1 -0
@@ -77,6 +77,7 @@ libperf-y += stat-shadow.o libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o +libperf-y += srccode.o libperf-y += data.o libperf-y += tsc.o libperf-y += cloexec.o
tools/perf/util/evsel_fprintf.c +1 -0
@@ -173,6 +173,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,if (!print_oneline) printed +=fprintf (fp,"\n" ); +/* Add srccode here too? */ if (symbol_conf.bt_stop_list && node->sym && strlist__has_entry(symbol_conf.bt_stop_list,
tools/perf/util/map.c +49 -0
61 lines not on this page · raw message
tools/perf/util/map.h +16 -0
@@ -174,6 +174,22 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym);int map__fprintf_srcline (struct map *map,u64 addr,const char *prefix,FILE *fp); +struct srccode_state { +char *srcfile; +unsigned line; +}; + +static inline void srccode_state_init (struct srccode_state *state) +{ + state->srcfile =NULL ; + state->line =0 ; +} + +void srccode_state_free (struct srccode_state *state); + +int map__fprintf_srccode (struct map *map,u64 addr, +FILE *fp,struct srccode_state *state); +int map__load (struct map *map);struct symbol *map__find_symbol (struct map *map,u64 addr);struct symbol *map__find_symbol_by_name (struct map *map,const char *name);
tools/perf/util/srccode.c new file +186 -0
186 lines not on this page · raw message
tools/perf/util/srccode.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef SRCCODE_H +#define SRCCODE_H 1 + +/* Result is not 0 terminated */ +char *find_sourceline (char *fn,unsigned line,int *lenp); + +#endif
tools/perf/util/srcline.c +28 -0
@@ -548,6 +548,34 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,return srcline; } +/* Returns filename and fills in line number in line */ +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line) +{ +char *file =NULL ; +const char *dso_name; + +if (!dso->has_srcline) + goto out; + + dso_name =dso__name (dso); +if (dso_name ==NULL ) + goto out; + +if (!addr2line (dso_name, addr, &file, line, dso, true,NULL ,NULL )) + goto out; + + dso->a2l_fails =0 ; +return file; + +out: +if (dso->a2l_fails && ++dso->a2l_fails >A2L_FAIL_LIMIT ) { + dso->has_srcline =0 ; +dso__free_a2l (dso); + } + +return NULL ; +} +void free_srcline (char *srcline) {if (srcline &&strcmp (srcline,SRCLINE_UNKNOWN ) !=0 )
tools/perf/util/srcline.h +1 -0
@@ -16,6 +16,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, bool unwind_inlines, u64 ip);void free_srcline (char *srcline); +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line);/* insert the srcline into the DSO, which will take ownership */ void srcline__tree_insert (struct rb_root *tree,u64 addr,char *srcline);
tools/perf/util/thread.c +2 -0
@@ -64,6 +64,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)RB_CLEAR_NODE (&thread->rb_node);/* Thread holds first ref to nsdata. */ thread->nsinfo =nsinfo__new (pid); +srccode_state_init (&thread->srccode_state); }return thread;
@@ -103,6 +104,7 @@ void thread__delete(struct thread *thread)unwind__finish_access (thread);nsinfo__zput (thread->nsinfo); +srccode_state_free (&thread->srccode_state);exit_rwsem (&thread->namespaces_lock);exit_rwsem (&thread->comm_lock);
tools/perf/util/thread.h +2 -0
@@ -8,6 +8,7 @@#include <unistd.h> #include <sys/types.h> #include "symbol.h" +#include "map.h" #include <strlist.h> #include <intlist.h> #include "rwsem.h"
@@ -38,6 +39,7 @@ struct thread {void *priv;struct thread_stack *ts;struct nsinfo *nsinfo; +struct srccode_state srccode_state;#ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space;struct unwind_libunwind_ops *unwind_libunwind_ops;
Signature · 1 line
2.17.2
Quoted 67 lines · Andi Kleen
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn...
main+22: 0000000000400543 insn: e8 ca ff ff ff # PRED |18 f1(); f1: 0000000000400512 insn: 55 |10 { 0000000000400513 insn: 48 89 e5 0000000000400516 insn: b8 00 00 00 00 |11 f2(); 000000000040051b insn: e8 d6 ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00 |6 c = a / b; 0000000000400500 insn: 8b 0d 2a 0b 20 00 0000000000400506 insn: 99 0000000000400507 insn: f7 f9 0000000000400509 insn: 89 05 29 0b 20 00 000000000040050f insn: 90 |7 } 0000000000400510 insn: 5d 0000000000400511 insn: c3 # PRED f1+14: 0000000000400520 insn: b8 00 00 00 00 |12 f2(); 0000000000400525 insn: e8 cc ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00
Quoted 4 lines
|6 c = a / b;
Not supported for callchains currently, would need some layout changes there.
nice, works nicely, especialy with --xed
I need to check, but is there a way to make this work with perf-with-kcore script? looks like we endup with kcore and won't allow vmlinux lookups for debug info
thanks,
jirka
Arnaldo Carvalho de Melo
maintainerEm Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
Quoted 70 lines · Andi Kleen
Quoted 69 lines
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn...
main+22: 0000000000400543 insn: e8 ca ff ff ff # PRED |18 f1(); f1: 0000000000400512 insn: 55 |10 { 0000000000400513 insn: 48 89 e5 0000000000400516 insn: b8 00 00 00 00 |11 f2(); 000000000040051b insn: e8 d6 ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00 |6 c = a / b; 0000000000400500 insn: 8b 0d 2a 0b 20 00 0000000000400506 insn: 99 0000000000400507 insn: f7 f9 0000000000400509 insn: 89 05 29 0b 20 00 000000000040050f insn: 90 |7 } 0000000000400510 insn: 5d 0000000000400511 insn: c3 # PRED f1+14: 0000000000400520 insn: b8 00 00 00 00 |12 f2(); 0000000000400525 insn: e8 cc ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00|6 c = a / b;
Quoted 4 lines
Quoted 2 lines
Not supported for callchains currently, would need some layout changes there.
nice, works nicely, especialy with --xed
The above seems to imply you actually tested it, was that the case? Can you please provide me the exact 'perf record' line you used, that is lacking in Andi's original commit log message?
- Arnaldo
Quoted 1 line
Acked-by Jiri Olsa <[email protected]>
Quoted 71 lines · Arnaldo Carvalho de Melo
Em Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
Quoted 70 lines · Andi Kleen
Quoted 69 lines
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn...
main+22: 0000000000400543 insn: e8 ca ff ff ff # PRED |18 f1(); f1: 0000000000400512 insn: 55 |10 { 0000000000400513 insn: 48 89 e5 0000000000400516 insn: b8 00 00 00 00 |11 f2(); 000000000040051b insn: e8 d6 ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00 |6 c = a / b; 0000000000400500 insn: 8b 0d 2a 0b 20 00 0000000000400506 insn: 99 0000000000400507 insn: f7 f9 0000000000400509 insn: 89 05 29 0b 20 00 000000000040050f insn: 90 |7 } 0000000000400510 insn: 5d 0000000000400511 insn: c3 # PRED f1+14: 0000000000400520 insn: b8 00 00 00 00 |12 f2(); 0000000000400525 insn: e8 cc ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00|6 c = a / b;
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Not supported for callchains currently, would need some layout changes there.
nice, works nicely, especialy with --xed
The above seems to imply you actually tested it, was that the case? Can you please provide me the exact 'perf record' line you used, that is lacking in Andi's original commit log message?
yep..
# ./perf record -e intel_pt//u -- ./perf
jirka
Quoted 73 lines · Jiri Olsa
Quoted 67 lines · Andi Kleen
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn...
main+22: 0000000000400543 insn: e8 ca ff ff ff # PRED |18 f1(); f1: 0000000000400512 insn: 55 |10 { 0000000000400513 insn: 48 89 e5 0000000000400516 insn: b8 00 00 00 00 |11 f2(); 000000000040051b insn: e8 d6 ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00 |6 c = a / b; 0000000000400500 insn: 8b 0d 2a 0b 20 00 0000000000400506 insn: 99 0000000000400507 insn: f7 f9 0000000000400509 insn: 89 05 29 0b 20 00 000000000040050f insn: 90 |7 } 0000000000400510 insn: 5d 0000000000400511 insn: c3 # PRED f1+14: 0000000000400520 insn: b8 00 00 00 00 |12 f2(); 0000000000400525 insn: e8 cc ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00Quoted 4 lines
|6 c = a / b;
Not supported for callchains currently, would need some layout changes there.
Quoted 7 lines
nice, works nicely, especialy with --xed
Acked-by Jiri Olsa <[email protected]>I need to check, but is there a way to make this work with perf-with-kcore script? looks like we endup with kcore and won't allow vmlinux lookups for debug info
Hmm, probably not currently. Would somehow need to point to the debuginfo. Perhaps if /proc/kcore was fixed to report the debugid, and then could find it this way.
Or we could add an option to perf report to add a vmlinux only for debug info that is not used for reading the code.
-andi
Arnaldo Carvalho de Melo
maintainerEm Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
Quoted 70 lines · Andi Kleen
Quoted 69 lines
From: Andi Kleen <[email protected]>
When looking at PT or brstackinsn traces with perf script it can be very useful to see the source code. This adds a simple facility to print them with perf script, if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004c6 main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004cd main 5 for (i = 0; i < 10000000; i++) 4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn...
main+22: 0000000000400543 insn: e8 ca ff ff ff # PRED |18 f1(); f1: 0000000000400512 insn: 55 |10 { 0000000000400513 insn: 48 89 e5 0000000000400516 insn: b8 00 00 00 00 |11 f2(); 000000000040051b insn: e8 d6 ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00 |6 c = a / b; 0000000000400500 insn: 8b 0d 2a 0b 20 00 0000000000400506 insn: 99 0000000000400507 insn: f7 f9 0000000000400509 insn: 89 05 29 0b 20 00 000000000040050f insn: 90 |7 } 0000000000400510 insn: 5d 0000000000400511 insn: c3 # PRED f1+14: 0000000000400520 insn: b8 00 00 00 00 |12 f2(); 0000000000400525 insn: e8 cc ff ff ff # PRED f2: 00000000004004f6 insn: 55 |5 { 00000000004004f7 insn: 48 89 e5 00000000004004fa insn: 8b 05 2c 0b 20 00|6 c = a / b;
Quoted 6 lines
Quoted 2 lines
Not supported for callchains currently, would need some layout changes there.
nice, works nicely, especialy with --xed
Acked-by Jiri Olsa <[email protected]>
Trying to fix this:
alpine:3.4
Downloading http://x.x.x.x/perf/perf-4.20.0-rc3.tar.xz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed100 1426k 100 1426k 0 0 232M 0 --:--:-- --:--:-- --:--:-- 232M8932875925270caf72895c32013a678e9c19aa0d
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-alpine-linux-musl/5.3.0/lto-wrapper
Target: x86_64-alpine-linux-musl
Configured with: /home/buildozer/aports/main/gcc/src/gcc-5.3.0/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --build=x86_64-alpine-linux-musl --host=x86_64-alpine-linux-musl --target=x86_64-alpine-linux-musl --with-pkgversion='Alpine 5.3.0' --enable-checking=release --disable-fixed-point --disable-libstdcxx-pch --disable-multilib --disable-nls --disable-werror --disable-symvers --enable-__cxa_atexit --enable-esp --enable-cloog-backend --enable-languages=c,c++,objc,java,fortran,ada --disable-libssp --disable-libmudflap --disable-libsanitizer --enable-shared --enable-threads --enable-tls --with-system-zlib Thread model: posix
gcc version 5.3.0 (Alpine 5.3.0)
CC /tmp/build/perf/util/srccode.o
In file included from util/srccode.c:19:0:/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
^
CC /tmp/build/perf/util/data.o
cc1: all warnings being treated as errors
mv: can't rename '/tmp/build/perf/util/.srccode.o.tmp': No such file or directory
/git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/srccode.o' failed
make[4]: *** [/tmp/build/perf/util/srccode.o] Error 1
make[4]: *** Waiting for unfinished jobs....
CC /tmp/build/perf/tests/attr.o
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf tools: Support 'srccode' output
In reply to Andi Kleenperf tools: Support 'srccode' output
Commit-ID: 6024b7a51a19256df871d148925b2f0e4fc18436 Gitweb: https://git.kernel.org/tip/6024b7a51a19256df871d148925b2f0e4fc18436 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 3 Dec 2018 16:18:48 -0800 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Thu, 6 Dec 2018 14:12:32 -0300
perf tools: Support 'srccode' output
When looking at PT or brstackinsn traces with 'perf script' it can be very useful to see the source code. This adds a simple facility to print them with 'perf script', if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn
...
main+22:
0000000000400543 insn: e8 ca ff ff ff # PRED
|18 f1();
f1:
0000000000400512 insn: 55
|10 {
0000000000400513 insn: 48 89 e5
0000000000400516 insn: b8 00 00 00 00
|11 f2();
000000000040051b insn: e8 d6 ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
0000000000400500 insn: 8b 0d 2a 0b 20 00
0000000000400506 insn: 99
0000000000400507 insn: f7 f9
0000000000400509 insn: 89 05 29 0b 20 00
000000000040050f insn: 90
|7 }
0000000000400510 insn: 5d
0000000000400511 insn: c3 # PRED
f1+14:
0000000000400520 insn: b8 00 00 00 00
|12 f2();
0000000000400525 insn: e8 cc ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;Not supported for callchains currently, would need some layout changes there.
Committer notes:
Fixed the build on Alpine Linux (3.4 .. 3.8) by addressing this warning:
In file included from util/srccode.c:19:0:
/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
^~~~~~~
cc1: all warnings being treated as errors
--- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 47 +++++++- tools/perf/util/Build | 1 + tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/map.c | 49 ++++++++ tools/perf/util/map.h | 16 +++ tools/perf/util/srccode.c | 186 +++++++++++++++++++++++++++++++ tools/perf/util/srccode.h | 7 ++ tools/perf/util/srcline.c | 28 +++++ tools/perf/util/srcline.h | 1 + tools/perf/util/thread.c | 2 + tools/perf/util/thread.h | 2 + 12 files changed, 339 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-script.txt +1 -1
@@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn, - brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc. + brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode. 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 +45 -2
113 lines not on this page · raw message
tools/perf/util/Build +1 -0
@@ -77,6 +77,7 @@ libperf-y += stat-shadow.o libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o +libperf-y += srccode.o libperf-y += data.o libperf-y += tsc.o libperf-y += cloexec.o
tools/perf/util/evsel_fprintf.c +1 -0
@@ -173,6 +173,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,if (!print_oneline) printed +=fprintf (fp,"\n" ); +/* Add srccode here too? */ if (symbol_conf.bt_stop_list && node->sym && strlist__has_entry(symbol_conf.bt_stop_list,
tools/perf/util/map.c +49 -0
61 lines not on this page · raw message
tools/perf/util/map.h +16 -0
@@ -174,6 +174,22 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym);int map__fprintf_srcline (struct map *map,u64 addr,const char *prefix,FILE *fp); +struct srccode_state { +char *srcfile; +unsigned line; +}; + +static inline void srccode_state_init (struct srccode_state *state) +{ + state->srcfile =NULL ; + state->line =0 ; +} + +void srccode_state_free (struct srccode_state *state); + +int map__fprintf_srccode (struct map *map,u64 addr, +FILE *fp,struct srccode_state *state); +int map__load (struct map *map);struct symbol *map__find_symbol (struct map *map,u64 addr);struct symbol *map__find_symbol_by_name (struct map *map,const char *name);
tools/perf/util/srccode.c new file +186 -0
186 lines not on this page · raw message
tools/perf/util/srccode.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef SRCCODE_H +#define SRCCODE_H 1 + +/* Result is not 0 terminated */ +char *find_sourceline (char *fn,unsigned line,int *lenp); + +#endif
tools/perf/util/srcline.c +28 -0
@@ -548,6 +548,34 @@ out:return srcline; } +/* Returns filename and fills in line number in line */ +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line) +{ +char *file =NULL ; +const char *dso_name; + +if (!dso->has_srcline) + goto out; + + dso_name =dso__name (dso); +if (dso_name ==NULL ) + goto out; + +if (!addr2line (dso_name, addr, &file, line, dso, true,NULL ,NULL )) + goto out; + + dso->a2l_fails =0 ; +return file; + +out: +if (dso->a2l_fails && ++dso->a2l_fails >A2L_FAIL_LIMIT ) { + dso->has_srcline =0 ; +dso__free_a2l (dso); + } + +return NULL ; +} +void free_srcline (char *srcline) {if (srcline &&strcmp (srcline,SRCLINE_UNKNOWN ) !=0 )
tools/perf/util/srcline.h +1 -0
@@ -16,6 +16,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, bool unwind_inlines, u64 ip);void free_srcline (char *srcline); +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line);/* insert the srcline into the DSO, which will take ownership */ void srcline__tree_insert (struct rb_root *tree,u64 addr,char *srcline);
tools/perf/util/thread.c +2 -0
@@ -64,6 +64,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)RB_CLEAR_NODE (&thread->rb_node);/* Thread holds first ref to nsdata. */ thread->nsinfo =nsinfo__new (pid); +srccode_state_init (&thread->srccode_state); }return thread;
@@ -103,6 +104,7 @@ void thread__delete(struct thread *thread)unwind__finish_access (thread);nsinfo__zput (thread->nsinfo); +srccode_state_free (&thread->srccode_state);exit_rwsem (&thread->namespaces_lock);exit_rwsem (&thread->comm_lock);
tools/perf/util/thread.h +2 -0
@@ -8,6 +8,7 @@#include <unistd.h> #include <sys/types.h> #include "symbol.h" +#include "map.h" #include <strlist.h> #include <intlist.h> #include "rwsem.h"
@@ -38,6 +39,7 @@ struct thread {void *priv;struct thread_stack *ts;struct nsinfo *nsinfo; +struct srccode_state srccode_state;#ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space;struct unwind_libunwind_ops *unwind_libunwind_ops;
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf tools: Support 'srccode' output
In reply to Andi Kleenperf tools: Support 'srccode' output
Commit-ID: dd2e18e9ac20e3ffc27cabf318e83b43ed5ddb92 Gitweb: https://git.kernel.org/tip/dd2e18e9ac20e3ffc27cabf318e83b43ed5ddb92 Author: Andi Kleen <[email protected]> AuthorDate: Mon, 3 Dec 2018 16:18:48 -0800 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 17 Dec 2018 14:57:07 -0300
perf tools: Support 'srccode' output
When looking at PT or brstackinsn traces with 'perf script' it can be very useful to see the source code. This adds a simple facility to print them with 'perf script', if the information is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004b3 main6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn
...
main+22:
0000000000400543 insn: e8 ca ff ff ff # PRED
|18 f1();
f1:
0000000000400512 insn: 55
|10 {
0000000000400513 insn: 48 89 e5
0000000000400516 insn: b8 00 00 00 00
|11 f2();
000000000040051b insn: e8 d6 ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
0000000000400500 insn: 8b 0d 2a 0b 20 00
0000000000400506 insn: 99
0000000000400507 insn: f7 f9
0000000000400509 insn: 89 05 29 0b 20 00
000000000040050f insn: 90
|7 }
0000000000400510 insn: 5d
0000000000400511 insn: c3 # PRED
f1+14:
0000000000400520 insn: b8 00 00 00 00
|12 f2();
0000000000400525 insn: e8 cc ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;Not supported for callchains currently, would need some layout changes there.
Committer notes:
Fixed the build on Alpine Linux (3.4 .. 3.8) by addressing this warning:
In file included from util/srccode.c:19:0:
/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
^~~~~~~
cc1: all warnings being treated as errors
--- tools/perf/Documentation/perf-script.txt | 2 +- tools/perf/builtin-script.c | 47 +++++++- tools/perf/util/Build | 1 + tools/perf/util/evsel_fprintf.c | 1 + tools/perf/util/map.c | 49 ++++++++ tools/perf/util/map.h | 16 +++ tools/perf/util/srccode.c | 186 +++++++++++++++++++++++++++++++ tools/perf/util/srccode.h | 7 ++ tools/perf/util/srcline.c | 28 +++++ tools/perf/util/srcline.h | 1 + tools/perf/util/thread.c | 2 + tools/perf/util/thread.h | 2 + 12 files changed, 339 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-script.txt +1 -1
@@ -117,7 +117,7 @@ OPTIONS Comma separated list of fields to print. Options are: comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn, - brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc. + brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode. 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 +45 -2
113 lines not on this page · raw message
tools/perf/util/Build +1 -0
@@ -77,6 +77,7 @@ libperf-y += stat-shadow.o libperf-y += stat-display.o libperf-y += record.o libperf-y += srcline.o +libperf-y += srccode.o libperf-y += data.o libperf-y += tsc.o libperf-y += cloexec.o
tools/perf/util/evsel_fprintf.c +1 -0
@@ -173,6 +173,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,if (!print_oneline) printed +=fprintf (fp,"\n" ); +/* Add srccode here too? */ if (symbol_conf.bt_stop_list && node->sym && strlist__has_entry(symbol_conf.bt_stop_list,
tools/perf/util/map.c +49 -0
61 lines not on this page · raw message
tools/perf/util/map.h +16 -0
@@ -174,6 +174,22 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym);int map__fprintf_srcline (struct map *map,u64 addr,const char *prefix,FILE *fp); +struct srccode_state { +char *srcfile; +unsigned line; +}; + +static inline void srccode_state_init (struct srccode_state *state) +{ + state->srcfile =NULL ; + state->line =0 ; +} + +void srccode_state_free (struct srccode_state *state); + +int map__fprintf_srccode (struct map *map,u64 addr, +FILE *fp,struct srccode_state *state); +int map__load (struct map *map);struct symbol *map__find_symbol (struct map *map,u64 addr);struct symbol *map__find_symbol_by_name (struct map *map,const char *name);
tools/perf/util/srccode.c new file +186 -0
186 lines not on this page · raw message
tools/perf/util/srccode.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef SRCCODE_H +#define SRCCODE_H 1 + +/* Result is not 0 terminated */ +char *find_sourceline (char *fn,unsigned line,int *lenp); + +#endif
tools/perf/util/srcline.c +28 -0
@@ -548,6 +548,34 @@ out:return srcline; } +/* Returns filename and fills in line number in line */ +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line) +{ +char *file =NULL ; +const char *dso_name; + +if (!dso->has_srcline) + goto out; + + dso_name =dso__name (dso); +if (dso_name ==NULL ) + goto out; + +if (!addr2line (dso_name, addr, &file, line, dso, true,NULL ,NULL )) + goto out; + + dso->a2l_fails =0 ; +return file; + +out: +if (dso->a2l_fails && ++dso->a2l_fails >A2L_FAIL_LIMIT ) { + dso->has_srcline =0 ; +dso__free_a2l (dso); + } + +return NULL ; +} +void free_srcline (char *srcline) {if (srcline &&strcmp (srcline,SRCLINE_UNKNOWN ) !=0 )
tools/perf/util/srcline.h +1 -0
@@ -16,6 +16,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym, bool show_sym, bool show_addr, bool unwind_inlines, u64 ip);void free_srcline (char *srcline); +char *get_srcline_split (struct dso *dso,u64 addr,unsigned *line);/* insert the srcline into the DSO, which will take ownership */ void srcline__tree_insert (struct rb_root *tree,u64 addr,char *srcline);
tools/perf/util/thread.c +2 -0
@@ -64,6 +64,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)RB_CLEAR_NODE (&thread->rb_node);/* Thread holds first ref to nsdata. */ thread->nsinfo =nsinfo__new (pid); +srccode_state_init (&thread->srccode_state); }return thread;
@@ -103,6 +104,7 @@ void thread__delete(struct thread *thread)unwind__finish_access (thread);nsinfo__zput (thread->nsinfo); +srccode_state_free (&thread->srccode_state);exit_rwsem (&thread->namespaces_lock);exit_rwsem (&thread->comm_lock);
tools/perf/util/thread.h +2 -0
@@ -8,6 +8,7 @@#include <unistd.h> #include <sys/types.h> #include "symbol.h" +#include "map.h" #include <strlist.h> #include <intlist.h> #include "rwsem.h"
@@ -38,6 +39,7 @@ struct thread {void *priv;struct thread_stack *ts;struct nsinfo *nsinfo; +struct srccode_state srccode_state;#ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space;struct unwind_libunwind_ops *unwind_libunwind_ops;