diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8d2fe1fd31e96d..a0475f57fa21f4 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -3937,6 +3937,8 @@ int cmd_script(int argc, const char **argv) OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", "only display events for these comms"), + OPT_STRING('X', "no-comms", &symbol_conf.no_comm_list_str, "comm[,comm...]", + "exclude these comms"), OPT_STRING(0, "pid", &symbol_conf.pid_list_str, "pid[,pid...]", "only consider symbols in these pids"), OPT_STRING(0, "tid", &symbol_conf.tid_list_str, "tid[,tid...]", @@ -4000,6 +4002,8 @@ int cmd_script(int argc, const char **argv) "file", "file saving guest os /proc/modules"), OPT_BOOLEAN(0, "guest-code", &symbol_conf.guest_code, "Guest code can be found in hypervisor process"), + OPT_BOOLEAN(0, "no-addr2line-errors", &symbol_conf.disable_add2line_warn, + "disable addr2line errors"), OPT_BOOLEAN('\0', "stitch-lbr", &script.stitch_lbr, "Enable LBR callgraph stitching approach"), OPTS_EVSWITCH(&script.evswitch), diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 0888b7163b7cc2..c4c3aca36785c4 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1396,6 +1396,7 @@ static void hist_entry__check_and_remove_filter(struct hist_entry *he, switch (type) { case HIST_FILTER__THREAD: if (symbol_conf.comm_list == NULL && + symbol_conf.no_comm_list == NULL && symbol_conf.pid_list == NULL && symbol_conf.tid_list == NULL) return; diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 82cc74b9358e0d..1f494b9bebf063 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -2711,6 +2711,9 @@ int symbol__init(struct perf_env *env) symbol_conf.bt_stop_list_str, "symbol") < 0) goto out_free_sym_list; + if (setup_list(&symbol_conf.no_comm_list, + symbol_conf.no_comm_list_str, "no_comm") < 0) + goto out_free_bt_stop_list; /* * A path to symbols of "/" is identical to "" * reset here for simplicity. @@ -2728,6 +2731,8 @@ int symbol__init(struct perf_env *env) symbol_conf.initialized = true; return 0; +out_free_bt_stop_list: + strlist__delete(symbol_conf.bt_stop_list); out_free_sym_list: strlist__delete(symbol_conf.sym_list); intlist__delete(symbol_conf.addr_list); @@ -2750,11 +2755,12 @@ void symbol__exit(void) strlist__delete(symbol_conf.sym_list); strlist__delete(symbol_conf.dso_list); strlist__delete(symbol_conf.comm_list); + strlist__delete(symbol_conf.no_comm_list); intlist__delete(symbol_conf.tid_list); intlist__delete(symbol_conf.pid_list); intlist__delete(symbol_conf.addr_list); vmlinux_path__exit(); - symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; + symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = symbol_conf.no_comm_list = NULL; symbol_conf.bt_stop_list = NULL; symbol_conf.initialized = false; } diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index 0b589570d1d095..9a3f16b9de648d 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -54,6 +54,7 @@ struct symbol_conf { const char *guestmount; const char *dso_list_str, *comm_list_str, + *no_comm_list_str, *pid_list_str, *tid_list_str, *sym_list_str, @@ -63,6 +64,7 @@ struct symbol_conf { unsigned long time_quantum; struct strlist *dso_list, *comm_list, + *no_comm_list, *sym_list, *dso_from_list, *dso_to_list, diff --git a/tools/perf/util/symbol_fprintf.c b/tools/perf/util/symbol_fprintf.c index e2165c898bd214..9888e21febdc24 100644 --- a/tools/perf/util/symbol_fprintf.c +++ b/tools/perf/util/symbol_fprintf.c @@ -2,6 +2,7 @@ #include #include #include +#include #include "dso.h" #include "map.h" @@ -17,6 +18,12 @@ size_t symbol__fprintf(struct symbol *sym, FILE *fp) sym->name); } +static int __is_srcline(const char *str) +{ + return str && *str && str[0] != '?' && + isdigit((unsigned char)str[strlen(str) - 1]); +} + size_t __symbol__fprintf_sym_offs(const struct symbol *sym, const struct addr_location *al, bool unknown_as_addr, bool print_offsets, @@ -30,20 +37,28 @@ size_t __symbol__fprintf_sym_offs(const struct symbol *sym, if (al && (print_offsets || print_line)) { if (print_line) { int ret = 0; - char *srcline = map__srcline(al->map, al->addr, NULL); - if (srcline != SRCLINE_UNKNOWN) { + char *srcline = get_srcline( + map__dso(al->map), + map__rip_2objdump(al->map, al->addr), + NULL, false, false, al->addr); + if (__is_srcline(srcline)) { ret = fprintf(fp, "+%s", srcline); if (ret > 0) length += (size_t)ret; } zfree_srcline(&srcline); - srcline = map__srcline(al->map, sym->start, NULL); - if (srcline != SRCLINE_UNKNOWN) { - ret = fprintf(fp, "+%s", srcline); - if (ret > 0) - length += (size_t)ret; + if (ret > 0) { + srcline = get_srcline( + map__dso(al->map), + map__rip_2objdump(al->map, sym->start), + NULL, false, false, sym->start); + if (__is_srcline(srcline)) { + ret = fprintf(fp, "+%s", srcline); + if (ret > 0) + length += (size_t)ret; + } + zfree_srcline(&srcline); } - zfree_srcline(&srcline); } else { if (al->addr < sym->end) offset = al->addr - sym->start; diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 3593fcea597f7e..3714405e79e340 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -322,6 +322,11 @@ static inline bool thread__is_filtered(struct thread *thread) return true; } + if (symbol_conf.no_comm_list && + strlist__has_entry(symbol_conf.no_comm_list, thread__comm_str(thread))) { + return true; + } + if (symbol_conf.pid_list && !intlist__has_entry(symbol_conf.pid_list, thread__pid(thread))) { return true;