|
@@ -855,11 +855,22 @@ static int probe_point_lazy_walker(const char *fname, int lineno,
|
|
|
static int find_probe_point_lazy(Dwarf_Die *sp_die, struct probe_finder *pf)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
+ char *fpath;
|
|
|
|
|
|
if (intlist__empty(pf->lcache)) {
|
|
|
+ const char *comp_dir;
|
|
|
+
|
|
|
+ comp_dir = cu_get_comp_dir(&pf->cu_die);
|
|
|
+ ret = get_real_path(pf->fname, comp_dir, &fpath);
|
|
|
+ if (ret < 0) {
|
|
|
+ pr_warning("Failed to find source file path.\n");
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
/* Matching lazy line pattern */
|
|
|
- ret = find_lazy_match_lines(pf->lcache, pf->fname,
|
|
|
+ ret = find_lazy_match_lines(pf->lcache, fpath,
|
|
|
pf->pev->point.lazy_line);
|
|
|
+ free(fpath);
|
|
|
if (ret <= 0)
|
|
|
return ret;
|
|
|
}
|
|
@@ -1622,3 +1633,61 @@ found:
|
|
|
return (ret < 0) ? ret : lf.found;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * 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.
|
|
|
+ */
|
|
|
+int get_real_path(const char *raw_path, const char *comp_dir,
|
|
|
+ char **new_path)
|
|
|
+{
|
|
|
+ const char *prefix = symbol_conf.source_prefix;
|
|
|
+
|
|
|
+ if (!prefix) {
|
|
|
+ if (raw_path[0] != '/' && comp_dir)
|
|
|
+ /* If not an absolute path, try to use comp_dir */
|
|
|
+ prefix = comp_dir;
|
|
|
+ else {
|
|
|
+ if (access(raw_path, R_OK) == 0) {
|
|
|
+ *new_path = strdup(raw_path);
|
|
|
+ return *new_path ? 0 : -ENOMEM;
|
|
|
+ } else
|
|
|
+ return -errno;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
|
|
|
+ if (!*new_path)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ for (;;) {
|
|
|
+ sprintf(*new_path, "%s/%s", prefix, raw_path);
|
|
|
+
|
|
|
+ if (access(*new_path, R_OK) == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (!symbol_conf.source_prefix) {
|
|
|
+ /* In case of searching comp_dir, don't retry */
|
|
|
+ zfree(new_path);
|
|
|
+ return -errno;
|
|
|
+ }
|
|
|
+
|
|
|
+ switch (errno) {
|
|
|
+ case ENAMETOOLONG:
|
|
|
+ case ENOENT:
|
|
|
+ case EROFS:
|
|
|
+ case EFAULT:
|
|
|
+ raw_path = strchr(++raw_path, '/');
|
|
|
+ if (!raw_path) {
|
|
|
+ zfree(new_path);
|
|
|
+ return -ENOENT;
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+
|
|
|
+ default:
|
|
|
+ zfree(new_path);
|
|
|
+ return -errno;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|