diff options
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r-- | tools/perf/builtin-report.c | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 860f1eeeea7d..cfc655d40bb7 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -34,6 +34,8 @@ | |||
34 | static char const *input_name = "perf.data"; | 34 | static char const *input_name = "perf.data"; |
35 | 35 | ||
36 | static int force; | 36 | static int force; |
37 | static bool hide_unresolved; | ||
38 | static bool dont_use_callchains; | ||
37 | 39 | ||
38 | static int show_threads; | 40 | static int show_threads; |
39 | static struct perf_read_values show_threads_values; | 41 | static struct perf_read_values show_threads_values; |
@@ -91,11 +93,8 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
91 | 93 | ||
92 | event__parse_sample(event, session->sample_type, &data); | 94 | event__parse_sample(event, session->sample_type, &data); |
93 | 95 | ||
94 | dump_printf("(IP, %d): %d/%d: %p period: %Ld\n", | 96 | dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc, |
95 | event->header.misc, | 97 | data.pid, data.tid, data.ip, data.period); |
96 | data.pid, data.tid, | ||
97 | (void *)(long)data.ip, | ||
98 | (long long)data.period); | ||
99 | 98 | ||
100 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { | 99 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) { |
101 | unsigned int i; | 100 | unsigned int i; |
@@ -121,7 +120,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
121 | return -1; | 120 | return -1; |
122 | } | 121 | } |
123 | 122 | ||
124 | if (al.filtered) | 123 | if (al.filtered || (hide_unresolved && al.sym == NULL)) |
125 | return 0; | 124 | return 0; |
126 | 125 | ||
127 | if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { | 126 | if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) { |
@@ -156,14 +155,14 @@ static int process_read_event(event_t *event, struct perf_session *session __use | |||
156 | return 0; | 155 | return 0; |
157 | } | 156 | } |
158 | 157 | ||
159 | static int sample_type_check(struct perf_session *session) | 158 | static int perf_session__setup_sample_type(struct perf_session *self) |
160 | { | 159 | { |
161 | if (!(session->sample_type & PERF_SAMPLE_CALLCHAIN)) { | 160 | if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { |
162 | if (sort__has_parent) { | 161 | if (sort__has_parent) { |
163 | fprintf(stderr, "selected --sort parent, but no" | 162 | fprintf(stderr, "selected --sort parent, but no" |
164 | " callchain data. Did you call" | 163 | " callchain data. Did you call" |
165 | " perf record without -g?\n"); | 164 | " perf record without -g?\n"); |
166 | return -1; | 165 | return -EINVAL; |
167 | } | 166 | } |
168 | if (symbol_conf.use_callchain) { | 167 | if (symbol_conf.use_callchain) { |
169 | fprintf(stderr, "selected -g but no callchain data." | 168 | fprintf(stderr, "selected -g but no callchain data." |
@@ -171,12 +170,13 @@ static int sample_type_check(struct perf_session *session) | |||
171 | " -g?\n"); | 170 | " -g?\n"); |
172 | return -1; | 171 | return -1; |
173 | } | 172 | } |
174 | } else if (callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) { | 173 | } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE && |
174 | !symbol_conf.use_callchain) { | ||
175 | symbol_conf.use_callchain = true; | 175 | symbol_conf.use_callchain = true; |
176 | if (register_callchain_param(&callchain_param) < 0) { | 176 | if (register_callchain_param(&callchain_param) < 0) { |
177 | fprintf(stderr, "Can't register callchain" | 177 | fprintf(stderr, "Can't register callchain" |
178 | " params\n"); | 178 | " params\n"); |
179 | return -1; | 179 | return -EINVAL; |
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
@@ -184,20 +184,18 @@ static int sample_type_check(struct perf_session *session) | |||
184 | } | 184 | } |
185 | 185 | ||
186 | static struct perf_event_ops event_ops = { | 186 | static struct perf_event_ops event_ops = { |
187 | .process_sample_event = process_sample_event, | 187 | .sample = process_sample_event, |
188 | .process_mmap_event = event__process_mmap, | 188 | .mmap = event__process_mmap, |
189 | .process_comm_event = event__process_comm, | 189 | .comm = event__process_comm, |
190 | .process_exit_event = event__process_task, | 190 | .exit = event__process_task, |
191 | .process_fork_event = event__process_task, | 191 | .fork = event__process_task, |
192 | .process_lost_event = event__process_lost, | 192 | .lost = event__process_lost, |
193 | .process_read_event = process_read_event, | 193 | .read = process_read_event, |
194 | .sample_type_check = sample_type_check, | ||
195 | }; | 194 | }; |
196 | 195 | ||
197 | |||
198 | static int __cmd_report(void) | 196 | static int __cmd_report(void) |
199 | { | 197 | { |
200 | int ret; | 198 | int ret = -EINVAL; |
201 | struct perf_session *session; | 199 | struct perf_session *session; |
202 | 200 | ||
203 | session = perf_session__new(input_name, O_RDONLY, force); | 201 | session = perf_session__new(input_name, O_RDONLY, force); |
@@ -207,6 +205,10 @@ static int __cmd_report(void) | |||
207 | if (show_threads) | 205 | if (show_threads) |
208 | perf_read_values_init(&show_threads_values); | 206 | perf_read_values_init(&show_threads_values); |
209 | 207 | ||
208 | ret = perf_session__setup_sample_type(session); | ||
209 | if (ret) | ||
210 | goto out_delete; | ||
211 | |||
210 | ret = perf_session__process_events(session, &event_ops); | 212 | ret = perf_session__process_events(session, &event_ops); |
211 | if (ret) | 213 | if (ret) |
212 | goto out_delete; | 214 | goto out_delete; |
@@ -243,11 +245,19 @@ out_delete: | |||
243 | 245 | ||
244 | static int | 246 | static int |
245 | parse_callchain_opt(const struct option *opt __used, const char *arg, | 247 | parse_callchain_opt(const struct option *opt __used, const char *arg, |
246 | int unset __used) | 248 | int unset) |
247 | { | 249 | { |
248 | char *tok; | 250 | char *tok; |
249 | char *endptr; | 251 | char *endptr; |
250 | 252 | ||
253 | /* | ||
254 | * --no-call-graph | ||
255 | */ | ||
256 | if (unset) { | ||
257 | dont_use_callchains = true; | ||
258 | return 0; | ||
259 | } | ||
260 | |||
251 | symbol_conf.use_callchain = true; | 261 | symbol_conf.use_callchain = true; |
252 | 262 | ||
253 | if (!arg) | 263 | if (!arg) |
@@ -319,7 +329,7 @@ static const struct option options[] = { | |||
319 | "pretty printing style key: normal raw"), | 329 | "pretty printing style key: normal raw"), |
320 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", | 330 | OPT_STRING('s', "sort", &sort_order, "key[,key2...]", |
321 | "sort by key(s): pid, comm, dso, symbol, parent"), | 331 | "sort by key(s): pid, comm, dso, symbol, parent"), |
322 | OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths, | 332 | OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths, |
323 | "Don't shorten the pathnames taking into account the cwd"), | 333 | "Don't shorten the pathnames taking into account the cwd"), |
324 | OPT_STRING('p', "parent", &parent_pattern, "regex", | 334 | OPT_STRING('p', "parent", &parent_pattern, "regex", |
325 | "regex filter to identify parent, see: '--sort parent'"), | 335 | "regex filter to identify parent, see: '--sort parent'"), |
@@ -340,6 +350,8 @@ static const struct option options[] = { | |||
340 | OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", | 350 | OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", |
341 | "separator for columns, no spaces will be added between " | 351 | "separator for columns, no spaces will be added between " |
342 | "columns '.' is reserved."), | 352 | "columns '.' is reserved."), |
353 | OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved, | ||
354 | "Only display entries resolved to a symbol"), | ||
343 | OPT_END() | 355 | OPT_END() |
344 | }; | 356 | }; |
345 | 357 | ||