diff options
| -rw-r--r-- | tools/perf/Documentation/perf-script.txt | 10 | ||||
| -rw-r--r-- | tools/perf/builtin-script.c | 31 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 50 | ||||
| -rw-r--r-- | tools/perf/util/session.h | 5 |
4 files changed, 58 insertions, 38 deletions
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 86c87e214b11..67a4e5cbc880 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt | |||
| @@ -115,10 +115,10 @@ 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, sym. Field | 118 | comm, tid, pid, time, cpu, event, trace, ip, sym. Field |
| 119 | list can be prepended with the type, trace, sw or hw, | 119 | 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,sym and -f trace:time,cpu,trace | 121 | e.g., -f sw:comm,tid,time,ip,sym and -f trace:time,cpu,trace |
| 122 | 122 | ||
| 123 | perf script -f <fields> | 123 | perf script -f <fields> |
| 124 | 124 | ||
| @@ -132,17 +132,17 @@ OPTIONS | |||
| 132 | The arguments are processed in the order received. A later usage can | 132 | The arguments are processed in the order received. A later usage can |
| 133 | reset a prior request. e.g.: | 133 | reset a prior request. e.g.: |
| 134 | 134 | ||
| 135 | -f trace: -f comm,tid,time,sym | 135 | -f trace: -f comm,tid,time,ip,sym |
| 136 | 136 | ||
| 137 | The first -f suppresses trace events (field list is ""), but then the | 137 | The first -f suppresses trace events (field list is ""), but then the |
| 138 | second invocation sets the fields to comm,tid,time,sym. In this case a | 138 | second invocation sets the fields to comm,tid,time,ip,sym. In this case a |
| 139 | warning is given to the user: | 139 | warning is given to the user: |
| 140 | 140 | ||
| 141 | "Overriding previous field request for all events." | 141 | "Overriding previous field request for all events." |
| 142 | 142 | ||
| 143 | Alternativey, consider the order: | 143 | Alternativey, consider the order: |
| 144 | 144 | ||
| 145 | -f comm,tid,time,sym -f trace: | 145 | -f comm,tid,time,ip,sym -f trace: |
| 146 | 146 | ||
| 147 | The first -f sets the fields for all events and the second -f | 147 | The first -f sets the fields for all events and the second -f |
| 148 | suppresses trace events. The user is given a warning message about | 148 | suppresses trace events. The user is given a warning message about |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 22747de7234b..0852db2ea155 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -30,7 +30,8 @@ enum perf_output_field { | |||
| 30 | PERF_OUTPUT_CPU = 1U << 4, | 30 | PERF_OUTPUT_CPU = 1U << 4, |
| 31 | PERF_OUTPUT_EVNAME = 1U << 5, | 31 | PERF_OUTPUT_EVNAME = 1U << 5, |
| 32 | PERF_OUTPUT_TRACE = 1U << 6, | 32 | PERF_OUTPUT_TRACE = 1U << 6, |
| 33 | PERF_OUTPUT_SYM = 1U << 7, | 33 | PERF_OUTPUT_IP = 1U << 7, |
| 34 | PERF_OUTPUT_SYM = 1U << 8, | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | struct output_option { | 37 | struct output_option { |
| @@ -44,6 +45,7 @@ struct output_option { | |||
| 44 | {.str = "cpu", .field = PERF_OUTPUT_CPU}, | 45 | {.str = "cpu", .field = PERF_OUTPUT_CPU}, |
| 45 | {.str = "event", .field = PERF_OUTPUT_EVNAME}, | 46 | {.str = "event", .field = PERF_OUTPUT_EVNAME}, |
| 46 | {.str = "trace", .field = PERF_OUTPUT_TRACE}, | 47 | {.str = "trace", .field = PERF_OUTPUT_TRACE}, |
| 48 | {.str = "ip", .field = PERF_OUTPUT_IP}, | ||
| 47 | {.str = "sym", .field = PERF_OUTPUT_SYM}, | 49 | {.str = "sym", .field = PERF_OUTPUT_SYM}, |
| 48 | }; | 50 | }; |
| 49 | 51 | ||
| @@ -60,7 +62,8 @@ static struct { | |||
| 60 | 62 | ||
| 61 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 63 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 62 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 64 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 63 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, | 65 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 66 | PERF_OUTPUT_SYM, | ||
| 64 | 67 | ||
| 65 | .invalid_fields = PERF_OUTPUT_TRACE, | 68 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 66 | }, | 69 | }, |
| @@ -70,7 +73,8 @@ static struct { | |||
| 70 | 73 | ||
| 71 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 74 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 72 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 75 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 73 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, | 76 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 77 | PERF_OUTPUT_SYM, | ||
| 74 | 78 | ||
| 75 | .invalid_fields = PERF_OUTPUT_TRACE, | 79 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 76 | }, | 80 | }, |
| @@ -88,7 +92,8 @@ static struct { | |||
| 88 | 92 | ||
| 89 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | | 93 | .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | |
| 90 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | | 94 | PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | |
| 91 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, | 95 | PERF_OUTPUT_EVNAME | PERF_OUTPUT_IP | |
| 96 | PERF_OUTPUT_SYM, | ||
| 92 | 97 | ||
| 93 | .invalid_fields = PERF_OUTPUT_TRACE, | 98 | .invalid_fields = PERF_OUTPUT_TRACE, |
| 94 | }, | 99 | }, |
| @@ -157,15 +162,20 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel, | |||
| 157 | !perf_session__has_traces(session, "record -R")) | 162 | !perf_session__has_traces(session, "record -R")) |
| 158 | return -EINVAL; | 163 | return -EINVAL; |
| 159 | 164 | ||
| 160 | if (PRINT_FIELD(SYM)) { | 165 | if (PRINT_FIELD(IP)) { |
| 161 | if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", | 166 | if (perf_event_attr__check_stype(attr, PERF_SAMPLE_IP, "IP", |
| 162 | PERF_OUTPUT_SYM)) | 167 | PERF_OUTPUT_IP)) |
| 163 | return -EINVAL; | 168 | return -EINVAL; |
| 164 | 169 | ||
| 165 | if (!no_callchain && | 170 | if (!no_callchain && |
| 166 | !(attr->sample_type & PERF_SAMPLE_CALLCHAIN)) | 171 | !(attr->sample_type & PERF_SAMPLE_CALLCHAIN)) |
| 167 | symbol_conf.use_callchain = false; | 172 | symbol_conf.use_callchain = false; |
| 168 | } | 173 | } |
| 174 | if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP)) { | ||
| 175 | pr_err("Display of symbols requested but IP is not selected.\n" | ||
| 176 | "No addresses to convert to symbols.\n"); | ||
| 177 | return -EINVAL; | ||
| 178 | } | ||
| 169 | 179 | ||
| 170 | if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && | 180 | if ((PRINT_FIELD(PID) || PRINT_FIELD(TID)) && |
| 171 | perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", | 181 | perf_event_attr__check_stype(attr, PERF_SAMPLE_TID, "TID", |
| @@ -230,7 +240,7 @@ static void print_sample_start(struct perf_sample *sample, | |||
| 230 | if (PRINT_FIELD(COMM)) { | 240 | if (PRINT_FIELD(COMM)) { |
| 231 | if (latency_format) | 241 | if (latency_format) |
| 232 | printf("%8.8s ", thread->comm); | 242 | printf("%8.8s ", thread->comm); |
| 233 | else if (PRINT_FIELD(SYM) && symbol_conf.use_callchain) | 243 | else if (PRINT_FIELD(IP) && symbol_conf.use_callchain) |
| 234 | printf("%s ", thread->comm); | 244 | printf("%s ", thread->comm); |
| 235 | else | 245 | else |
| 236 | printf("%16s ", thread->comm); | 246 | printf("%16s ", thread->comm); |
| @@ -288,12 +298,13 @@ static void process_event(union perf_event *event __unused, | |||
| 288 | print_trace_event(sample->cpu, sample->raw_data, | 298 | print_trace_event(sample->cpu, sample->raw_data, |
| 289 | sample->raw_size); | 299 | sample->raw_size); |
| 290 | 300 | ||
| 291 | if (PRINT_FIELD(SYM)) { | 301 | if (PRINT_FIELD(IP)) { |
| 292 | if (!symbol_conf.use_callchain) | 302 | if (!symbol_conf.use_callchain) |
| 293 | printf(" "); | 303 | printf(" "); |
| 294 | else | 304 | else |
| 295 | printf("\n"); | 305 | printf("\n"); |
| 296 | perf_session__print_symbols(event, sample, session); | 306 | perf_session__print_ip(event, sample, session, |
| 307 | PRINT_FIELD(SYM)); | ||
| 297 | } | 308 | } |
| 298 | 309 | ||
| 299 | printf("\n"); | 310 | printf("\n"); |
| @@ -985,7 +996,7 @@ static const struct option options[] = { | |||
| 985 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", | 996 | OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", |
| 986 | "Look for files with symbols relative to this directory"), | 997 | "Look for files with symbols relative to this directory"), |
| 987 | OPT_CALLBACK('f', "fields", NULL, "str", | 998 | OPT_CALLBACK('f', "fields", NULL, "str", |
| 988 | "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym", | 999 | "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,ip,sym", |
| 989 | parse_output_fields), | 1000 | parse_output_fields), |
| 990 | 1001 | ||
| 991 | OPT_END() | 1002 | OPT_END() |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f5a8fbdd3f76..ad33650cdd41 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -1202,9 +1202,10 @@ struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | |||
| 1202 | return NULL; | 1202 | return NULL; |
| 1203 | } | 1203 | } |
| 1204 | 1204 | ||
| 1205 | void perf_session__print_symbols(union perf_event *event, | 1205 | void perf_session__print_ip(union perf_event *event, |
