Loading tools/perf/builtin-annotate.c +45 −16 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self) printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); } static void annotate_sym(struct hist_entry *he) static int hist_entry__tty_annotate(struct hist_entry *he) { struct map *map = he->ms.map; struct dso *dso = map->dso; Loading @@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he) struct objdump_line *pos, *n; if (hist_entry__annotate(he, &head) < 0) return; return -1; if (full_paths) d_filename = filename; Loading Loading @@ -317,32 +317,61 @@ static void annotate_sym(struct hist_entry *he) if (print_line) free_source_line(he, len); return 0; } static void hists__find_annotations(struct hists *self) { struct rb_node *nd; struct rb_node *first = rb_first(&self->entries), *nd = first; int key = KEY_RIGHT; for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { while (nd) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; if (he->ms.sym == NULL) continue; if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) goto find_next; priv = symbol__priv(he->ms.sym); if (priv->hist == NULL) if (priv->hist == NULL) { find_next: if (key == KEY_LEFT) nd = rb_prev(nd); else nd = rb_next(nd); continue; } annotate_sym(he); if (use_browser) { key = hist_entry__tui_annotate(he); if (is_exit_key(key)) break; switch (key) { case KEY_RIGHT: case '\t': nd = rb_next(nd); break; case KEY_LEFT: if (nd == first) continue; nd = rb_prev(nd); default: break; } } else { hist_entry__tty_annotate(he); nd = rb_next(nd); /* * Since we have a hist_entry per IP for the same symbol, free * he->ms.sym->hist to signal we already processed this symbol. * Since we have a hist_entry per IP for the same * symbol, free he->ms.sym->hist to signal we already * processed this symbol. */ free(priv->hist); priv->hist = NULL; } } } static struct perf_event_ops event_ops = { .sample = process_sample_event, Loading Loading @@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, annotate_usage, 0); setup_browser(); symbol_conf.priv_size = sizeof(struct sym_priv); symbol_conf.try_vmlinux_path = true; Loading @@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) sym_hist_filter = argv[0]; } setup_pager(); if (field_sep && *field_sep == '.') { pr_err("'.' is the only non valid --field-separator argument\n"); return -1; Loading tools/perf/util/hist.c +5 −8 Original line number Diff line number Diff line Loading @@ -992,14 +992,14 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) char *filename = dso__build_id_filename(dso, NULL, 0); char command[PATH_MAX * 2]; FILE *file; int err = -1; int err = 0; u64 len; if (filename == NULL) { if (dso->has_build_id) { pr_err("Can't annotate %s: not enough memory\n", sym->name); return -1; return -ENOMEM; } /* * If we don't have build-ids, well, lets hope that this Loading @@ -1009,14 +1009,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) } if (dso->origin == DSO__ORIG_KERNEL) { if (dso->annotate_warned) { err = 0; if (dso->annotate_warned) goto out_free_filename; } err = -ENOENT; dso->annotate_warned = 1; pr_err("Can't annotate %s: No vmlinux file was found in the " "path:\n", sym->name); vmlinux_path__fprintf(stderr); "path\n", sym->name); goto out_free_filename; } Loading Loading @@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) break; pclose(file); err = 0; out_free_filename: if (dso->has_build_id) free(filename); Loading tools/perf/util/hist.h +10 −0 Original line number Diff line number Diff line Loading @@ -102,8 +102,18 @@ static inline int hists__browse(struct hists *self __used, { return 0; } static inline int hist_entry__tui_annotate(struct hist_entry *self __used) { return 0; } #define KEY_LEFT -1 #define KEY_RIGHT -2 #else #include <newt.h> int hists__browse(struct hists *self, const char *helpline, const char *input_name); int hist_entry__tui_annotate(struct hist_entry *self); #define KEY_LEFT NEWT_KEY_LEFT #define KEY_RIGHT NEWT_KEY_RIGHT #endif #endif /* __PERF_HIST_H */ tools/perf/util/newt.c +42 −19 Original line number Diff line number Diff line Loading @@ -235,6 +235,15 @@ static bool dialog_yesno(const char *msg) return newtWinChoice(NULL, yes, no, (char *)msg) == 1; } static void ui__error_window(const char *fmt, ...) { va_list ap; va_start(ap, fmt); newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); va_end(ap); } #define HE_COLORSET_TOP 50 #define HE_COLORSET_MEDIUM 51 #define HE_COLORSET_NORMAL 52 Loading Loading @@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, newtFormAddHotKey(self->form, ' '); newtFormAddHotKey(self->form, NEWT_KEY_HOME); newtFormAddHotKey(self->form, NEWT_KEY_END); newtFormAddHotKey(self->form, NEWT_KEY_TAB); newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); if (ui_browser__refresh_entries(self) < 0) return -1; Loading @@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, if (es->reason != NEWT_EXIT_HOTKEY) break; if (is_exit_key(es->u.key)) return es->u.key; switch (es->u.key) { case NEWT_KEY_DOWN: if (self->index == self->nr_entries - 1) Loading Loading @@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title, } } break; case NEWT_KEY_ESCAPE: case NEWT_KEY_RIGHT: case NEWT_KEY_LEFT: case CTRL('c'): case 'Q': case 'q': return 0; case NEWT_KEY_TAB: return es->u.key; default: continue; } Loading Loading @@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self, return ret; } static void hist_entry__annotate_browser(struct hist_entry *self) int hist_entry__tui_annotate(struct hist_entry *self) { struct ui_browser browser; struct newtExitStruct es; struct objdump_line *pos, *n; LIST_HEAD(head); int ret; if (self->ms.sym == NULL) return; return -1; if (hist_entry__annotate(self, &head) < 0) return; if (self->ms.map->dso->annotate_warned) return -1; if (hist_entry__annotate(self, &head) < 0) { ui__error_window(browser__last_msg); return -1; } ui_helpline__push("Press <- or ESC to exit"); Loading @@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self) } browser.width += 18; /* Percentage */ ui_browser__run(&browser, self->ms.sym->name, &es); ret = ui_browser__run(&browser, self->ms.sym->name, &es); newtFormDestroy(browser.form); newtPopWindow(); list_for_each_entry_safe(pos, n, &head, node) { Loading @@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self) objdump_line__free(pos); } ui_helpline__pop(); return ret; } static const void *newt__symbol_tree_get_current(newtComponent self) Loading Loading @@ -914,6 +932,9 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na switch (toupper(es.u.key)) { case 'A': if (browser->selection->map == NULL && browser->selection->map->dso->annotate_warned) continue; goto do_annotate; case 'D': goto zoom_dso; Loading @@ -932,14 +953,14 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na continue; default:; } if (toupper(es.u.key) == 'Q' || es.u.key == CTRL('c')) break; if (is_exit_key(es.u.key)) { if (es.u.key == NEWT_KEY_ESCAPE) { if (dialog_yesno("Do you really want to exit?")) break; else continue; } else break; } if (es.u.key == NEWT_KEY_LEFT) { Loading @@ -957,6 +978,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na } if (browser->selection->sym != NULL && !browser->selection->map->dso->annotate_warned && asprintf(&options[nr_options], "Annotate %s", browser->selection->sym->name) > 0) annotate = nr_options++; Loading Loading @@ -991,6 +1013,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na struct hist_entry *he; do_annotate: if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { browser->selection->map->dso->annotate_warned = 1; ui_helpline__puts("No vmlinux file found, can't " "annotate with just a " "kallsyms file"); Loading @@ -1001,7 +1024,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na if (he == NULL) continue; hist_entry__annotate_browser(he); hist_entry__tui_annotate(he); } else if (choice == zoom_dso) { zoom_dso: if (dso_filter) { Loading Loading @@ -1069,7 +1092,7 @@ void setup_browser(void) { struct newtPercentTreeColors *c = &defaultPercentTreeColors; if (!isatty(1) || !use_browser) { if (!isatty(1) || !use_browser || dump_trace) { setup_pager(); return; } Loading tools/perf/util/util.h +14 −1 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ #include <inttypes.h> #include "../../../include/linux/magic.h" #include "types.h" #include <sys/ttydefaults.h> #ifndef NO_ICONV #include <iconv.h> Loading Loading @@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat); bool strlazymatch(const char *str, const char *pat); unsigned long convert_unit(unsigned long value, char *unit); #ifndef ESC #define ESC 27 #endif static inline bool is_exit_key(int key) { char up; if (key == CTRL('c') || key == ESC) return true; up = toupper(key); return up == 'Q'; } #define _STR(x) #x #define STR(x) _STR(x) Loading Loading
tools/perf/builtin-annotate.c +45 −16 Original line number Diff line number Diff line Loading @@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self) printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); } static void annotate_sym(struct hist_entry *he) static int hist_entry__tty_annotate(struct hist_entry *he) { struct map *map = he->ms.map; struct dso *dso = map->dso; Loading @@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he) struct objdump_line *pos, *n; if (hist_entry__annotate(he, &head) < 0) return; return -1; if (full_paths) d_filename = filename; Loading Loading @@ -317,32 +317,61 @@ static void annotate_sym(struct hist_entry *he) if (print_line) free_source_line(he, len); return 0; } static void hists__find_annotations(struct hists *self) { struct rb_node *nd; struct rb_node *first = rb_first(&self->entries), *nd = first; int key = KEY_RIGHT; for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { while (nd) { struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); struct sym_priv *priv; if (he->ms.sym == NULL) continue; if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned) goto find_next; priv = symbol__priv(he->ms.sym); if (priv->hist == NULL) if (priv->hist == NULL) { find_next: if (key == KEY_LEFT) nd = rb_prev(nd); else nd = rb_next(nd); continue; } annotate_sym(he); if (use_browser) { key = hist_entry__tui_annotate(he); if (is_exit_key(key)) break; switch (key) { case KEY_RIGHT: case '\t': nd = rb_next(nd); break; case KEY_LEFT: if (nd == first) continue; nd = rb_prev(nd); default: break; } } else { hist_entry__tty_annotate(he); nd = rb_next(nd); /* * Since we have a hist_entry per IP for the same symbol, free * he->ms.sym->hist to signal we already processed this symbol. * Since we have a hist_entry per IP for the same * symbol, free he->ms.sym->hist to signal we already * processed this symbol. */ free(priv->hist); priv->hist = NULL; } } } static struct perf_event_ops event_ops = { .sample = process_sample_event, Loading Loading @@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) { argc = parse_options(argc, argv, options, annotate_usage, 0); setup_browser(); symbol_conf.priv_size = sizeof(struct sym_priv); symbol_conf.try_vmlinux_path = true; Loading @@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) sym_hist_filter = argv[0]; } setup_pager(); if (field_sep && *field_sep == '.') { pr_err("'.' is the only non valid --field-separator argument\n"); return -1; Loading
tools/perf/util/hist.c +5 −8 Original line number Diff line number Diff line Loading @@ -992,14 +992,14 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) char *filename = dso__build_id_filename(dso, NULL, 0); char command[PATH_MAX * 2]; FILE *file; int err = -1; int err = 0; u64 len; if (filename == NULL) { if (dso->has_build_id) { pr_err("Can't annotate %s: not enough memory\n", sym->name); return -1; return -ENOMEM; } /* * If we don't have build-ids, well, lets hope that this Loading @@ -1009,14 +1009,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) } if (dso->origin == DSO__ORIG_KERNEL) { if (dso->annotate_warned) { err = 0; if (dso->annotate_warned) goto out_free_filename; } err = -ENOENT; dso->annotate_warned = 1; pr_err("Can't annotate %s: No vmlinux file was found in the " "path:\n", sym->name); vmlinux_path__fprintf(stderr); "path\n", sym->name); goto out_free_filename; } Loading Loading @@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) break; pclose(file); err = 0; out_free_filename: if (dso->has_build_id) free(filename); Loading
tools/perf/util/hist.h +10 −0 Original line number Diff line number Diff line Loading @@ -102,8 +102,18 @@ static inline int hists__browse(struct hists *self __used, { return 0; } static inline int hist_entry__tui_annotate(struct hist_entry *self __used) { return 0; } #define KEY_LEFT -1 #define KEY_RIGHT -2 #else #include <newt.h> int hists__browse(struct hists *self, const char *helpline, const char *input_name); int hist_entry__tui_annotate(struct hist_entry *self); #define KEY_LEFT NEWT_KEY_LEFT #define KEY_RIGHT NEWT_KEY_RIGHT #endif #endif /* __PERF_HIST_H */
tools/perf/util/newt.c +42 −19 Original line number Diff line number Diff line Loading @@ -235,6 +235,15 @@ static bool dialog_yesno(const char *msg) return newtWinChoice(NULL, yes, no, (char *)msg) == 1; } static void ui__error_window(const char *fmt, ...) { va_list ap; va_start(ap, fmt); newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap); va_end(ap); } #define HE_COLORSET_TOP 50 #define HE_COLORSET_MEDIUM 51 #define HE_COLORSET_NORMAL 52 Loading Loading @@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, newtFormAddHotKey(self->form, ' '); newtFormAddHotKey(self->form, NEWT_KEY_HOME); newtFormAddHotKey(self->form, NEWT_KEY_END); newtFormAddHotKey(self->form, NEWT_KEY_TAB); newtFormAddHotKey(self->form, NEWT_KEY_RIGHT); if (ui_browser__refresh_entries(self) < 0) return -1; Loading @@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title, if (es->reason != NEWT_EXIT_HOTKEY) break; if (is_exit_key(es->u.key)) return es->u.key; switch (es->u.key) { case NEWT_KEY_DOWN: if (self->index == self->nr_entries - 1) Loading Loading @@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title, } } break; case NEWT_KEY_ESCAPE: case NEWT_KEY_RIGHT: case NEWT_KEY_LEFT: case CTRL('c'): case 'Q': case 'q': return 0; case NEWT_KEY_TAB: return es->u.key; default: continue; } Loading Loading @@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self, return ret; } static void hist_entry__annotate_browser(struct hist_entry *self) int hist_entry__tui_annotate(struct hist_entry *self) { struct ui_browser browser; struct newtExitStruct es; struct objdump_line *pos, *n; LIST_HEAD(head); int ret; if (self->ms.sym == NULL) return; return -1; if (hist_entry__annotate(self, &head) < 0) return; if (self->ms.map->dso->annotate_warned) return -1; if (hist_entry__annotate(self, &head) < 0) { ui__error_window(browser__last_msg); return -1; } ui_helpline__push("Press <- or ESC to exit"); Loading @@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self) } browser.width += 18; /* Percentage */ ui_browser__run(&browser, self->ms.sym->name, &es); ret = ui_browser__run(&browser, self->ms.sym->name, &es); newtFormDestroy(browser.form); newtPopWindow(); list_for_each_entry_safe(pos, n, &head, node) { Loading @@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self) objdump_line__free(pos); } ui_helpline__pop(); return ret; } static const void *newt__symbol_tree_get_current(newtComponent self) Loading Loading @@ -914,6 +932,9 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na switch (toupper(es.u.key)) { case 'A': if (browser->selection->map == NULL && browser->selection->map->dso->annotate_warned) continue; goto do_annotate; case 'D': goto zoom_dso; Loading @@ -932,14 +953,14 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na continue; default:; } if (toupper(es.u.key) == 'Q' || es.u.key == CTRL('c')) break; if (is_exit_key(es.u.key)) { if (es.u.key == NEWT_KEY_ESCAPE) { if (dialog_yesno("Do you really want to exit?")) break; else continue; } else break; } if (es.u.key == NEWT_KEY_LEFT) { Loading @@ -957,6 +978,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na } if (browser->selection->sym != NULL && !browser->selection->map->dso->annotate_warned && asprintf(&options[nr_options], "Annotate %s", browser->selection->sym->name) > 0) annotate = nr_options++; Loading Loading @@ -991,6 +1013,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na struct hist_entry *he; do_annotate: if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { browser->selection->map->dso->annotate_warned = 1; ui_helpline__puts("No vmlinux file found, can't " "annotate with just a " "kallsyms file"); Loading @@ -1001,7 +1024,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na if (he == NULL) continue; hist_entry__annotate_browser(he); hist_entry__tui_annotate(he); } else if (choice == zoom_dso) { zoom_dso: if (dso_filter) { Loading Loading @@ -1069,7 +1092,7 @@ void setup_browser(void) { struct newtPercentTreeColors *c = &defaultPercentTreeColors; if (!isatty(1) || !use_browser) { if (!isatty(1) || !use_browser || dump_trace) { setup_pager(); return; } Loading
tools/perf/util/util.h +14 −1 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ #include <inttypes.h> #include "../../../include/linux/magic.h" #include "types.h" #include <sys/ttydefaults.h> #ifndef NO_ICONV #include <iconv.h> Loading Loading @@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat); bool strlazymatch(const char *str, const char *pat); unsigned long convert_unit(unsigned long value, char *unit); #ifndef ESC #define ESC 27 #endif static inline bool is_exit_key(int key) { char up; if (key == CTRL('c') || key == ESC) return true; up = toupper(key); return up == 'Q'; } #define _STR(x) #x #define STR(x) _STR(x) Loading