aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2016-07-29 15:27:18 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-08-01 17:18:16 -0400
commitee51d851392e1fe3e8be30b3c5847f34da343424 (patch)
tree995d0ca1d366d17876e5b8d32daef596941dacaa /tools
parent5cb725a9723aebb248106ff7f8c6c7253b24bbb1 (diff)
perf annotate: Introduce strerror for handling symbol__disassemble() errors
We were just using pr_error() which makes it difficult for non stdio UIs to provide errors using its widgets, as they need to somehow catch what was passed to pr_error(). Fix it by introducing a __strerror() interface like the ones used elsewhere, for instance target__strerror(). This is just the initial step, more work will be done, but first some error handling bugs noticed while working on this need to be dealt with. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-dgd22zl2xg7x4vcnoa83jxfb@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-top.c4
-rw-r--r--tools/perf/ui/browsers/annotate.c9
-rw-r--r--tools/perf/ui/gtk/annotate.c8
-rw-r--r--tools/perf/util/annotate.c68
-rw-r--r--tools/perf/util/annotate.h20
5 files changed, 78 insertions, 31 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 823dbbbf82a9..418ed94756d3 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -132,6 +132,10 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)
132 if (err == 0) { 132 if (err == 0) {
133out_assign: 133out_assign:
134 top->sym_filter_entry = he; 134 top->sym_filter_entry = he;
135 } else {
136 char msg[BUFSIZ];
137 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
138 pr_err("Couldn't annotate %s: %s\n", sym->name, msg);
135 } 139 }
136 140
137 pthread_mutex_unlock(&notes->lock); 141 pthread_mutex_unlock(&notes->lock);
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index f4d6a8a962af..2e2d10022355 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -1026,7 +1026,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
1026 .use_navkeypressed = true, 1026 .use_navkeypressed = true,
1027 }, 1027 },
1028 }; 1028 };
1029 int ret = -1; 1029 int ret = -1, err;
1030 int nr_pcnt = 1; 1030 int nr_pcnt = 1;
1031 size_t sizeof_bdl = sizeof(struct browser_disasm_line); 1031 size_t sizeof_bdl = sizeof(struct browser_disasm_line);
1032 1032
@@ -1050,8 +1050,11 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
1050 (nr_pcnt - 1); 1050 (nr_pcnt - 1);
1051 } 1051 }
1052 1052
1053 if (symbol__disassemble(sym, map, sizeof_bdl) < 0) { 1053 err = symbol__disassemble(sym, map, sizeof_bdl);
1054 ui__error("%s", ui_helpline__last_msg); 1054 if (err) {
1055 char msg[BUFSIZ];
1056 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
1057 ui__error("Couldn't annotate %s:\n%s", sym->name, msg);
1055 goto out_free_offsets; 1058 goto out_free_offsets;
1056 } 1059 }
1057 1060
diff --git a/tools/perf/ui/gtk/annotate.c b/tools/perf/ui/gtk/annotate.c
index 35e4b9e28c8d..42d319927762 100644
--- a/tools/perf/ui/gtk/annotate.c
+++ b/tools/perf/ui/gtk/annotate.c
@@ -162,12 +162,16 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,
162 GtkWidget *notebook; 162 GtkWidget *notebook;
163 GtkWidget *scrolled_window; 163 GtkWidget *scrolled_window;
164 GtkWidget *tab_label; 164 GtkWidget *tab_label;
165 int err;
165 166
166 if (map->dso->annotate_warned) 167 if (map->dso->annotate_warned)
167 return -1; 168 return -1;
168 169
169 if (symbol__disassemble(sym, map, 0) < 0) { 170 err = symbol__disassemble(sym, map, 0);
170 ui__error("%s", ui_helpline__current); 171 if (err) {
172 char msg[BUFSIZ];
173 symbol__strerror_disassemble(sym, map, err, msg, sizeof(msg));
174 ui__error("Couldn't annotate %s: %s\n", sym->name, msg);
171 return -1; 175 return -1;
172 } 176 }
173 177
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 4f47b6069197..4982ed487e96 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1123,6 +1123,45 @@ static void delete_last_nop(struct symbol *sym)
1123 } 1123 }
1124} 1124}
1125 1125
1126int symbol__strerror_disassemble(struct symbol *sym __maybe_unused, struct map *map,
1127 int errnum, char *buf, size_t buflen)
1128{
1129 struct dso *dso = map->dso;
1130
1131 BUG_ON(buflen == 0);
1132
1133 if (errnum >= 0) {
1134 str_error_r(errnum, buf, buflen);
1135 return 0;
1136 }
1137
1138 switch (errnum) {
1139 case SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX: {
1140 char bf[SBUILD_ID_SIZE + 15] = " with build id ";
1141 char *build_id_msg = NULL;
1142
1143 if (dso->has_build_id) {
1144 build_id__sprintf(dso->build_id,
1145 sizeof(dso->build_id), bf + 15);
1146 build_id_msg = bf;
1147 }
1148 scnprintf(buf, buflen,
1149 "No vmlinux file%s\nwas found in the path.\n\n"
1150 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n"
1151 "Please use:\n\n"
1152 " perf buildid-cache -vu vmlinux\n\n"
1153 "or:\n\n"
1154 " --vmlinux vmlinux\n", build_id_msg ?: "");
1155 }
1156 break;
1157 default:
1158 scnprintf(buf, buflen, "Internal error: Invalid %d error code\n", errnum);
1159 break;
1160 }
1161
1162 return 0;
1163}
1164
1126int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize) 1165int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
1127{ 1166{
1128 struct dso *dso = map->dso; 1167 struct dso *dso = map->dso;
@@ -1143,11 +1182,8 @@ int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize)
1143 symbol__join_symfs(symfs_filename, filename); 1182 symbol__join_symfs(symfs_filename, filename);
1144 1183
1145 if (filename == NULL) { 1184 if (filename == NULL) {
1146 if (dso->has_build_id) { 1185 if (dso->has_build_id)
1147 pr_err("Can't annotate %s: not enough memory\n", 1186 return ENOMEM;
1148 sym->name);
1149 return -ENOMEM;
1150 }
1151 goto fallback; 1187 goto fallback;
1152 } else if (dso__is_kcore(dso)) { 1188 } else if (dso__is_kcore(dso)) {
1153 goto fallback; 1189 goto fallback;
@@ -1168,27 +1204,7 @@ fallback:
1168 1204
1169 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS && 1205 if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
1170 !dso__is_kcore(dso)) { 1206 !dso__is_kcore(dso)) {
1171 char bf[SBUILD_ID_SIZE + 15] = " with build id "; 1207 err = SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX;
1172 char *build_id_msg = NULL;
1173
1174 if (dso->annotate_warned)
1175 goto out_free_filename;
1176
1177 if (dso->has_build_id) {
1178 build_id__sprintf(dso->build_id,
1179 sizeof(dso->build_id), bf + 15);
1180 build_id_msg = bf;
1181 }
1182 err = -ENOENT;
1183 dso->annotate_warned = 1;
1184 pr_err("Can't annotate %s:\n\n"
1185 "No vmlinux file%s\nwas found in the path.\n\n"
1186 "Note that annotation using /proc/kcore requires CAP_SYS_RAWIO capability.\n\n"
1187 "Please use:\n\n"
1188 " perf buildid-cache -vu vmlinux\n\n"
1189 "or:\n\n"
1190 " --vmlinux vmlinux\n",
1191 sym->name, build_id_msg ?: "");
1192 goto out_free_filename; 1208 goto out_free_filename;
1193 } 1209 }
1194 1210
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index b0750d8bee1f..f67ccb027561 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -157,6 +157,26 @@ void symbol__annotate_zero_histograms(struct symbol *sym);
157 157
158int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize); 158int symbol__disassemble(struct symbol *sym, struct map *map, size_t privsize);
159 159
160enum symbol_disassemble_errno {
161 SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0,
162
163 /*
164 * Choose an arbitrary negative big number not to clash with standard
165 * errno since SUS requires the errno has distinct positive values.
166 * See 'Issue 6' in the link below.
167 *
168 * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
169 */
170 __SYMBOL_ANNOTATE_ERRNO__START = -10000,
171
172 SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START,
173
174 __SYMBOL_ANNOTATE_ERRNO__END,
175};
176
177int symbol__strerror_disassemble(struct symbol *sym, struct map *map,
178 int errnum, char *buf, size_t buflen);
179
160int symbol__annotate_init(struct map *map, struct symbol *sym); 180int symbol__annotate_init(struct map *map, struct symbol *sym);
161int symbol__annotate_printf(struct symbol *sym, struct map *map, 181int symbol__annotate_printf(struct symbol *sym, struct map *map,
162 struct perf_evsel *evsel, bool full_paths, 182 struct perf_evsel *evsel, bool full_paths,