Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf script: Add new output field 'dsoff' to print dso offset

This adds a new 'dsoff' field to print dso offset for resolved symbols,
and the offset is appended to dso name.

Default output:

$ perf script
ls 2695501 3011030.487017: 500000 cycles: 152cc73ef4b5 get_common_indices.constprop.0+0x155 (/usr/lib/x86_64-linux-gnu/ld-2.31.so)
ls 2695501 3011030.487018: 500000 cycles: ffffffff99045b3e [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffff9968e107 [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffffc1f54afb [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffff9968382f [unknown] ([unknown])
ls 2695501 3011030.487019: 500000 cycles: ffffffff99e00094 [unknown] ([unknown])
ls 2695501 3011030.487019: 500000 cycles: 152cc718a8d0 __errno_location@plt+0x0 (/usr/lib/x86_64-linux-gnu/libselinux.so.1)

Display 'dsoff' field:

$ perf script -F +dsoff
ls 2695501 3011030.487017: 500000 cycles: 152cc73ef4b5 get_common_indices.constprop.0+0x155 (/usr/lib/x86_64-linux-gnu/ld-2.31.so+0x1c4b5)
ls 2695501 3011030.487018: 500000 cycles: ffffffff99045b3e [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffff9968e107 [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffffc1f54afb [unknown] ([unknown])
ls 2695501 3011030.487018: 500000 cycles: ffffffff9968382f [unknown] ([unknown])
ls 2695501 3011030.487019: 500000 cycles: ffffffff99e00094 [unknown] ([unknown])
ls 2695501 3011030.487019: 500000 cycles: 152cc718a8d0 __errno_location@plt+0x0 (/usr/lib/x86_64-linux-gnu/libselinux.so.1+0x68d0)
ls 2695501 3011030.487019: 500000 cycles: ffffffff992a6db0 [unknown] ([unknown])

Signed-off-by: Changbin Du <changbin.du@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Hui Wang <hw.huiwang@huawei.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20230418031825.1262579-4-changbin.du@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Changbin Du and committed by
Arnaldo Carvalho de Melo
af9eb56b 2b433fad

+32 -47
+1 -1
tools/perf/Documentation/perf-script.txt
··· 130 130 -F:: 131 131 --fields:: 132 132 Comma separated list of fields to print. Options are: 133 - comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff, 133 + comm, tid, pid, time, cpu, event, trace, ip, sym, dso, dsoff, addr, symoff, 134 134 srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, 135 135 brstackinsn, brstackinsnlen, brstackoff, callindent, insn, insnlen, synth, 136 136 phys_addr, metric, misc, srccode, ipc, data_page_size, code_page_size, ins_lat,
+24 -36
tools/perf/builtin-script.c
··· 133 133 PERF_OUTPUT_VCPU = 1ULL << 38, 134 134 PERF_OUTPUT_CGROUP = 1ULL << 39, 135 135 PERF_OUTPUT_RETIRE_LAT = 1ULL << 40, 136 + PERF_OUTPUT_DSOFF = 1ULL << 41, 136 137 }; 137 138 138 139 struct perf_script { ··· 175 174 {.str = "ip", .field = PERF_OUTPUT_IP}, 176 175 {.str = "sym", .field = PERF_OUTPUT_SYM}, 177 176 {.str = "dso", .field = PERF_OUTPUT_DSO}, 177 + {.str = "dsoff", .field = PERF_OUTPUT_DSOFF}, 178 178 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 179 179 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET}, 180 180 {.str = "srcline", .field = PERF_OUTPUT_SRCLINE}, ··· 576 574 if (PRINT_FIELD(DSO)) 577 575 output[type].print_ip_opts |= EVSEL__PRINT_DSO; 578 576 577 + if (PRINT_FIELD(DSOFF)) 578 + output[type].print_ip_opts |= EVSEL__PRINT_DSOFF; 579 + 579 580 if (PRINT_FIELD(SYMOFFSET)) 580 581 output[type].print_ip_opts |= EVSEL__PRINT_SYMOFFSET; 581 582 ··· 631 626 632 627 if (evsel == NULL) 633 628 continue; 629 + 630 + /* 'dsoff' implys 'dso' field */ 631 + if (output[j].fields & PERF_OUTPUT_DSOFF) 632 + output[j].fields |= PERF_OUTPUT_DSO; 634 633 635 634 set_print_ip_opts(&evsel->core.attr); 636 635 tod |= output[j].fields & PERF_OUTPUT_TOD; ··· 938 929 } 939 930 940 931 printed += fprintf(fp, " 0x%"PRIx64, from); 941 - if (PRINT_FIELD(DSO)) { 942 - printed += fprintf(fp, "("); 943 - printed += map__fprintf_dsoname(alf.map, fp); 944 - printed += fprintf(fp, ")"); 945 - } 932 + if (PRINT_FIELD(DSO)) 933 + printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 946 934 947 935 printed += fprintf(fp, "/0x%"PRIx64, to); 948 - if (PRINT_FIELD(DSO)) { 949 - printed += fprintf(fp, "("); 950 - printed += map__fprintf_dsoname(alt.map, fp); 951 - printed += fprintf(fp, ")"); 952 - } 936 + if (PRINT_FIELD(DSO)) 937 + printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 953 938 954 939 printed += print_bstack_flags(fp, entries + i); 955 940 } ··· 975 972 thread__find_symbol_fb(thread, sample->cpumode, to, &alt); 976 973 977 974 printed += symbol__fprintf_symname_offs(alf.sym, &alf, fp); 978 - if (PRINT_FIELD(DSO)) { 979 - printed += fprintf(fp, "("); 980 - printed += map__fprintf_dsoname(alf.map, fp); 981 - printed += fprintf(fp, ")"); 982 - } 975 + if (PRINT_FIELD(DSO)) 976 + printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 983 977 printed += fprintf(fp, "%c", '/'); 984 978 printed += symbol__fprintf_symname_offs(alt.sym, &alt, fp); 985 - if (PRINT_FIELD(DSO)) { 986 - printed += fprintf(fp, "("); 987 - printed += map__fprintf_dsoname(alt.map, fp); 988 - printed += fprintf(fp, ")"); 989 - } 979 + if (PRINT_FIELD(DSO)) 980 + printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 990 981 printed += print_bstack_flags(fp, entries + i); 991 982 } 992 983 ··· 1016 1019 to = map__dso_map_ip(alt.map, to); 1017 1020 1018 1021 printed += fprintf(fp, " 0x%"PRIx64, from); 1019 - if (PRINT_FIELD(DSO)) { 1020 - printed += fprintf(fp, "("); 1021 - printed += map__fprintf_dsoname(alf.map, fp); 1022 - printed += fprintf(fp, ")"); 1023 - } 1022 + if (PRINT_FIELD(DSO)) 1023 + printed += map__fprintf_dsoname_dsoff(alf.map, PRINT_FIELD(DSOFF), alf.addr, fp); 1024 1024 printed += fprintf(fp, "/0x%"PRIx64, to); 1025 - if (PRINT_FIELD(DSO)) { 1026 - printed += fprintf(fp, "("); 1027 - printed += map__fprintf_dsoname(alt.map, fp); 1028 - printed += fprintf(fp, ")"); 1029 - } 1025 + if (PRINT_FIELD(DSO)) 1026 + printed += map__fprintf_dsoname_dsoff(alt.map, PRINT_FIELD(DSOFF), alt.addr, fp); 1030 1027 printed += print_bstack_flags(fp, entries + i); 1031 1028 } 1032 1029 ··· 1384 1393 printed += symbol__fprintf_symname(al.sym, fp); 1385 1394 } 1386 1395 1387 - if (PRINT_FIELD(DSO)) { 1388 - printed += fprintf(fp, " ("); 1389 - printed += map__fprintf_dsoname(al.map, fp); 1390 - printed += fprintf(fp, ")"); 1391 - } 1396 + if (PRINT_FIELD(DSO)) 1397 + printed += map__fprintf_dsoname_dsoff(al.map, PRINT_FIELD(DSOFF), al.addr, fp); 1392 1398 out: 1393 1399 return printed; 1394 1400 } ··· 3871 3883 "comma separated output fields prepend with 'type:'. " 3872 3884 "+field to add and -field to remove." 3873 3885 "Valid types: hw,sw,trace,raw,synth. " 3874 - "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 3886 + "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,dsoff" 3875 3887 "addr,symoff,srcline,period,iregs,uregs,brstack," 3876 3888 "brstacksym,flags,data_src,weight,bpf-output,brstackinsn," 3877 3889 "brstackinsnlen,brstackoff,callindent,insn,insnlen,synth,"
+6 -10
tools/perf/util/evsel_fprintf.c
··· 116 116 int print_ip = print_opts & EVSEL__PRINT_IP; 117 117 int print_sym = print_opts & EVSEL__PRINT_SYM; 118 118 int print_dso = print_opts & EVSEL__PRINT_DSO; 119 + int print_dsoff = print_opts & EVSEL__PRINT_DSOFF; 119 120 int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; 120 121 int print_oneline = print_opts & EVSEL__PRINT_ONELINE; 121 122 int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; ··· 172 171 } 173 172 } 174 173 175 - if (print_dso && (!sym || !sym->inlined)) { 176 - printed += fprintf(fp, " ("); 177 - printed += map__fprintf_dsoname(map, fp); 178 - printed += fprintf(fp, ")"); 179 - } 174 + if (print_dso && (!sym || !sym->inlined)) 175 + printed += map__fprintf_dsoname_dsoff(map, print_dsoff, addr, fp); 180 176 181 177 if (print_srcline) 182 178 printed += map__fprintf_srcline(map, addr, "\n ", fp); ··· 207 209 int print_ip = print_opts & EVSEL__PRINT_IP; 208 210 int print_sym = print_opts & EVSEL__PRINT_SYM; 209 211 int print_dso = print_opts & EVSEL__PRINT_DSO; 212 + int print_dsoff = print_opts & EVSEL__PRINT_DSOFF; 210 213 int print_symoffset = print_opts & EVSEL__PRINT_SYMOFFSET; 211 214 int print_srcline = print_opts & EVSEL__PRINT_SRCLINE; 212 215 int print_unknown_as_addr = print_opts & EVSEL__PRINT_UNKNOWN_AS_ADDR; ··· 233 234 } 234 235 } 235 236 236 - if (print_dso) { 237 - printed += fprintf(fp, " ("); 238 - printed += map__fprintf_dsoname(al->map, fp); 239 - printed += fprintf(fp, ")"); 240 - } 237 + if (print_dso) 238 + printed += map__fprintf_dsoname_dsoff(al->map, print_dsoff, al->addr, fp); 241 239 242 240 if (print_srcline) 243 241 printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
+1
tools/perf/util/evsel_fprintf.h
··· 26 26 #define EVSEL__PRINT_UNKNOWN_AS_ADDR (1<<6) 27 27 #define EVSEL__PRINT_CALLCHAIN_ARROW (1<<7) 28 28 #define EVSEL__PRINT_SKIP_IGNORED (1<<8) 29 + #define EVSEL__PRINT_DSOFF (1<<9) 29 30 30 31 struct addr_location; 31 32 struct perf_event_attr;