aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2010-07-09 05:28:59 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-07-16 10:46:34 -0400
commit7cf0b79e6ffd04bba5d4e625a0fe2e30a5b383e5 (patch)
tree65a99a3bd6aeaafd723397ffb623a9a90e327474 /tools/perf/util/probe-event.c
parent0dd9ac63ce26ec87b080ca9c3e6efed33c23ace6 (diff)
perf probe: Fix error message if get_real_path() failed
Perf probe -L shows incorrect error message (Dwarf error) if it fails to find source file. This can confuse users. # ./perf probe -s /nowhere -L vfs_read Debuginfo analysis failed. (-2) Error: Failed to show lines. (-2) With this patch, it shows correct message. # ./perf probe -s /nowhere -L vfs_read Failed to find source file. (-2) Error: Failed to show lines. (-2) LKML-Reference: <4C36EBDB.4020308@hitachi.com> Cc: Chase Douglas <chase.douglas@canonical.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Acked-by: Chase Douglas <chase.douglas@canonical.com> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 09cf5465e10a..8d08e75b2dd3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -195,6 +195,55 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
195 return ntevs; 195 return ntevs;
196} 196}
197 197
198/*
199 * Find a src file from a DWARF tag path. Prepend optional source path prefix
200 * and chop off leading directories that do not exist. Result is passed back as
201 * a newly allocated path on success.
202 * Return 0 if file was found and readable, -errno otherwise.
203 */
204static int get_real_path(const char *raw_path, char **new_path)
205{
206 if (!symbol_conf.source_prefix) {
207 if (access(raw_path, R_OK) == 0) {
208 *new_path = strdup(raw_path);
209 return 0;
210 } else
211 return -errno;
212 }
213
214 *new_path = malloc((strlen(symbol_conf.source_prefix) +
215 strlen(raw_path) + 2));
216 if (!*new_path)
217 return -ENOMEM;
218
219 for (;;) {
220 sprintf(*new_path, "%s/%s", symbol_conf.source_prefix,
221 raw_path);
222
223 if (access(*new_path, R_OK) == 0)
224 return 0;
225
226 switch (errno) {
227 case ENAMETOOLONG:
228 case ENOENT:
229 case EROFS:
230 case EFAULT:
231 raw_path = strchr(++raw_path, '/');
232 if (!raw_path) {
233 free(*new_path);
234 *new_path = NULL;
235 return -ENOENT;
236 }
237 continue;
238
239 default:
240 free(*new_path);
241 *new_path = NULL;
242 return -errno;
243 }
244 }
245}
246
198#define LINEBUF_SIZE 256 247#define LINEBUF_SIZE 256
199#define NR_ADDITIONAL_LINES 2 248#define NR_ADDITIONAL_LINES 2
200 249
@@ -244,6 +293,7 @@ int show_line_range(struct line_range *lr)
244 struct line_node *ln; 293 struct line_node *ln;
245 FILE *fp; 294 FILE *fp;
246 int fd, ret; 295 int fd, ret;
296 char *tmp;
247 297
248 /* Search a line range */ 298 /* Search a line range */
249 ret = init_vmlinux(); 299 ret = init_vmlinux();
@@ -266,6 +316,15 @@ int show_line_range(struct line_range *lr)
266 return ret; 316 return ret;
267 } 317 }
268 318
319 /* Convert source file path */
320 tmp = lr->path;
321 ret = get_real_path(tmp, &lr->path);
322 free(tmp); /* Free old path */
323 if (ret < 0) {
324 pr_warning("Failed to find source file. (%d)\n", ret);
325 return ret;
326 }
327
269 setup_pager(); 328 setup_pager();
270 329
271 if (lr->function) 330 if (lr->function)