[Lldb-commits] [lldb] 69a5869 - [lldb][split-dwarf] implement GetSeparateDebugInfo for SymbolFileOnDemand (#71230)

via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 20 12:17:20 PST 2023


Author: Tom Yang
Date: 2023-11-20T12:17:15-08:00
New Revision: 69a5869da4906f61caf59ff021559ca7d974c5f9

URL: https://github.com/llvm/llvm-project/commit/69a5869da4906f61caf59ff021559ca7d974c5f9
DIFF: https://github.com/llvm/llvm-project/commit/69a5869da4906f61caf59ff021559ca7d974c5f9.diff

LOG: [lldb][split-dwarf] implement GetSeparateDebugInfo for SymbolFileOnDemand (#71230)

Small change to get `image dump separate-debug-info` working when using
`symbols.load-on-demand`.

Added tests to `TestDumpDwo`, and enabled the test for all platforms. If we fail to build, we skip the test, so this shouldn't cause the test to fail on unsupported platforms.
```
bin/lldb-dotest -p TestDumpDwo
```

It's easy to verify this manually by running 
```
lldb --one-line-before-file "settings set symbols.load-on-demand true" <some_target>
(lldb) image dump separate-debug-info
...
```

---------

Co-authored-by: Tom Yang <toyang at fb.com>

Added: 
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.c
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.c

Modified: 
    lldb/include/lldb/Symbol/SymbolFileOnDemand.h
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/Makefile
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py
    lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py

Removed: 
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.cpp
    lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.cpp


################################################################################
diff  --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
index adf1017ce73c11b..9cbcef2a111d320 100644
--- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -228,6 +228,11 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
     return m_sym_file_impl->SetDebugInfoHadFrameVariableErrors();
   }
 
+  bool GetSeparateDebugInfo(StructuredData::Dictionary &d,
+                            bool errors_only) override {
+    return m_sym_file_impl->GetSeparateDebugInfo(d, errors_only);
+  }
+
   lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name,
                         std::optional<uint64_t> byte_size,
                         SymbolContextScope *context,

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/Makefile b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/Makefile
index 3b6d788b2b0130a..99b3fb3bd7762f7 100644
--- a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/Makefile
+++ b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/Makefile
@@ -1,4 +1,4 @@
-CXX_SOURCES := main.cpp foo.cpp
-CFLAGS_EXTRAS := -gsplit-dwarf
-
 include Makefile.rules
+
+a.out:
+	$(CC) -target x86_64-pc-linux-elf -g -gsplit-dwarf -o $@ $(SRCDIR)/main.c $(SRCDIR)/foo.c

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py
index 163f5a112367693..05c72945b14390e 100644
--- a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py
+++ b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py
@@ -7,6 +7,7 @@
 
 from lldbsuite.test import lldbtest, lldbutil
 from lldbsuite.test.decorators import *
+from lldbsuite.test_event.build_exception import BuildError
 
 
 class TestDumpDWO(lldbtest.TestBase):
@@ -23,14 +24,17 @@ def get_dwos_from_json_output(self):
             result[symfile_entry["symfile"]] = dwo_dict
         return result
 
-    @skipIfRemote
-    @skipIfDarwin
-    @skipIfWindows
+    def build_and_skip_if_error(self):
+        try:
+            self.build()
+        except BuildError as e:
+            self.skipTest(f"Skipping test due to build exception: {e}")
+
     def test_dwos_loaded_json_output(self):
-        self.build()
+        self.build_and_skip_if_error()
         exe = self.getBuildArtifact("a.out")
-        main_dwo = self.getBuildArtifact("main.dwo")
-        foo_dwo = self.getBuildArtifact("foo.dwo")
+        main_dwo = self.getBuildArtifact("a.out-main.dwo")
+        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
 
         # Make sure dwo files exist
         self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
@@ -43,17 +47,14 @@ def test_dwos_loaded_json_output(self):
 
         # Check the output
         output = self.get_dwos_from_json_output()
-        self.assertTrue(output[exe]["main.dwo"]["loaded"])
-        self.assertTrue(output[exe]["foo.dwo"]["loaded"])
+        self.assertTrue(output[exe]["a.out-main.dwo"]["loaded"])
+        self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])
 
-    @skipIfRemote
-    @skipIfDarwin
-    @skipIfWindows
     def test_dwos_not_loaded_json_output(self):
-        self.build()
+        self.build_and_skip_if_error()
         exe = self.getBuildArtifact("a.out")
-        main_dwo = self.getBuildArtifact("main.dwo")
-        foo_dwo = self.getBuildArtifact("foo.dwo")
+        main_dwo = self.getBuildArtifact("a.out-main.dwo")
+        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
 
         # REMOVE one of the dwo files
         os.unlink(main_dwo)
@@ -65,26 +66,23 @@ def test_dwos_not_loaded_json_output(self):
 
         # Check the output
         output = self.get_dwos_from_json_output()
