DavidSpickett updated this revision to Diff 555333.
DavidSpickett marked 2 inline comments as done.
DavidSpickett added a comment.

Use *.dwo in commands since I'm not sure the DWO name will be the
same everywhere. The specific name isn't important, we know there's
only going to be one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D157609/new/

https://reviews.llvm.org/D157609

Files:
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  
lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-dwoname-absolute-compdir.c
  
lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-absolute-compdir.c
  
lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-relative-compdir.c
  
lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-relative-compdir.c
  lldb/test/Shell/SymbolFile/DWARF/dwo-relative-filename-only-binary-dir.c

Index: lldb/test/Shell/SymbolFile/DWARF/dwo-relative-filename-only-binary-dir.c
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwo-relative-filename-only-binary-dir.c
@@ -0,0 +1,23 @@
+/// Check that LLDB can find a relative DWO file next to a binary just using the
+/// filename of that DWO. For example "main.dwo" not "a/b/main.dwo".
+// RUN: rm -rf %t.compdir/
+// RUN: mkdir -p %t.compdir/a/b/
+// RUN: cp %s %t.compdir/a/b/main.c
+// RUN: cd %t.compdir/a/
+/// The produced DWO is named b/main-main.dwo, with a DW_AT_comp_dir of a/.
+// RUN: %clang_host -g -gsplit-dwarf -fdebug-prefix-map=%t.compdir=. b/main.c -o b/main
+// RUN: cd ../..
+/// Move binary and DWO out of expected locations.
+// RUN: mv %t.compdir/a/b/main %t.compdir/
+// RUN: mv %t.compdir/a/b/*.dwo %t.compdir/
+// RUN: %lldb --no-lldbinit %t.compdir/main \
+// RUN:   -o "b main" -o "run" -o "p num" --batch 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning: {{.*}}main unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
+// CHECK: (int) 5
+
+int num = 5;
+
+int main(void) {
+  return 0;
+}
\ No newline at end of file
Index: lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-relative-compdir.c
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-relative-compdir.c
@@ -0,0 +1,28 @@
+/// Check that LLDB uses the paths in target.debug-file-search-paths to find
+/// split DWARF files with a relative DW_AT_comp_dir set, when the program file
+/// has been moved and/or we're executing it from another directory.
+// RUN: rm -rf %t.compdir/ %t.e/
+// RUN: mkdir -p %t.compdir/a/b/c/d/
+// RUN: cp %s %t.compdir/a/b/c/d/main.c
+// RUN: cd %t.compdir/a/b/
+/// The produced DWO is named c/d/main-main.dwo, with a DW_AT_comp_dir of a/b.
+// RUN: %clang_host -g -gsplit-dwarf -fdebug-prefix-map=%t.compdir=. c/d/main.c -o c/d/main
+// RUN: cd ../../..
+/// Move only the program, leaving the DWO file in place.
+// RUN: mv %t.compdir/a/b/c/d/main %t.compdir/a/
+/// Debug it from yet another path.
+// RUN: mkdir -p %t.e/
+// RUN: cd %t.e
+/// LLDB won't find the DWO next to the binary or in the current dir, so it
+/// should find the DWO file by doing %t.compdir/ + a/b/ + c/d/main-main.dwo.
+// RUN: %lldb --no-lldbinit %t.compdir/a/main \
+// RUN:   -O "settings append target.debug-file-search-paths %t.compdir" \
+// RUN:   -o "b main.c:27" -o "run" -o "frame variable" --batch 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning: {{.*}}main unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
+// CHECK: (int) num = 5
+
+int main(void) {
+  int num = 5;
+  return 0;
+}
\ No newline at end of file
Index: lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-relative-compdir.c
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-relative-compdir.c
@@ -0,0 +1,28 @@
+/// Check that when LLDB is looking for a relative DWO it uses the debug search
+/// paths setting. If it doesn't find it by adding the whole relative path to
+/// of DWO it should try adding just the filename (e.g. main.dwo) to each debug
+/// search path.
+// RUN: rm -rf %t.compdir/
+// RUN: mkdir -p %t.compdir/a/b/
+// RUN: cp %s %t.compdir/a/b/main.c
+// RUN: cd %t.compdir/a/
+/// The produced DWO is named /b/main-main.dwo, with a DW_AT_comp_dir of a/.
+// RUN: %clang_host -g -gsplit-dwarf -fdebug-prefix-map=%t.compdir=. b/main.c -o b/main
+// RUN: cd ../..
+/// Move the DWO file away from the expected location.
+// RUN: mv %t.compdir/a/b/*.dwo %t.compdir/
+/// LLDB won't find the DWO next to the binary or by adding the relative path
+/// to any of the search paths. So it should find the DWO file at
+/// %t.compdir/main-main.dwo.
+// RUN: %lldb --no-lldbinit %t.compdir/a/b/main \
+// RUN:   -O "settings append target.debug-file-search-paths %t.compdir" \
+// RUN:   -o "b main" -o "run" -o "p num" --batch 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning: {{.*}}main unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
+// CHECK: (int) 5
+
+int num = 5;
+
+int main(void) {
+  return 0;
+}
\ No newline at end of file
Index: lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-absolute-compdir.c
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-filename-only-absolute-compdir.c
@@ -0,0 +1,33 @@
+/// Check that LLDB uses the paths in target.debug-file-search-paths to find
+/// split DWARF files with DW_AT_comp_dir set to some non-relative path, when
+/// the program file and DWO have been moved and/or we're executing from another
+/// directory. Specifically when the DWO is not at it's "name", here we move
+/// it to %t.compdir/main-main.dwo and it's name is c/d/main-main.dwo.
+// RUN: rm -rf %t.compdir/ %t.e/
+// RUN: mkdir -p %t.compdir/a/b/c/d/
+// RUN: cp %s %t.compdir/a/b/c/d/main.c
+// RUN: cd %t.compdir/a/b/
+/// The produced DWO is named c/d/main-main.dwo, with a non-relative
+/// DW_AT_comp_dir of <pathtobuild>/a/b
+// RUN: %clang_host -g -gsplit-dwarf c/d/main.c -o c/d/main
+// RUN: cd ../../..
+/// Move the program.
+// RUN: mv %t.compdir/a/b/c/d/main %t.compdir/a/
+/// Move the DWO.
+// RUN: mv %t.compdir/a/b/c/d/*.dwo %t.compdir
+/// Debug it from yet another path.
+// RUN: mkdir -p %t.e/
+// RUN: cd %t.e
+/// LLDB should find in %t.compdir.
+// RUN: %lldb --no-lldbinit %t.compdir/a/main \
+// RUN:   -O "settings append target.debug-file-search-paths %t.compdir" \
+// RUN:   -o "b main" -o "run" -o "p num" --batch 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning: {{.*}}main unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
+// CHECK: (int) 5
+
+int num = 5;
+
+int main(void) {
+  return 0;
+}
\ No newline at end of file
Index: lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-dwoname-absolute-compdir.c
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/dwo-debug-file-search-paths-dwoname-absolute-compdir.c
@@ -0,0 +1,34 @@
+/// Check that LLDB uses the paths in target.debug-file-search-paths to find
+/// split DWARF files with DW_AT_comp_dir set to some absolute path, when
+/// the program file and DWO have been moved and/or we're executing from
+/// another directory. Specifically when the DWO has been moved to another
+/// directory but is still at it's name. Here, %t.compdir/c/d/main-main.dwo.
+// RUN: rm -rf %t.compdir/ %t.e/
+// RUN: mkdir -p %t.compdir/a/b/c/d/
+// RUN: cp %s %t.compdir/a/b/c/d/main.c
+// RUN: cd %t.compdir/a/b/
+/// The produced DWO is named c/d/main-main.dwo, with a non-relative
+/// DW_AT_comp_dir of <pathtobuild>/a/b
+// RUN: %clang_host -g -gsplit-dwarf c/d/main.c -o c/d/main
+// RUN: cd ../../..
+/// Move the program.
+// RUN: mv %t.compdir/a/b/c/d/main %t.compdir/a/
+/// Move the DWO but keep it at the path in in its name.
+// RUN: mkdir -p %t.compdir/c/d/
+// RUN: mv %t.compdir/a/b/c/d/*.dwo %t.compdir/c/d/
+/// Debug it from yet another path.
+// RUN: mkdir -p %t.e/
+// RUN: cd %t.e
+/// LLDB should find in %t.compdir.
+// RUN: %lldb --no-lldbinit %t.compdir/a/main \
+// RUN:   -O "settings append target.debug-file-search-paths %t.compdir" \
+// RUN:   -o "b main" -o "run" -o "p num" --batch 2>&1 | FileCheck %s
+
+// CHECK-NOT: warning: {{.*}}main unable to locate separate debug file (dwo, dwp). Debugging will be degraded.
+// CHECK: (int) 5
+
+int num = 5;
+
+int main(void) {
+  return 0;
+}
\ No newline at end of file
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1728,12 +1728,22 @@
   if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile())
     return dwp_sp;
 
