perf report: Fix --no-call-chain option handling
[safe/jmp/linux-2.6] / tools / perf / builtin-report.c
index e50a6b1..80d691a 100644 (file)
@@ -34,6 +34,8 @@
 static char            const *input_name = "perf.data";
 
 static int             force;
+static bool            hide_unresolved;
+static bool            dont_use_callchains;
 
 static int             show_threads;
 static struct perf_read_values show_threads_values;
@@ -121,7 +123,7 @@ static int process_sample_event(event_t *event, struct perf_session *session)
                return -1;
        }
 
-       if (al.filtered)
+       if (al.filtered || (hide_unresolved && al.sym == NULL))
                return 0;
 
        if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
@@ -156,14 +158,14 @@ static int process_read_event(event_t *event, struct perf_session *session __use
        return 0;
 }
 
-static int sample_type_check(struct perf_session *session)
+static int perf_session__setup_sample_type(struct perf_session *self)
 {
-       if (!(session->sample_type & PERF_SAMPLE_CALLCHAIN)) {
+       if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
                if (sort__has_parent) {
                        fprintf(stderr, "selected --sort parent, but no"
                                        " callchain data. Did you call"
                                        " perf record without -g?\n");
-                       return -1;
+                       return -EINVAL;
                }
                if (symbol_conf.use_callchain) {
                        fprintf(stderr, "selected -g but no callchain data."
@@ -171,12 +173,13 @@ static int sample_type_check(struct perf_session *session)
                                        " -g?\n");
                        return -1;
                }
-       } else if (callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) {
+       } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE &&
+                  !symbol_conf.use_callchain) {
                        symbol_conf.use_callchain = true;
                        if (register_callchain_param(&callchain_param) < 0) {
                                fprintf(stderr, "Can't register callchain"
                                                " params\n");
-                               return -1;
+                               return -EINVAL;
                        }
        }
 
@@ -184,20 +187,18 @@ static int sample_type_check(struct perf_session *session)
 }
 
 static struct perf_event_ops event_ops = {
-       .process_sample_event   = process_sample_event,
-       .process_mmap_event     = event__process_mmap,
-       .process_comm_event     = event__process_comm,
-       .process_exit_event     = event__process_task,
-       .process_fork_event     = event__process_task,
-       .process_lost_event     = event__process_lost,
-       .process_read_event     = process_read_event,
-       .sample_type_check      = sample_type_check,
+       .sample = process_sample_event,
+       .mmap   = event__process_mmap,
+       .comm   = event__process_comm,
+       .exit   = event__process_task,
+       .fork   = event__process_task,
+       .lost   = event__process_lost,
+       .read   = process_read_event,
 };
 
-
 static int __cmd_report(void)
 {
-       int ret;
+       int ret = -EINVAL;
        struct perf_session *session;
 
        session = perf_session__new(input_name, O_RDONLY, force);
@@ -207,6 +208,10 @@ static int __cmd_report(void)
        if (show_threads)
                perf_read_values_init(&show_threads_values);
 
+       ret = perf_session__setup_sample_type(session);
+       if (ret)
+               goto out_delete;
+
        ret = perf_session__process_events(session, &event_ops);
        if (ret)
                goto out_delete;
@@ -224,7 +229,7 @@ static int __cmd_report(void)
 
        perf_session__collapse_resort(session);
        perf_session__output_resort(session, session->events_stats.total);
-       fprintf(stdout, "# Samples: %ld\n#\n", session->events_stats.total);
+       fprintf(stdout, "# Samples: %Ld\n#\n", session->events_stats.total);
        perf_session__fprintf_hists(session, NULL, false, stdout);
        if (sort_order == default_sort_order &&
            parent_pattern == default_parent_pattern)
@@ -243,11 +248,19 @@ out_delete:
 
 static int
 parse_callchain_opt(const struct option *opt __used, const char *arg,
-                   int unset __used)
+                   int unset)
 {
        char *tok;
        char *endptr;
 
+       /*
+        * --no-call-graph
+        */
+       if (unset) {
+               dont_use_callchains = true;
+               return 0;
+       }
+
        symbol_conf.use_callchain = true;
 
        if (!arg)
@@ -294,8 +307,7 @@ setup:
        return 0;
 }
 
-//static const char * const report_usage[] = {
-const char * const report_usage[] = {
+static const char * const report_usage[] = {
        "perf report [<options>] <command>",
        NULL
 };
@@ -320,7 +332,7 @@ static const struct option options[] = {
                   "pretty printing style key: normal raw"),
        OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
                   "sort by key(s): pid, comm, dso, symbol, parent"),
-       OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths,
+       OPT_BOOLEAN('P', "full-paths", &symbol_conf.full_paths,
                    "Don't shorten the pathnames taking into account the cwd"),
        OPT_STRING('p', "parent", &parent_pattern, "regex",
                   "regex filter to identify parent, see: '--sort parent'"),
@@ -341,6 +353,8 @@ static const struct option options[] = {
        OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
                   "separator for columns, no spaces will be added between "
                   "columns '.' is reserved."),
+       OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
+                   "Only display entries resolved to a symbol"),
        OPT_END()
 };