From: Andi Kleen <a...@linux.intel.com>

Sometimes ~/.debug can get corrupted and contain files that still
have symbol tables, but which objdump cannot handle. Add a fallback
to read the "original" file in such a case. This might be wrong
too if it's different, but in many cases when profiling
on the same host it will work.

Signed-off-by: Andi Kleen <a...@linux.intel.com>
---
 tools/perf/util/annotate.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 1748f528b6e9..cff5f36786fa 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -1638,19 +1638,22 @@ int symbol__strerror_disassemble(struct symbol *sym 
__maybe_unused, struct map *
        return 0;
 }
 
-static int dso__disassemble_filename(struct dso *dso, char *filename, size_t 
filename_size)
+static int dso__disassemble_filename(struct dso *dso, char *filename, size_t 
filename_size,
+                                    bool *build_id)
 {
        char linkname[PATH_MAX];
        char *build_id_filename;
        char *build_id_path = NULL;
        char *pos;
 
+       *build_id = false;
        if (dso->symtab_type == DSO_BINARY_TYPE__KALLSYMS &&
            !dso__is_kcore(dso))
                return SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX;
 
        build_id_filename = dso__build_id_filename(dso, NULL, 0, false);
        if (build_id_filename) {
+               *build_id = true;
                __symbol__join_symfs(filename, filename_size, 
build_id_filename);
                free(build_id_filename);
        } else {
@@ -1854,11 +1857,14 @@ static int symbol__disassemble(struct symbol *sym, 
struct annotate_args *args)
        int lineno = 0;
        int nline;
        pid_t pid;
-       int err = dso__disassemble_filename(dso, symfs_filename, 
sizeof(symfs_filename));
+       bool build_id;
+       int err = dso__disassemble_filename(dso, symfs_filename, 
sizeof(symfs_filename),
+                                           &build_id);
 
        if (err)
                return err;
 
+again:
        pr_debug("%s: filename=%s, sym=%s, start=%#" PRIx64 ", end=%#" PRIx64 
"\n", __func__,
                 symfs_filename, sym->name, map->unmap_ip(map, sym->start),
                 map->unmap_ip(map, sym->end));
@@ -1955,8 +1961,21 @@ static int symbol__disassemble(struct symbol *sym, 
struct annotate_args *args)
                nline++;
        }
 
-       if (nline == 0)
-               pr_err("No output from %s\n", command);
+       if (nline == 0) {
+               pr_err("No objdump output for %s. Corrupted file?\n", 
symfs_filename);
+               if (build_id) {
+                       /*
+                        * It could be that the buildid file is corrupted.
+                        * Try again with the "true" file. This might be wrong
+                        * too, but it's better than nothing.
+                        * We could move the build id file here?
+                        */
+                       __symbol__join_symfs(symfs_filename, 
sizeof(symfs_filename),
+                                            dso->long_name);
+                       build_id = false;
+                       goto again;
+               }
+       }
 
        /*
         * kallsyms does not have symbol sizes so there may a nop at the end.
-- 
2.21.0

Reply via email to