mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-16 22:10:24 +00:00
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>
This commit is contained in:
parent
0dd9ac63ce
commit
7cf0b79e6f
@ -195,6 +195,55 @@ static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
|
|||||||
return ntevs;
|
return ntevs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find a src file from a DWARF tag path. Prepend optional source path prefix
|
||||||
|
* and chop off leading directories that do not exist. Result is passed back as
|
||||||
|
* a newly allocated path on success.
|
||||||
|
* Return 0 if file was found and readable, -errno otherwise.
|
||||||
|
*/
|
||||||
|
static int get_real_path(const char *raw_path, char **new_path)
|
||||||
|
{
|
||||||
|
if (!symbol_conf.source_prefix) {
|
||||||
|
if (access(raw_path, R_OK) == 0) {
|
||||||
|
*new_path = strdup(raw_path);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
*new_path = malloc((strlen(symbol_conf.source_prefix) +
|
||||||
|
strlen(raw_path) + 2));
|
||||||
|
if (!*new_path)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
sprintf(*new_path, "%s/%s", symbol_conf.source_prefix,
|
||||||
|
raw_path);
|
||||||
|
|
||||||
|
if (access(*new_path, R_OK) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (errno) {
|
||||||
|
case ENAMETOOLONG:
|
||||||
|
case ENOENT:
|
||||||
|
case EROFS:
|
||||||
|
case EFAULT:
|
||||||
|
raw_path = strchr(++raw_path, '/');
|
||||||
|
if (!raw_path) {
|
||||||
|
free(*new_path);
|
||||||
|
*new_path = NULL;
|
||||||
|
return -ENOENT;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
default:
|
||||||
|
free(*new_path);
|
||||||
|
*new_path = NULL;
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define LINEBUF_SIZE 256
|
#define LINEBUF_SIZE 256
|
||||||
#define NR_ADDITIONAL_LINES 2
|
#define NR_ADDITIONAL_LINES 2
|
||||||
|
|
||||||
@ -244,6 +293,7 @@ int show_line_range(struct line_range *lr)
|
|||||||
struct line_node *ln;
|
struct line_node *ln;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
|
char *tmp;
|
||||||
|
|
||||||
/* Search a line range */
|
/* Search a line range */
|
||||||
ret = init_vmlinux();
|
ret = init_vmlinux();
|
||||||
@ -266,6 +316,15 @@ int show_line_range(struct line_range *lr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert source file path */
|
||||||
|
tmp = lr->path;
|
||||||
|
ret = get_real_path(tmp, &lr->path);
|
||||||
|
free(tmp); /* Free old path */
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_warning("Failed to find source file. (%d)\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
setup_pager();
|
setup_pager();
|
||||||
|
|
||||||
if (lr->function)
|
if (lr->function)
|
||||||
|
@ -58,55 +58,6 @@ static int strtailcmp(const char *s1, const char *s2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Find a src file from a DWARF tag path. Prepend optional source path prefix
|
|
||||||
* and chop off leading directories that do not exist. Result is passed back as
|
|
||||||
* a newly allocated path on success.
|
|
||||||
* Return 0 if file was found and readable, -errno otherwise.
|
|
||||||
*/
|
|
||||||
static int get_real_path(const char *raw_path, char **new_path)
|
|
||||||
{
|
|
||||||
if (!symbol_conf.source_prefix) {
|
|
||||||
if (access(raw_path, R_OK) == 0) {
|
|
||||||
*new_path = strdup(raw_path);
|
|
||||||
return 0;
|
|
||||||
} else
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
*new_path = malloc((strlen(symbol_conf.source_prefix) +
|
|
||||||
strlen(raw_path) + 2));
|
|
||||||
if (!*new_path)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
sprintf(*new_path, "%s/%s", symbol_conf.source_prefix,
|
|
||||||
raw_path);
|
|
||||||
|
|
||||||
if (access(*new_path, R_OK) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (errno) {
|
|
||||||
case ENAMETOOLONG:
|
|
||||||
case ENOENT:
|
|
||||||
case EROFS:
|
|
||||||
case EFAULT:
|
|
||||||
raw_path = strchr(++raw_path, '/');
|
|
||||||
if (!raw_path) {
|
|
||||||
free(*new_path);
|
|
||||||
*new_path = NULL;
|
|
||||||
return -ENOENT;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
|
||||||
free(*new_path);
|
|
||||||
*new_path = NULL;
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Line number list operations */
|
/* Line number list operations */
|
||||||
|
|
||||||
/* Add a line to line number list */
|
/* Add a line to line number list */
|
||||||
@ -1256,13 +1207,11 @@ end:
|
|||||||
static int line_range_add_line(const char *src, unsigned int lineno,
|
static int line_range_add_line(const char *src, unsigned int lineno,
|
||||||
struct line_range *lr)
|
struct line_range *lr)
|
||||||
{
|
{
|
||||||
int ret;
|
/* Copy source path */
|
||||||
|
|
||||||
/* Copy real path */
|
|
||||||
if (!lr->path) {
|
if (!lr->path) {
|
||||||
ret = get_real_path(src, &lr->path);
|
lr->path = strdup(src);
|
||||||
if (ret != 0)
|
if (lr->path == NULL)
|
||||||
return ret;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
return line_list__add_line(&lr->line_list, lineno);
|
return line_list__add_line(&lr->line_list, lineno);
|
||||||
}
|
}
|
||||||
@ -1460,7 +1409,7 @@ int find_line_range(int fd, struct line_range *lr)
|
|||||||
}
|
}
|
||||||
off = noff;
|
off = noff;
|
||||||
}
|
}
|
||||||
pr_debug("path: %lx\n", (unsigned long)lr->path);
|
pr_debug("path: %s\n", lr->path);
|
||||||
dwarf_end(dbg);
|
dwarf_end(dbg);
|
||||||
|
|
||||||
return (ret < 0) ? ret : lf.found;
|
return (ret < 0) ? ret : lf.found;
|
||||||
|
Loading…
Reference in New Issue
Block a user