forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf ui/gtk: Implement basic GTK2 annotation browser
Basic implementation of perf annotate on GTK2. Currently only shows first symbol. Add a new --gtk option to use it. Signed-off-by: Namhyung Kim <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Paul Mackerras <[email protected]> Cc: Pekka Enberg <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
- Loading branch information
Showing
6 changed files
with
218 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
#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__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]; | ||
|
||
if (map->dso->annotate_warned) | ||
return -1; | ||
|
||
if (symbol__annotate(sym, map, 0) < 0) { | ||
ui__error("%s", ui_helpline__current); | ||
return -1; | ||
} | ||
|
||
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, | ||
i == ANN_COL__PERCENT ? "markup" : "text", | ||
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, ¬es->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); | ||
gtk_list_store_set(store, &iter, ANN_COL__LINE, pos->line, -1); | ||
} | ||
|
||
gtk_container_add(GTK_CONTAINER(window), view); | ||
|
||
list_for_each_entry_safe(pos, n, ¬es->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 *vbox; | ||
GtkWidget *notebook; | ||
GtkWidget *infobar; | ||
GtkWidget *statbar; | ||
GtkWidget *window; | ||
GtkWidget *scrolled_window; | ||
GtkWidget *tab_label; | ||
|
||
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(); | ||
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); | ||
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); | ||
|
||
perf_gtk__annotate_symbol(scrolled_window, sym, map, evidx, hbt); | ||
|
||
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); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters