return -1;
}
+ if (al.filtered)
+ return 0;
+
event__parse_sample(event, session->sample_type, &data);
if (al.sym && perf_session__add_hist_entry(session, &al, data.period)) {
printed = fprintf(fp, "%4lu %5.5s ", pos, displacement);
if (show_percent) {
- double old_percent = (old_count * 100) / pair_session->events_stats.total,
- new_percent = (self->count * 100) / session->events_stats.total;
- double diff = old_percent - new_percent;
+ double old_percent = 0, new_percent = 0, diff;
+
+ if (pair_session->events_stats.total > 0)
+ old_percent = (old_count * 100) / pair_session->events_stats.total;
+ if (session->events_stats.total > 0)
+ new_percent = (self->count * 100) / session->events_stats.total;
+ diff = old_percent - new_percent;
if (verbose)
printed += fprintf(fp, " %3.2f%% %3.2f%%", old_percent, new_percent);
"Don't shorten the pathnames taking into account the cwd"),
OPT_BOOLEAN('P', "full-paths", &event_ops.full_paths,
"Don't shorten the pathnames taking into account the cwd"),
+ OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
+ "only consider symbols in these dsos"),
+ OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
+ "only consider symbols in these comms"),
+ OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
+ "only consider these symbols"),
OPT_END()
};
if (total_samples)
ret = percent_color_fprintf(fp,
- field_sep ? "%.2f" : " %6.2f%%",
+ symbol_conf.field_sep ? "%.2f" : " %6.2f%%",
(self->count * 100.0) / total_samples);
else
- ret = fprintf(fp, field_sep ? "%lld" : "%12lld ", self->count);
+ ret = fprintf(fp, symbol_conf.field_sep ? "%lld" : "%12lld ", self->count);
if (show_nr_samples) {
- if (field_sep)
- fprintf(fp, "%c%lld", *field_sep, self->count);
+ if (symbol_conf.field_sep)
+ fprintf(fp, "%c%lld", *symbol_conf.field_sep, self->count);
else
fprintf(fp, "%11lld", self->count);
}
if (se->elide)
continue;
- fprintf(fp, "%s", field_sep ?: " ");
+ fprintf(fp, "%s", symbol_conf.field_sep ?: " ");
ret += se->print(fp, self, se->width ? *se->width : 0);
}
return ret;
}
-/*
- *
- */
-
-static void dso__calc_col_width(struct dso *self)
-{
- if (!symbol_conf.col_width_list_str && !field_sep &&
- (!symbol_conf.dso_list ||
- strlist__has_entry(symbol_conf.dso_list, self->name))) {
- unsigned int slen = strlen(self->name);
- if (slen > dsos__col_width)
- dsos__col_width = slen;
- }
-
- self->slen_calculated = 1;
-}
-
static void thread__comm_adjust(struct thread *self)
{
char *comm = self->comm;
- if (!symbol_conf.col_width_list_str && !field_sep &&
+ if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
(!symbol_conf.comm_list ||
strlist__has_entry(symbol_conf.comm_list, comm))) {
unsigned int slen = strlen(comm);
fprintf(fp, "# Overhead");
if (show_nr_samples) {
- if (field_sep)
- fprintf(fp, "%cSamples", *field_sep);
+ if (symbol_conf.field_sep)
+ fprintf(fp, "%cSamples", *symbol_conf.field_sep);
else
fputs(" Samples ", fp);
}
list_for_each_entry(se, &hist_entry__sort_list, list) {
if (se->elide)
continue;
- if (field_sep) {
- fprintf(fp, "%c%s", *field_sep, se->header);
+ if (symbol_conf.field_sep) {
+ fprintf(fp, "%c%s", *symbol_conf.field_sep, se->header);
continue;
}
width = strlen(se->header);
}
fprintf(fp, "\n");
- if (field_sep)
+ if (symbol_conf.field_sep)
goto print_entries;
fprintf(fp, "# ........");
static int process_sample_event(event_t *event, struct perf_session *session)
{
- struct sample_data data;
- int cpumode;
+ struct sample_data data = { .period = 1, };
struct addr_location al;
- struct thread *thread;
-
- memset(&data, 0, sizeof(data));
- data.period = 1;
event__parse_sample(event, session->sample_type, &data);
}
}
- thread = perf_session__findnew(session, data.pid);
- if (thread == NULL) {
- pr_debug("problem processing %d event, skipping it.\n",
+ if (event__preprocess_sample(event, session, &al, NULL) < 0) {
+ fprintf(stderr, "problem processing %d event, skipping it.\n",
event->header.type);
return -1;
}
- dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
-
- if (symbol_conf.comm_list &&
- !strlist__has_entry(symbol_conf.comm_list, thread->comm))
- return 0;
-
- cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
-
- thread__find_addr_location(thread, session, cpumode,
- MAP__FUNCTION, data.ip, &al, NULL);
- /*
- * We have to do this here as we may have a dso with no symbol hit that
- * has a name longer than the ones with symbols sampled.
- */
- if (al.map && !sort_dso.elide && !al.map->dso->slen_calculated)
- dso__calc_col_width(al.map->dso);
-
- if (symbol_conf.dso_list &&
- (!al.map || !al.map->dso ||
- !(strlist__has_entry(symbol_conf.dso_list, al.map->dso->short_name) ||
- (al.map->dso->short_name != al.map->dso->long_name &&
- strlist__has_entry(symbol_conf.dso_list, al.map->dso->long_name)))))
- return 0;
-
- if (symbol_conf.sym_list && al.sym &&
- !strlist__has_entry(symbol_conf.sym_list, al.sym->name))
+ if (al.filtered)
return 0;
if (perf_session__add_hist_entry(session, &al, data.callchain, data.period)) {
OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
"width[,width...]",
"don't try to adjust column width, use these fixed values"),
- OPT_STRING('t', "field-separator", &field_sep, "separator",
+ OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
"separator for columns, no spaces will be added between "
"columns '.' is reserved."),
OPT_END()
sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
- if (field_sep && *field_sep == '.') {
- fputs("'.' is the only non valid --field-separator argument\n",
- stderr);
- exit(129);
- }
-
return __cmd_report();
}
#include "event.h"
#include "debug.h"
#include "session.h"
+#include "sort.h"
#include "string.h"
+#include "strlist.h"
#include "thread.h"
static pid_t event__synthesize_comm(pid_t pid, int full,
}
}
+static void dso__calc_col_width(struct dso *self)
+{
+ if (!symbol_conf.col_width_list_str && !symbol_conf.field_sep &&
+ (!symbol_conf.dso_list ||
+ strlist__has_entry(symbol_conf.dso_list, self->name))) {
+ unsigned int slen = strlen(self->name);
+ if (slen > dsos__col_width)
+ dsos__col_width = slen;
+ }
+
+ self->slen_calculated = 1;
+}
+
int event__preprocess_sample(const event_t *self, struct perf_session *session,
struct addr_location *al, symbol_filter_t filter)
{
if (thread == NULL)
return -1;
+ if (symbol_conf.comm_list &&
+ !strlist__has_entry(symbol_conf.comm_list, thread->comm))
+ goto out_filtered;
+
dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
thread__find_addr_location(thread, session, cpumode, MAP__FUNCTION,
dump_printf(" ...... dso: %s\n",
al->map ? al->map->dso->long_name :
al->level == 'H' ? "[hypervisor]" : "<not found>");
+ /*
+ * We have to do this here as we may have a dso with no symbol hit that
+ * has a name longer than the ones with symbols sampled.
+ */
+ if (al->map && !sort_dso.elide && !al->map->dso->slen_calculated)
+ dso__calc_col_width(al->map->dso);
+
+ if (symbol_conf.dso_list &&
+ (!al->map || !al->map->dso ||
+ !(strlist__has_entry(symbol_conf.dso_list, al->map->dso->short_name) ||
+ (al->map->dso->short_name != al->map->dso->long_name &&
+ strlist__has_entry(symbol_conf.dso_list, al->map->dso->long_name)))))
+ goto out_filtered;
+
+ if (symbol_conf.sym_list && al->sym &&
+ !strlist__has_entry(symbol_conf.sym_list, al->sym->name))
+ goto out_filtered;
+
+ al->filtered = false;
+ return 0;
+
+out_filtered:
+ al->filtered = true;
return 0;
}