aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
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
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')
-rw-r--r--tools/perf/util/probe-event.c59
-rw-r--r--tools/perf/util/probe-finder.c61
2 files changed, 64 insertions, 56 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)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 3e64e1fa1051..a934a364c30f 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -58,55 +58,6 @@ static int strtailcmp(const char *s1, const char *s2)
58 return 0; 58 return 0;
59} 59}
60 60
61/*
62 * Find a src file from a DWARF tag path. Prepend optional source path prefix
63 * and chop off leading directories that do not exist. Result is passed back as
64 * a newly allocated path on success.
65 * Return 0 if file was found and readable, -errno otherwise.
66 */
67static int get_real_path(const char *raw_path, char **new_path)
68{
69 if (!symbol_conf.source_prefix) {
70 if (access(raw_path, R_OK) == 0) {
71 *new_path = strdup(raw_path);
72 return 0;
73 } else
74 return -errno;
75 }
76
77 *new_path = malloc((strlen(symbol_conf.source_prefix) +
78 strlen(raw_path) + 2));
79 if (!*new_path)
80 return -ENOMEM;
81
82 for (;;) {
83 sprintf(*new_path, "%s/%s", symbol_conf.source_prefix,
84 raw_path);
85
86 if (access(*new_path, R_OK) == 0)
87 return 0;
88
89 switch (errno) {
90 case ENAMETOOLONG:
91 case ENOENT:
92 case EROFS:
93 case EFAULT:
94 raw_path = strchr(++raw_path, '/');
95 if (!raw_path) {
96 free(*new_path);
97 *new_path = NULL;
98 return -ENOENT;
99 }
100 continue;
101
102 default:
103 free(*new_path);
104 *new_path = NULL;
105 return -errno;
106 }
107 }
108}
109
110/* Line number list operations */ 61/* Line number list operations */
111 62
112/* Add a line to line number list */ 63/* Add a line to line number list */
@@ -1256,13 +1207,11 @@ end:
1256static int line_range_add_line(const char *src, unsigned int lineno, 1207static int line_range_add_line(const char *src, unsigned int lineno,
1257 struct line_range *lr) 1208 struct line_range *lr)
1258{ 1209{
1259 int ret; 1210 /* Copy source path */
1260
1261 /* Copy real path */
1262 if (!lr->path) { 1211 if (!lr->path) {
1263 ret = get_real_path(src, &lr->path); 1212 lr->path = strdup(src);
1264 if (ret != 0) 1213 if (lr->path == NULL)
1265 return ret; 1214 return -ENOMEM;
1266 } 1215 }
1267 return line_list__add_line(&lr->line_list, lineno); 1216 return line_list__add_line(&lr->line_list, lineno);
1268} 1217}
@@ -1460,7 +1409,7 @@ int find_line_range(int fd, struct line_range *lr)
1460 } 1409 }
1461 off = noff; 1410 off = noff;
1462 } 1411 }
1463 pr_debug("path: %lx\n", (unsigned long)lr->path); 1412 pr_debug("path: %s\n", lr->path);
1464 dwarf_end(dbg); 1413 dwarf_end(dbg);
1465 1414
1466 return (ret < 0) ? ret : lf.found; 1415 return (ret < 0) ? ret : lf.found;