-        self.assertFalse(output[exe]["main.dwo"]["loaded"])
-        self.assertIn("error", output[exe]["main.dwo"])
-        self.assertTrue(output[exe]["foo.dwo"]["loaded"])
-        self.assertNotIn("error", output[exe]["foo.dwo"])
+        self.assertFalse(output[exe]["a.out-main.dwo"]["loaded"])
+        self.assertIn("error", output[exe]["a.out-main.dwo"])
+        self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])
+        self.assertNotIn("error", output[exe]["a.out-foo.dwo"])
 
         # Check with --errors-only
         self.runCmd("target modules dump separate-debug-info --json --errors-only")
         output = self.get_dwos_from_json_output()
-        self.assertFalse(output[exe]["main.dwo"]["loaded"])
-        self.assertIn("error", output[exe]["main.dwo"])
-        self.assertNotIn("foo.dwo", output[exe])
+        self.assertFalse(output[exe]["a.out-main.dwo"]["loaded"])
+        self.assertIn("error", output[exe]["a.out-main.dwo"])
+        self.assertNotIn("a.out-foo.dwo", output[exe])
 
-    @skipIfRemote
-    @skipIfDarwin
-    @skipIfWindows
     def test_dwos_loaded_table_output(self):
-        self.build()
+        self.build_and_skip_if_error()
         exe = self.getBuildArtifact("a.out")
-        main_dwo = self.getBuildArtifact("main.dwo")
-        foo_dwo = self.getBuildArtifact("foo.dwo")
+        main_dwo = self.getBuildArtifact("a.out-main.dwo")
+        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
 
         # Make sure dwo files exist
         self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
@@ -104,14 +102,11 @@ def test_dwos_loaded_table_output(self):
             ],
         )
 
-    @skipIfRemote
-    @skipIfDarwin
-    @skipIfWindows
     def test_dwos_not_loaded_table_output(self):
-        self.build()
+        self.build_and_skip_if_error()
         exe = self.getBuildArtifact("a.out")
-        main_dwo = self.getBuildArtifact("main.dwo")
-        foo_dwo = self.getBuildArtifact("foo.dwo")
+        main_dwo = self.getBuildArtifact("a.out-main.dwo")
+        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
 
         # REMOVE the dwo files
         os.unlink(main_dwo)
@@ -130,3 +125,26 @@ def test_dwos_not_loaded_table_output(self):
                 "0x[a-zA-Z0-9]{16}\s+E\s+.*foo\.dwo",
             ],
         )
+
+    def test_dwos_loaded_symbols_on_demand(self):
+        self.build_and_skip_if_error()
+        exe = self.getBuildArtifact("a.out")
+        main_dwo = self.getBuildArtifact("a.out-main.dwo")
+        foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
+
+        # Make sure dwo files exist
+        self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
+        self.assertTrue(os.path.exists(foo_dwo), f'Make sure "{foo_dwo}" file exists')
+
+        # Load symbols on-demand
+        self.runCmd("settings set symbols.load-on-demand true")
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, lldbtest.VALID_TARGET)
+
+        self.runCmd("target modules dump separate-debug-info --json")
+
+        # Check the output
+        output = self.get_dwos_from_json_output()
+        self.assertTrue(output[exe]["a.out-main.dwo"]["loaded"])
+        self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.cpp b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.c
similarity index 100%
rename from lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.cpp
rename to lldb/test/API/commands/target/dump-separate-debug-info/dwo/foo.c

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.c b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.c
new file mode 100644
index 000000000000000..2505586c52e43a9
--- /dev/null
+++ b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.c
@@ -0,0 +1,3 @@
+#include "foo.h"
+
+int main(void) { return foo(); }

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.cpp b/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.cpp
deleted file mode 100644
index 8087e682432798b..000000000000000
--- a/lldb/test/API/commands/target/dump-separate-debug-info/dwo/main.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "foo.h"
-
-int main() { return foo(); }

diff  --git a/lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py b/lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py
index b69938454659bda..06dc8234591844b 100644
--- a/lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py
+++ b/lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py
@@ -126,3 +126,33 @@ def test_shows_oso_not_loaded_table_output(self):
                 "0x[a-zA-Z0-9]{16}\s+E\s+.*foo\.o",
             ],
         )
+
+    @skipIfRemote
+    @skipUnlessDarwin
+    def test_osos_loaded_symbols_on_demand(self):
+        self.build(debug_info="dwarf")
+        exe = self.getBuildArtifact("a.out")
+        main_o = self.getBuildArtifact("main.o")
+        foo_o = self.getBuildArtifact("foo.o")
+
+        # Make sure o files exist
+        self.assertTrue(os.path.exists(main_o), f'Make sure "{main_o}" file exists')
+        self.assertTrue(os.path.exists(foo_o), f'Make sure "{foo_o}" file exists')
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, lldbtest.VALID_TARGET)
+
+        self.runCmd("target modules dump separate-debug-info --json")
+
+        # Load symbols on-demand
+        self.runCmd("settings set symbols.load-on-demand true")
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, lldbtest.VALID_TARGET)
+
+        self.runCmd("target modules dump separate-debug-info --json")
+
+        # Check the output
+        osos = self.get_osos_from_json_output()
+        self.assertTrue(osos[exe][main_o]["loaded"])
+        self.assertTrue(osos[exe][foo_o]["loaded"])


        


More information about the lldb-commits mailing list