aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorAkihiro Nagai <akihiro.nagai.hw@hitachi.com>2012-01-29 23:43:15 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-01-30 15:09:21 -0500
commita978f2ab4166a84c77d0f846f59690f2a892d058 (patch)
tree015a35d71132a28a53b729be99ab469ebb641a66 /tools/perf
parent9558259697b827106b464648e850e568e0b0c931 (diff)
perf script: Add the offset field specifier
Add the offset field specifier 'symoff' to show the offset from the symbols in the output of perf-script. We can get the more detailed address information. Output sample: ffffffff81467612 irq_return+0x0 => 301ec016b0 _start+0x0 ffffffff81467612 irq_return+0x0 => 301ec016b0 _start+0x0 301ec016b3 _start+0x3 => 301ec04b70 _dl_start+0x0 ffffffff81467612 irq_return+0x0 => 301ec04b70 _dl_start+0x0 ffffffff81467612 irq_return+0x0 => 301ec04b96 _dl_start+0x26 ffffffff81467612 irq_return+0x0 => 301ec04b9d _dl_start+0x2d 301ec04beb _dl_start+0x7b => 301ec04c0d _dl_start+0x9d 301ec04c11 _dl_start+0xa1 => 301ec04bf0 _dl_start+0x80 [snip] Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20120130044314.2384.67094.stgit@linux3 Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-script.txt2
-rw-r--r--tools/perf/builtin-script.c23
-rw-r--r--tools/perf/util/session.c8
-rw-r--r--tools/perf/util/session.h2
-rw-r--r--tools/perf/util/symbol.c24
-rw-r--r--tools/perf/util/symbol.h2
6 files changed, 46 insertions, 15 deletions
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 2f6cef43da25..228c7bb0f0dd 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,7 +115,7 @@ OPTIONS
115-f:: 115-f::
116--fields:: 116--fields::
117 Comma separated list of fields to print. Options are: 117 Comma separated list of fields to print. Options are:
118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr. 118 comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff.
119 Field list can be prepended with the type, trace, sw or hw, 119 Field list can be prepended with the type, trace, sw or hw,
120 to indicate to which event type the field list applies. 120 to indicate to which event type the field list applies.
121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace 121 e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 414d49ad83de..752d4018d06d 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -40,6 +40,7 @@ enum perf_output_field {
40 PERF_OUTPUT_SYM = 1U << 8, 40 PERF_OUTPUT_SYM = 1U << 8,
41 PERF_OUTPUT_DSO = 1U << 9, 41 PERF_OUTPUT_DSO = 1U << 9,
42 PERF_OUTPUT_ADDR = 1U << 10, 42 PERF_OUTPUT_ADDR = 1U << 10,
43 PERF_OUTPUT_SYMOFFSET = 1U << 11,
43}; 44};
44 45
45struct output_option { 46struct output_option {
@@ -57,6 +58,7 @@ struct output_option {
57 {.str = "sym", .field = PERF_OUTPUT_SYM}, 58 {.str = "sym", .field = PERF_OUTPUT_SYM},
58 {.str = "dso", .field = PERF_OUTPUT_DSO}, 59 {.str = "dso", .field = PERF_OUTPUT_DSO},
59 {.str = "addr", .field = PERF_OUTPUT_ADDR}, 60 {.str = "addr", .field = PERF_OUTPUT_ADDR},
61 {.str = "symoff", .field = PERF_OUTPUT_SYMOFFSET},
60}; 62};
61 63
62/* default set to maintain compatibility with current format */ 64/* default set to maintain compatibility with current format */
@@ -193,6 +195,11 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
193 "to symbols.\n"); 195 "to symbols.\n");
194 return -EINVAL; 196 return -EINVAL;
195 } 197 }
198 if (PRINT_FIELD(SYMOFFSET) && !PRINT_FIELD(SYM)) {
199 pr_err("Display of offsets requested but symbol is not"
200 "selected.\n");
201 return -EINVAL;
202 }
196 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) { 203 if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
197 pr_err("Display of DSO requested but neither sample IP nor " 204 pr_err("Display of DSO requested but neither sample IP nor "
198 "sample address\nis selected. Hence, no addresses to convert " 205 "sample address\nis selected. Hence, no addresses to convert "
@@ -353,7 +360,10 @@ static void print_sample_addr(union perf_event *event,
353 360
354 if (PRINT_FIELD(SYM)) { 361 if (PRINT_FIELD(SYM)) {
355 printf(" "); 362 printf(" ");
356 symbol__fprintf_symname(al.sym, stdout); 363 if (PRINT_FIELD(SYMOFFSET))
364 symbol__fprintf_symname_offs(al.sym, &al, stdout);
365 else
366 symbol__fprintf_symname(al.sym, stdout);
357 } 367 }
358 368
359 if (PRINT_FIELD(DSO)) { 369 if (PRINT_FIELD(DSO)) {
@@ -378,7 +388,8 @@ static void print_sample_bts(union perf_event *event,
378 else 388 else
379 printf("\n"); 389 printf("\n");
380 perf_event__print_ip(event, sample, machine, evsel, 390 perf_event__print_ip(event, sample, machine, evsel,
381 PRINT_FIELD(SYM), PRINT_FIELD(DSO)); 391 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
392 PRINT_FIELD(SYMOFFSET));
382 } 393 }
383 394
384 printf(" => "); 395 printf(" => ");
@@ -421,7 +432,8 @@ static void process_event(union perf_event *event __unused,
421 else 432 else
422 printf("\n"); 433 printf("\n");
423 perf_event__print_ip(event, sample, machine, evsel, 434 perf_event__print_ip(event, sample, machine, evsel,
424 PRINT_FIELD(SYM), PRINT_FIELD(DSO)); 435 PRINT_FIELD(SYM), PRINT_FIELD(DSO),
436 PRINT_FIELD(SYMOFFSET));
425 } 437 }
426 438
427 printf("\n"); 439 printf("\n");
@@ -1131,7 +1143,10 @@ static const struct option options[] = {
1131 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 1143 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
1132 "Look for files with symbols relative to this directory"), 1144 "Look for files with symbols relative to this directory"),
1133 OPT_CALLBACK('f', "fields", NULL, "str", 1145 OPT_CALLBACK('f', "fields", NULL, "str",
1134 "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", 1146 "comma separated output fields prepend with 'type:'. "
1147 "Valid types: hw,sw,trace,raw. "
1148 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
1149 "addr,symoff",
1135 parse_output_fields), 1150 parse_output_fields),
1136 OPT_BOOLEAN('a', "all-cpus", &system_wide, 1151 OPT_BOOLEAN('a', "all-cpus", &system_wide,
1137 "system-wide collection from all CPUs"), 1152 "system-wide collection from all CPUs"),
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index e5334a976536..552c1c50eea1 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1293,7 +1293,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
1293 1293
1294void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, 1294void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1295 struct machine *machine, struct perf_evsel *evsel, 1295 struct machine *machine, struct perf_evsel *evsel,
1296 int print_sym, int print_dso) 1296 int print_sym, int print_dso, int print_symoffset)
1297{ 1297{
1298 struct addr_location al; 1298 struct addr_location al;
1299 struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; 1299 struct callchain_cursor *cursor = &evsel->hists.callchain_cursor;
@@ -1340,7 +1340,11 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
1340 printf("%16" PRIx64, sample->ip); 1340 printf("%16" PRIx64, sample->ip);
1341 if (print_sym) { 1341 if (print_sym) {
1342 printf(" "); 1342 printf(" ");
1343 symbol__fprintf_symname(al.sym, stdout); 1343 if (print_symoffset)
1344 symbol__fprintf_symname_offs(al.sym, &al,
1345 stdout);
1346 else
1347 symbol__fprintf_symname(al.sym, stdout);
1344 } 1348 }
1345 1349
1346 if (print_dso) { 1350 if (print_dso) {
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 37bc38381fb6..c8d90178e7de 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -147,7 +147,7 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
147 147
148void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, 148void perf_event__print_ip(union perf_event *event, struct perf_sample *sample,
149 struct machine *machine, struct perf_evsel *evsel, 149 struct machine *machine, struct perf_evsel *evsel,
150 int print_sym, int print_dso); 150 int print_sym, int print_dso, int print_symoffset);
151 151
152int perf_session__cpu_bitmap(struct perf_session *session, 152int perf_session__cpu_bitmap(struct perf_session *session,
153 const char *cpu_list, unsigned long *cpu_bitmap); 153 const char *cpu_list, unsigned long *cpu_bitmap);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index b580fa82911a..fc6e12fe4b44 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -263,16 +263,26 @@ static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
263 sym->name); 263 sym->name);
264} 264}
265 265
266size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp) 266size_t symbol__fprintf_symname_offs(const struct symbol *sym,
267 const struct addr_location *al, FILE *fp)
267{ 268{
268 const char *symname; 269 unsigned long offset;
270 size_t length;
269 271
270 if (sym && sym->name) 272 if (sym && sym->name) {
271 symname = sym->name; 273 length = fprintf(fp, "%s", sym->name);
272 else 274 if (al) {
273 symname = "[unknown]"; 275 offset = al->addr - sym->start;
276 length += fprintf(fp, "+0x%lx", offset);
277 }
278 return length;
279 } else
280 return fprintf(fp, "[unknown]");
281}
274 282
275 return fprintf(fp, "%s", symname); 283size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp)
284{
285 return symbol__fprintf_symname_offs(sym, NULL, fp);
276} 286}
277 287
278void dso__set_long_name(struct dso *dso, char *name) 288void dso__set_long_name(struct dso *dso, char *name)
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index d349c7a00b04..ba909c9970e2 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -241,6 +241,8 @@ void machines__destroy_guest_kernel_maps(struct rb_root *machines);
241 241
242int symbol__init(void); 242int symbol__init(void);
243void symbol__exit(void); 243void symbol__exit(void);
244size_t symbol__fprintf_symname_offs(const struct symbol *sym,
245 const struct addr_location *al, FILE *fp);
244size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp); 246size_t symbol__fprintf_symname(const struct symbol *sym, FILE *fp);
245bool symbol_type__is_a(char symbol_type, enum map_type map_type); 247bool symbol_type__is_a(char symbol_type, enum map_type map_type);
246 248