-  const char *comp_dir = nullptr;
   FileSpec dwo_file(dwo_name);
   FileSystem::Instance().Resolve(dwo_file);
-  if (dwo_file.IsRelative()) {
-    comp_dir = cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir,
-                                                nullptr);
+  bool found = false;
+
+  const FileSpecList &debug_file_search_paths =
+      Target::GetDefaultDebugFileSearchPaths();
+  size_t num_search_paths = debug_file_search_paths.GetSize();
+
+  if (FileSystem::Instance().Exists(dwo_file)) {
+    // It's relative, e.g. "foo.dwo", but we just to happen to be right next to
+    // it. Or it's absolute.
+    found = true;
+  } else {
+    // It must be a relative path that also uses DW_AT_COMP_DIR.
+    const char *comp_dir =
+        cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);
     if (!comp_dir) {
       unit.SetDwoError(Status::createWithFormat(
           "unable to locate relative .dwo debug file \"{0}\" for "
@@ -1744,18 +1754,91 @@
     }
 
     dwo_file.SetFile(comp_dir, FileSpec::Style::native);
-    if (dwo_file.IsRelative()) {
+    if (!dwo_file.IsRelative()) {
+      FileSystem::Instance().Resolve(dwo_file);
+      dwo_file.AppendPathComponent(dwo_name);
+      found = FileSystem::Instance().Exists(dwo_file);
+    } else {
+      FileSpecList dwo_paths;
+
       // if DW_AT_comp_dir is relative, it should be relative to the location
       // of the executable, not to the location from which the debugger was
       // launched.
-      dwo_file.PrependPathComponent(
+      FileSpec relative_to_binary = dwo_file;
+      relative_to_binary.PrependPathComponent(
           m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+      FileSystem::Instance().Resolve(relative_to_binary);
+      relative_to_binary.AppendPathComponent(dwo_name);
+      dwo_paths.Append(relative_to_binary);
+
+      // Or it's relative to one of the user specified debug directories.
+      for (size_t idx = 0; idx < num_search_paths; ++idx) {
+        FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+        dirspec.AppendPathComponent(comp_dir);
+        FileSystem::Instance().Resolve(dirspec);
+        if (!FileSystem::Instance().IsDirectory(dirspec))
+          continue;
+
+        dirspec.AppendPathComponent(dwo_name);
+        dwo_paths.Append(dirspec);
+      }
+
+      size_t num_possible = dwo_paths.GetSize();
+      for (size_t idx = 0; idx < num_possible && !found; ++idx) {
+        FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
+        if (FileSystem::Instance().Exists(dwo_spec)) {
+          dwo_file = dwo_spec;
+          found = true;
+        }
+      }
+    }
+  }
+
+  if (!found) {
+    // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the
+    // filename ("main-main.dwo") to binary dir and search paths.
+    FileSpecList dwo_paths;
+    FileSpec spec_to_get_name(dwo_name);
+    llvm::StringRef filename_only = spec_to_get_name.GetFilename();
+
+    FileSpec next_to_binary(
+        m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef());
+    FileSystem::Instance().Resolve(next_to_binary);
+
+    FileSpec dwo_name_next_to_binary(next_to_binary);
+    dwo_name_next_to_binary.AppendPathComponent(dwo_name);
+    dwo_paths.Append(dwo_name_next_to_binary);
+
+    FileSpec filename_next_to_binary(next_to_binary);
+    filename_next_to_binary.AppendPathComponent(filename_only);
+    dwo_paths.Append(filename_next_to_binary);
+
+    for (size_t idx = 0; idx < num_search_paths; ++idx) {
+      FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx);
+      FileSystem::Instance().Resolve(dirspec);
+      if (!FileSystem::Instance().IsDirectory(dirspec))
+        continue;
+
+      FileSpec dwo_name_dirspec(dirspec);
+      dwo_name_dirspec.AppendPathComponent(dwo_name);
+      dwo_paths.Append(dwo_name_dirspec);
+
+      FileSpec filename_dirspec(dirspec);
+      filename_dirspec.AppendPathComponent(filename_only);
+      dwo_paths.Append(filename_dirspec);
+    }
+
+    size_t num_possible = dwo_paths.GetSize();
+    for (size_t idx = 0; idx < num_possible && !found; ++idx) {
+      FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx);
+      if (FileSystem::Instance().Exists(dwo_spec)) {
+        dwo_file = dwo_spec;
+        found = true;
+      }
     }
-    FileSystem::Instance().Resolve(dwo_file);
-    dwo_file.AppendPathComponent(dwo_name);
   }
 
-  if (!FileSystem::Instance().Exists(dwo_file)) {
+  if (!found) {
     unit.SetDwoError(Status::createWithFormat(
         "unable to locate .dwo debug file \"{0}\" for skeleton DIE "
         "{1:x16}",
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to