aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-report.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-report.c')
-rw-r--r--tools/perf/builtin-report.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index db10c0e8ecae..cfc655d40bb7 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -34,6 +34,8 @@
34static char const *input_name = "perf.data"; 34static char const *input_name = "perf.data";
35 35
36static int force; 36static int force;
37static bool hide_unresolved;
38static bool dont_use_callchains;
37 39
38static int show_threads; 40static int show_threads;
39static struct perf_read_values show_threads_values; 41static 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
159static int sample_type_check(struct perf_session *session) 158static 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
186static struct perf_event_ops event_ops = { 186static 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
198static int __cmd_report(void) 196static 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
244static int 246static int
245parse_callchain_opt(const struct option *opt __used, const char *arg, 247parse_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)
@@ -269,7 +279,7 @@ parse_callchain_opt(const struct option *opt __used, const char *arg,
269 279
270 else if (!strncmp(tok, "none", strlen(arg))) { 280 else if (!strncmp(tok, "none", strlen(arg))) {
271 callchain_param.mode = CHAIN_NONE; 281 callchain_param.mode = CHAIN_NONE;
272 symbol_conf.use_callchain = true; 282 symbol_conf.use_callchain = false;
273 283
274 return 0; 284 return 0;
275 } 285 }
@@ -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