~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/ui/gtk/annotate.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include "gtk.h"
  3 #include "util/sort.h"
  4 #include "util/debug.h"
  5 #include "util/annotate.h"
  6 #include "util/evsel.h"
  7 #include "util/map.h"
  8 #include "util/dso.h"
  9 #include "util/symbol.h"
 10 #include "ui/helpline.h"
 11 #include <inttypes.h>
 12 #include <signal.h>
 13 
 14 enum {
 15         ANN_COL__PERCENT,
 16         ANN_COL__OFFSET,
 17         ANN_COL__LINE,
 18 
 19         MAX_ANN_COLS
 20 };
 21 
 22 static const char *const col_names[] = {
 23         "Overhead",
 24         "Offset",
 25         "Line"
 26 };
 27 
 28 static int perf_gtk__get_percent(char *buf, size_t size, struct symbol *sym,
 29                                  struct disasm_line *dl, int evidx)
 30 {
 31         struct annotation *notes;
 32         struct sym_hist *symhist;
 33         struct sym_hist_entry *entry;
 34         double percent = 0.0;
 35         const char *markup;
 36         int ret = 0;
 37         u64 nr_samples = 0;
 38 
 39         strcpy(buf, "");
 40 
 41         if (dl->al.offset == (s64) -1)
 42                 return 0;
 43 
 44         notes = symbol__annotation(sym);
 45         symhist = annotation__histogram(notes, evidx);
 46         entry = annotated_source__hist_entry(notes->src, evidx, dl->al.offset);
 47         if (entry)
 48                 nr_samples = entry->nr_samples;
 49 
 50         if (!symbol_conf.event_group && nr_samples == 0)
 51                 return 0;
 52 
 53         percent = 100.0 * nr_samples / symhist->nr_samples;
 54 
 55         markup = perf_gtk__get_percent_color(percent);
 56         if (markup)
 57                 ret += scnprintf(buf, size, "%s", markup);
 58         ret += scnprintf(buf + ret, size - ret, "%6.2f%%", percent);
 59         if (markup)
 60                 ret += scnprintf(buf + ret, size - ret, "</span>");
 61 
 62         return ret;
 63 }
 64 
 65 static int perf_gtk__get_offset(char *buf, size_t size, struct map_symbol *ms,
 66                                 struct disasm_line *dl)
 67 {
 68         u64 start = map__rip_2objdump(ms->map, ms->sym->start);
 69 
 70         strcpy(buf, "");
 71 
 72         if (dl->al.offset == (s64) -1)
 73                 return 0;
 74 
 75         return scnprintf(buf, size, "%"PRIx64, start + dl->al.offset);
 76 }
 77 
 78 static int perf_gtk__get_line(char *buf, size_t size, struct disasm_line *dl)
 79 {
 80         int ret = 0;
 81         char *line = g_markup_escape_text(dl->al.line, -1);
 82         const char *markup = "<span fgcolor='gray'>";
 83 
 84         strcpy(buf, "");
 85 
 86         if (!line)
 87                 return 0;
 88 
 89         if (dl->al.offset != (s64) -1)
 90                 markup = NULL;
 91 
 92         if (markup)
 93                 ret += scnprintf(buf, size, "%s", markup);
 94         ret += scnprintf(buf + ret, size - ret, "%s", line);
 95         if (markup)
 96                 ret += scnprintf(buf + ret, size - ret, "</span>");
 97 
 98         g_free(line);
 99         return ret;
100 }
101 
102 static int perf_gtk__annotate_symbol(GtkWidget *window, struct map_symbol *ms,
103                                 struct evsel *evsel,
104                                 struct hist_browser_timer *hbt __maybe_unused)
105 {
106         struct symbol *sym = ms->sym;
107         struct disasm_line *pos, *n;
108         struct annotation *notes;
109         GType col_types[MAX_ANN_COLS];
110         GtkCellRenderer *renderer;
111         GtkListStore *store;
112         GtkWidget *view;
113         int i;
114         char s[512];
115 
116         notes = symbol__annotation(sym);
117 
118         for (i = 0; i < MAX_ANN_COLS; i++) {
119                 col_types[i] = G_TYPE_STRING;
120         }
121         store = gtk_list_store_newv(MAX_ANN_COLS, col_types);
122 
123         view = gtk_tree_view_new();
124         renderer = gtk_cell_renderer_text_new();
125 
126         for (i = 0; i < MAX_ANN_COLS; i++) {
127                 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
128                                         -1, col_names[i], renderer, "markup",
129                                         i, NULL);
130         }
131 
132         gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
133         g_object_unref(GTK_TREE_MODEL(store));
134 
135         list_for_each_entry(pos, &notes->src->source, al.node) {
136                 GtkTreeIter iter;
137                 int ret = 0;
138 
139                 gtk_list_store_append(store, &iter);
140 
141                 if (evsel__is_group_event(evsel)) {
142                         for (i = 0; i < evsel->core.nr_members; i++) {
143                                 ret += perf_gtk__get_percent(s + ret,
144                                                              sizeof(s) - ret,
145                                                              sym, pos,
146                                                              evsel->core.idx + i);
147                                 ret += scnprintf(s + ret, sizeof(s) - ret, " ");
148                         }
149                 } else {
150                         ret = perf_gtk__get_percent(s, sizeof(s), sym, pos,
151                                                     evsel->core.idx);
152                 }
153 
154                 if (ret)
155                         gtk_list_store_set(store, &iter, ANN_COL__PERCENT, s, -1);
156                 if (perf_gtk__get_offset(s, sizeof(s), ms, pos))
157                         gtk_list_store_set(store, &iter, ANN_COL__OFFSET, s, -1);
158                 if (perf_gtk__get_line(s, sizeof(s), pos))
159                         gtk_list_store_set(store, &iter, ANN_COL__LINE, s, -1);
160         }
161 
162         gtk_container_add(GTK_CONTAINER(window), view);
163 
164         list_for_each_entry_safe(pos, n, &notes->src->source, al.node) {
165                 list_del_init(&pos->al.node);
166                 disasm_line__free(pos);
167         }
168 
169         return 0;
170 }
171 
172 static int symbol__gtk_annotate(struct map_symbol *ms, struct evsel *evsel,
173                                 struct hist_browser_timer *hbt)
174 {
175         struct dso *dso = map__dso(ms->map);
176         struct symbol *sym = ms->sym;
177         GtkWidget *window;
178         GtkWidget *notebook;
179         GtkWidget *scrolled_window;
180         GtkWidget *tab_label;
181         int err;
182 
183         if (dso__annotate_warned(dso))
184                 return -1;
185 
186         err = symbol__annotate(ms, evsel, NULL);
187         if (err) {
188                 char msg[BUFSIZ];
189 
190                 dso__set_annotate_warned(dso);
191                 symbol__strerror_disassemble(ms, err, msg, sizeof(msg));
192                 ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
193                 return -1;
194         }
195 
196         symbol__calc_percent(sym, evsel);
197 
198         if (perf_gtk__is_active_context(pgctx)) {
199                 window = pgctx->main_window;
200                 notebook = pgctx->notebook;
201         } else {
202                 GtkWidget *vbox;
203                 GtkWidget *infobar;
204                 GtkWidget *statbar;
205 
206                 signal(SIGSEGV, perf_gtk__signal);
207                 signal(SIGFPE,  perf_gtk__signal);
208                 signal(SIGINT,  perf_gtk__signal);
209                 signal(SIGQUIT, perf_gtk__signal);
210                 signal(SIGTERM, perf_gtk__signal);
211 
212                 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
213                 gtk_window_set_title(GTK_WINDOW(window), "perf annotate");
214 
215                 g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
216 
217                 pgctx = perf_gtk__activate_context(window);
218                 if (!pgctx)
219                         return -1;
220 
221                 vbox = gtk_vbox_new(FALSE, 0);
222                 notebook = gtk_notebook_new();
223                 pgctx->notebook = notebook;
224 
225                 gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
226 
227                 infobar = perf_gtk__setup_info_bar();
228                 if (infobar) {
229                         gtk_box_pack_start(GTK_BOX(vbox), infobar,
230                                            FALSE, FALSE, 0);
231                 }
232 
233                 statbar = perf_gtk__setup_statusbar();
234                 gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
235 
236                 gtk_container_add(GTK_CONTAINER(window), vbox);
237         }
238 
239         scrolled_window = gtk_scrolled_window_new(NULL, NULL);
240         tab_label = gtk_label_new(sym->name);
241 
242         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
243                                        GTK_POLICY_AUTOMATIC,
244                                        GTK_POLICY_AUTOMATIC);
245 
246         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window,
247                                  tab_label);
248 
249         perf_gtk__annotate_symbol(scrolled_window, ms, evsel, hbt);
250         return 0;
251 }
252 
253 int hist_entry__gtk_annotate(struct hist_entry *he,
254                              struct evsel *evsel,
255                              struct hist_browser_timer *hbt)
256 {
257         return symbol__gtk_annotate(&he->ms, evsel, hbt);
258 }
259 
260 void perf_gtk__show_annotations(void)
261 {
262         GtkWidget *window;
263 
264         if (!perf_gtk__is_active_context(pgctx))
265                 return;
266 
267         window = pgctx->main_window;
268         gtk_widget_show_all(window);
269 
270         perf_gtk__resize_window(window);
271         gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
272 
273         gtk_main();
274 
275         perf_gtk__deactivate_context(&pgctx);
276 }
277 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php