提交 6a71e69f 编写于 作者: I Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core

Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:

 * Fix cleanup in case of kzalloc failure, from Daniel Baluta.

 * Limit unwind support to x86 archs, fix from Jiri Olsa.

 * Initial GTK+ annotate browser, from Namhyung Kim.

 * Fix build with bison 2.3 and older, from Vinson Lee.
Signed-off-by: NArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
...@@ -676,7 +676,7 @@ int __init init_hw_breakpoint(void) ...@@ -676,7 +676,7 @@ int __init init_hw_breakpoint(void)
err_alloc: err_alloc:
for_each_possible_cpu(err_cpu) { for_each_possible_cpu(err_cpu) {
for (i = 0; i < TYPE_MAX; i++) for (i = 0; i < TYPE_MAX; i++)
kfree(per_cpu(nr_task_bp_pinned[i], cpu)); kfree(per_cpu(nr_task_bp_pinned[i], err_cpu));
if (err_cpu == cpu) if (err_cpu == cpu)
break; break;
} }
......
...@@ -61,11 +61,13 @@ OPTIONS ...@@ -61,11 +61,13 @@ OPTIONS
--stdio:: Use the stdio interface. --stdio:: Use the stdio interface.
--tui:: Use the TUI interface Use of --tui requires a tty, if one is not --tui:: Use the TUI interface. Use of --tui requires a tty, if one is not
present, as when piping to other commands, the stdio interface is present, as when piping to other commands, the stdio interface is
used. This interfaces starts by centering on the line with more used. This interfaces starts by centering on the line with more
samples, TAB/UNTAB cycles through the lines with more samples. samples, TAB/UNTAB cycles through the lines with more samples.
--gtk:: Use the GTK interface.
-C:: -C::
--cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can --cpu:: Only report samples for the list of CPUs provided. Multiple CPUs can
be provided as a comma-separated list with no space: 0,1. Ranges of be provided as a comma-separated list with no space: 0,1. Ranges of
...@@ -88,6 +90,9 @@ OPTIONS ...@@ -88,6 +90,9 @@ OPTIONS
--objdump=<path>:: --objdump=<path>::
Path to objdump binary. Path to objdump binary.
--skip-missing::
Skip symbols that cannot be annotated.
SEE ALSO SEE ALSO
-------- --------
linkperf:perf-record[1], linkperf:perf-report[1] linkperf:perf-record[1], linkperf:perf-report[1]
...@@ -27,6 +27,10 @@ OPTIONS ...@@ -27,6 +27,10 @@ OPTIONS
-M:: -M::
--missing=:: --missing=::
List missing build ids in the cache for the specified file. List missing build ids in the cache for the specified file.
-u::
--update::
Update specified file of the cache. It can be used to update kallsyms
kernel dso to vmlinux in order to support annotation.
-v:: -v::
--verbose:: --verbose::
Be more verbose. Be more verbose.
......
...@@ -296,13 +296,13 @@ $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-event ...@@ -296,13 +296,13 @@ $(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-event
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
$(OUTPUT)util/parse-events-bison.c: util/parse-events.y $(OUTPUT)util/parse-events-bison.c: util/parse-events.y
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c $(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c $(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
$(OUTPUT)util/pmu-bison.c: util/pmu.y $(OUTPUT)util/pmu-bison.c: util/pmu.y
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c $(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
$(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c $(OUTPUT)util/parse-events.o: $(OUTPUT)util/parse-events-flex.c $(OUTPUT)util/parse-events-bison.c
$(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c $(OUTPUT)util/pmu.o: $(OUTPUT)util/pmu-flex.c $(OUTPUT)util/pmu-bison.c
...@@ -581,6 +581,11 @@ else ...@@ -581,6 +581,11 @@ else
endif # SOURCE_LIBELF endif # SOURCE_LIBELF
endif # NO_LIBELF endif # NO_LIBELF
# There's only x86 (both 32 and 64) support for CFI unwind so far
ifneq ($(ARCH),x86)
NO_LIBUNWIND := 1
endif
ifndef NO_LIBUNWIND ifndef NO_LIBUNWIND
# for linking with debug library, run like: # for linking with debug library, run like:
# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/ # make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
...@@ -698,6 +703,7 @@ ifndef NO_GTK2 ...@@ -698,6 +703,7 @@ ifndef NO_GTK2
LIB_OBJS += $(OUTPUT)ui/gtk/util.o LIB_OBJS += $(OUTPUT)ui/gtk/util.o
LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
LIB_OBJS += $(OUTPUT)ui/gtk/progress.o LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
endif endif
endif endif
......
...@@ -34,9 +34,10 @@ ...@@ -34,9 +34,10 @@
struct perf_annotate { struct perf_annotate {
struct perf_tool tool; struct perf_tool tool;
bool force, use_tui, use_stdio; bool force, use_tui, use_stdio, use_gtk;
bool full_paths; bool full_paths;
bool print_line; bool print_line;
bool skip_missing;
const char *sym_hist_filter; const char *sym_hist_filter;
const char *cpu_list; const char *cpu_list;
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
...@@ -138,9 +139,22 @@ static void hists__find_annotations(struct hists *self, int evidx, ...@@ -138,9 +139,22 @@ static void hists__find_annotations(struct hists *self, int evidx,
continue; continue;
} }
if (use_browser > 0) { if (use_browser == 2) {
int ret;
ret = hist_entry__gtk_annotate(he, evidx, NULL);
if (!ret || !ann->skip_missing)
return;
/* skip missing symbols */
nd = rb_next(nd);
} else if (use_browser == 1) {
key = hist_entry__tui_annotate(he, evidx, NULL); key = hist_entry__tui_annotate(he, evidx, NULL);
switch (key) { switch (key) {
case -1:
if (!ann->skip_missing)
return;
/* fall through */
case K_RIGHT: case K_RIGHT:
next = rb_next(nd); next = rb_next(nd);
break; break;
...@@ -224,6 +238,10 @@ static int __cmd_annotate(struct perf_annotate *ann) ...@@ -224,6 +238,10 @@ static int __cmd_annotate(struct perf_annotate *ann)
ui__error("The %s file has no samples!\n", session->filename); ui__error("The %s file has no samples!\n", session->filename);
goto out_delete; goto out_delete;
} }
if (use_browser == 2)
perf_gtk__show_annotations();
out_delete: out_delete:
/* /*
* Speed up the exit process, for large files this can * Speed up the exit process, for large files this can
...@@ -270,6 +288,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -270,6 +288,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
"be more verbose (show symbol address, etc)"), "be more verbose (show symbol address, etc)"),
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
"dump raw trace in ASCII"), "dump raw trace in ASCII"),
OPT_BOOLEAN(0, "gtk", &annotate.use_gtk, "Use the GTK interface"),
OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"), OPT_BOOLEAN(0, "tui", &annotate.use_tui, "Use the TUI interface"),
OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"), OPT_BOOLEAN(0, "stdio", &annotate.use_stdio, "Use the stdio interface"),
OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
...@@ -280,6 +299,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -280,6 +299,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
"print matching source lines (may be slow)"), "print matching source lines (may be slow)"),
OPT_BOOLEAN('P', "full-paths", &annotate.full_paths, OPT_BOOLEAN('P', "full-paths", &annotate.full_paths,
"Don't shorten the displayed pathnames"), "Don't shorten the displayed pathnames"),
OPT_BOOLEAN(0, "skip-missing", &annotate.skip_missing,
"Skip symbols that cannot be annotated"),
OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"), OPT_STRING('C', "cpu", &annotate.cpu_list, "cpu", "list of cpus to profile"),
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"), "Look for files with symbols relative to this directory"),
...@@ -300,6 +321,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused) ...@@ -300,6 +321,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
use_browser = 0; use_browser = 0;
else if (annotate.use_tui) else if (annotate.use_tui)
use_browser = 1; use_browser = 1;
else if (annotate.use_gtk)
use_browser = 2;
setup_browser(true); setup_browser(true);
......
...@@ -93,6 +93,32 @@ static int build_id_cache__fprintf_missing(const char *filename, bool force, FIL ...@@ -93,6 +93,32 @@ static int build_id_cache__fprintf_missing(const char *filename, bool force, FIL
return 0; return 0;
} }
static int build_id_cache__update_file(const char *filename,
const char *debugdir)
{
u8 build_id[BUILD_ID_SIZE];
char sbuild_id[BUILD_ID_SIZE * 2 + 1];
int err;
if (filename__read_build_id(filename, &build_id, sizeof(build_id)) < 0) {
pr_debug("Couldn't read a build-id in %s\n", filename);
return -1;
}
build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
err = build_id_cache__remove_s(sbuild_id, debugdir);
if (!err) {
err = build_id_cache__add_s(sbuild_id, debugdir, filename,
false, false);
}
if (verbose)
pr_info("Updating %s %s: %s\n", sbuild_id, filename,
err ? "FAIL" : "Ok");
return err;
}
int cmd_buildid_cache(int argc, const char **argv, int cmd_buildid_cache(int argc, const char **argv,
const char *prefix __maybe_unused) const char *prefix __maybe_unused)
{ {
...@@ -103,7 +129,9 @@ int cmd_buildid_cache(int argc, const char **argv, ...@@ -103,7 +129,9 @@ int cmd_buildid_cache(int argc, const char **argv,
char debugdir[PATH_MAX]; char debugdir[PATH_MAX];
char const *add_name_list_str = NULL, char const *add_name_list_str = NULL,
*remove_name_list_str = NULL, *remove_name_list_str = NULL,
*missing_filename = NULL; *missing_filename = NULL,
*update_name_list_str = NULL;
const struct option buildid_cache_options[] = { const struct option buildid_cache_options[] = {
OPT_STRING('a', "add", &add_name_list_str, OPT_STRING('a', "add", &add_name_list_str,
"file list", "file(s) to add"), "file list", "file(s) to add"),
...@@ -112,6 +140,8 @@ int cmd_buildid_cache(int argc, const char **argv, ...@@ -112,6 +140,8 @@ int cmd_buildid_cache(int argc, const char **argv,
OPT_STRING('M', "missing", &missing_filename, "file", OPT_STRING('M', "missing", &missing_filename, "file",
"to find missing build ids in the cache"), "to find missing build ids in the cache"),
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
OPT_STRING('u', "update", &update_name_list_str, "file list",
"file(s) to update"),
OPT_INCR('v', "verbose", &verbose, "be more verbose"), OPT_INCR('v', "verbose", &verbose, "be more verbose"),
OPT_END() OPT_END()
}; };
...@@ -169,5 +199,23 @@ int cmd_buildid_cache(int argc, const char **argv, ...@@ -169,5 +199,23 @@ int cmd_buildid_cache(int argc, const char **argv,
if (missing_filename) if (missing_filename)
ret = build_id_cache__fprintf_missing(missing_filename, force, stdout); ret = build_id_cache__fprintf_missing(missing_filename, force, stdout);
if (update_name_list_str) {
list = strlist__new(true, update_name_list_str);
if (list) {
strlist__for_each(pos, list)
if (build_id_cache__update_file(pos->s, debugdir)) {
if (errno == ENOENT) {
pr_debug("%s wasn't in the cache\n",
pos->s);
continue;
}
pr_warning("Couldn't update %s: %s\n",
pos->s, strerror(errno));
}
strlist__delete(list);
}
}
return ret; return ret;
} }
#include "gtk.h"
#include "util/debug.h"
#include "util/annotate.h"
#include "ui/helpline.h"
enum {
ANN_COL__PERCENT,
ANN_COL__OFFSET,
ANN_COL__LINE,
MAX_ANN_COLS
};
static const char *const col_names[] = {
"Overhead",
"Offset",
"Line"
};
static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
struct disasm_line *dl, int evidx)
{
struct sym_hist *symhist;
double percent = 0.0;
const char *markup;
int ret = 0;
strcpy(buf, "");
if (dl->offset == (s64) -1)
return 0;
symhist = annotation__histogram(symbol__annotation(sym), evidx);
if (!symhist->addr[dl->offset])
return 0;
percent = 100.0 * symhist->addr[dl->offset] / symhist->sum;
markup = perf_gtk__get_percent_color(percent);
if (markup)
ret += scnprintf(buf, size, "%s", markup);
ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent);
if (markup)
ret += scnprintf(buf + ret, size - ret, "</span>");
return ret;
}
static int perf_gtk__get_offset(char *buf, size_t size, struct symbol *sym,
struct map *map, struct disasm_line *dl)
{
u64 start = map__rip_2objdump(map, sym->start);
strcpy(buf, "");
if (dl->offset == (s64) -1)
return 0;
return scnprintf(buf, size, "%"PRIx64, start + dl->offset);
}
static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl)
{
int ret = 0;
char *line = g_markup_escape_text(dl->line, -1);
const char *markup = "<span fgcolor='gray'>";
strcpy(buf, "");
if (!line)
return 0;
if (dl->offset != (s64) -1)
markup = NULL;
if (markup)
ret += scnprintf(buf, size, "%s", markup);
ret += scnprintf(buf + ret, size - ret, "%s", line);
if (markup)
ret += scnprintf(buf + ret, size - ret, "</span>");
g_free(line);
return ret;
}
static int perf_gtk__annotate_symbol(GtkWidget *window, struct symbol *sym,
struct map *map, int evidx,
struct hist_browser_timer *hbt __maybe_unused)
{
struct disasm_line *pos, *n;
struct annotation *notes;
GType col_types[MAX_ANN_COLS];
GtkCellRenderer *renderer;
GtkListStore *store;
GtkWidget *view;
int i;
char s[512];
notes = symbol__annotation(sym);
for (i = 0; i < MAX_ANN_COLS; i++) {
col_types[i] = G_TYPE_STRING;
}
store = gtk_list_store_newv(MAX_ANN_COLS, col_types);
view = gtk_tree_view_new();
renderer = gtk_cell_renderer_text_new();
for (i = 0; i < MAX_ANN_COLS; i++) {
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
-1, col_names[i], renderer, "markup",
i, NULL);
}
gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
g_object_unref(GTK_TREE_MODEL(store));
list_for_each_entry(pos, &notes->src->source, node) {
GtkTreeIter iter;
gtk_list_store_append(store, &iter);
if (perf_gtk__get_percent(s, sizeof(s), sym, pos, evidx))
gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
if (perf_gtk__get_offset(s, sizeof(s), sym, map, pos))
gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
if (perf_gtk__get_line(s, sizeof(s), pos))
gtk_list_store_set(store, &iter, ANN_COL__LINE, s, -1);
}
gtk_container_add(GTK_CONTAINER(window), view);
list_for_each_entry_safe(pos, n, &notes->src->source, node) {
list_del(&pos->node);
disasm_line__free(pos);
}
return 0;
}
int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
struct hist_browser_timer *hbt)
{
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *scrolled_window;
GtkWidget *tab_label;
if (map->dso->annotate_warned)
return -1;
if (symbol__annotate(sym, map, 0) < 0) {
ui__error("%s", ui_helpline__current);
return -1;
}
if (perf_gtk__is_active_context(pgctx)) {
window = pgctx->main_window;
notebook = pgctx->notebook;
} else {
GtkWidget *vbox;
GtkWidget *infobar;
GtkWidget *statbar;
signal(SIGSEGV, perf_gtk__signal);
signal(SIGFPE, perf_gtk__signal);
signal(SIGINT, perf_gtk__signal);
signal(SIGQUIT, perf_gtk__signal);
signal(SIGTERM, perf_gtk__signal);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "perf annotate");
g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
pgctx = perf_gtk__activate_context(window);
if (!pgctx)
return -1;
vbox = gtk_vbox_new(FALSE, 0);
notebook = gtk_notebook_new();
pgctx->notebook = notebook;
gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
infobar = perf_gtk__setup_info_bar();
if (infobar) {
gtk_box_pack_start(GTK_BOX(vbox), infobar,
FALSE, FALSE, 0);
}
statbar = perf_gtk__setup_statusbar();
gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
}
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
tab_label = gtk_label_new(sym->name);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
tab_label);
perf_gtk__annotate_symbol(scrolled_window, sym, map, evidx, hbt);
return 0;
}
void perf_gtk__show_annotations(void)
{
GtkWidget *window;
if (!perf_gtk__is_active_context(pgctx))
return;
window = pgctx->main_window;
gtk_widget_show_all(window);
perf_gtk__resize_window(window);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_main();
perf_gtk__deactivate_context(&pgctx);
}
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
struct perf_gtk_context { struct perf_gtk_context {
GtkWidget *main_window; GtkWidget *main_window;
GtkWidget *notebook;
#ifdef HAVE_GTK_INFO_BAR #ifdef HAVE_GTK_INFO_BAR
GtkWidget *info_bar; GtkWidget *info_bar;
......
...@@ -8,7 +8,7 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER; ...@@ -8,7 +8,7 @@ pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;
void setup_browser(bool fallback_to_pager) void setup_browser(bool fallback_to_pager)
{ {
if (!isatty(1) || dump_trace) if (use_browser < 2 && (!isatty(1) || dump_trace))
use_browser = 0; use_browser = 0;
/* default to TUI */ /* default to TUI */
......
...@@ -809,7 +809,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) ...@@ -809,7 +809,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize)
pr_err("Can't annotate %s:\n\n" pr_err("Can't annotate %s:\n\n"
"No vmlinux file%s\nwas found in the path.\n\n" "No vmlinux file%s\nwas found in the path.\n\n"
"Please use:\n\n" "Please use:\n\n"
" perf buildid-cache -av vmlinux\n\n" " perf buildid-cache -vu vmlinux\n\n"
"or:\n\n" "or:\n\n"
" --vmlinux vmlinux\n", " --vmlinux vmlinux\n",
sym->name, build_id_msg ?: ""); sym->name, build_id_msg ?: "");
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "types.h" #include "types.h"
#include "symbol.h" #include "symbol.h"
#include "hist.h" #include "hist.h"
#include "sort.h"
#include <linux/list.h> #include <linux/list.h>
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <pthread.h> #include <pthread.h>
...@@ -154,6 +155,29 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused, ...@@ -154,6 +155,29 @@ static inline int symbol__tui_annotate(struct symbol *sym __maybe_unused,
} }
#endif #endif
#ifdef GTK2_SUPPORT
int symbol__gtk_annotate(struct symbol *sym, struct map *map, int evidx,
struct hist_browser_timer *hbt);
static inline int hist_entry__gtk_annotate(struct hist_entry *he, int evidx,
struct hist_browser_timer *hbt)
{
return symbol__gtk_annotate(he->ms.sym, he->ms.map, evidx, hbt);
}
void perf_gtk__show_annotations(void);
#else
static inline int hist_entry__gtk_annotate(struct hist_entry *he __maybe_unused,
int evidx __maybe_unused,
struct hist_browser_timer *hbt
__maybe_unused)
{
return 0;
}
static inline void perf_gtk__show_annotations(void) {}
#endif
extern const char *disassembler_style; extern const char *disassembler_style;
#endif /* __PERF_ANNOTATE_H */ #endif /* __PERF_ANNOTATE_H */
%pure-parser %pure-parser
%name-prefix "parse_events_"
%parse-param {void *_data} %parse-param {void *_data}
%parse-param {void *scanner} %parse-param {void *scanner}
%lex-param {void* scanner} %lex-param {void* scanner}
......
%name-prefix "perf_pmu_"
%parse-param {struct list_head *format} %parse-param {struct list_head *format}
%parse-param {char *name} %parse-param {char *name}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册