Skip to content

Commit 69a5869

Browse files
zhytyTom Yang
andauthored
[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 <[email protected]>
1 parent f4c6947 commit 69a5869

File tree

7 files changed

+92
-39
lines changed

7 files changed

+92
-39
lines changed

lldb/include/lldb/Symbol/SymbolFileOnDemand.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
228228
return m_sym_file_impl->SetDebugInfoHadFrameVariableErrors();
229229
}
230230

231+
bool GetSeparateDebugInfo(StructuredData::Dictionary &d,
232+
bool errors_only) override {
233+
return m_sym_file_impl->GetSeparateDebugInfo(d, errors_only);
234+
}
235+
231236
lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name,
232237
std::optional<uint64_t> byte_size,
233238
SymbolContextScope *context,
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CXX_SOURCES := main.cpp foo.cpp
2-
CFLAGS_EXTRAS := -gsplit-dwarf
3-
41
include Makefile.rules
2+
3+
a.out:
4+
$(CC) -target x86_64-pc-linux-elf -g -gsplit-dwarf -o $@ $(SRCDIR)/main.c $(SRCDIR)/foo.c

lldb/test/API/commands/target/dump-separate-debug-info/dwo/TestDumpDwo.py

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from lldbsuite.test import lldbtest, lldbutil
99
from lldbsuite.test.decorators import *
10+
from lldbsuite.test_event.build_exception import BuildError
1011

1112

1213
class TestDumpDWO(lldbtest.TestBase):
@@ -23,14 +24,17 @@ def get_dwos_from_json_output(self):
2324
result[symfile_entry["symfile"]] = dwo_dict
2425
return result
2526

26-
@skipIfRemote
27-
@skipIfDarwin
28-
@skipIfWindows
27+
def build_and_skip_if_error(self):
28+
try:
29+
self.build()
30+
except BuildError as e:
31+
self.skipTest(f"Skipping test due to build exception: {e}")
32+
2933
def test_dwos_loaded_json_output(self):
30-
self.build()
34+
self.build_and_skip_if_error()
3135
exe = self.getBuildArtifact("a.out")
32-
main_dwo = self.getBuildArtifact("main.dwo")
33-
foo_dwo = self.getBuildArtifact("foo.dwo")
36+
main_dwo = self.getBuildArtifact("a.out-main.dwo")
37+
foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
3438

3539
# Make sure dwo files exist
3640
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):
4347

4448
# Check the output
4549
output = self.get_dwos_from_json_output()
46-
self.assertTrue(output[exe]["main.dwo"]["loaded"])
47-
self.assertTrue(output[exe]["foo.dwo"]["loaded"])
50+
self.assertTrue(output[exe]["a.out-main.dwo"]["loaded"])
51+
self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])
4852

49-
@skipIfRemote
50-
@skipIfDarwin
51-
@skipIfWindows
5253
def test_dwos_not_loaded_json_output(self):
53-
self.build()
54+
self.build_and_skip_if_error()
5455
exe = self.getBuildArtifact("a.out")
55-
main_dwo = self.getBuildArtifact("main.dwo")
56-
foo_dwo = self.getBuildArtifact("foo.dwo")
56+
main_dwo = self.getBuildArtifact("a.out-main.dwo")
57+
foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
5758

5859
# REMOVE one of the dwo files
5960
os.unlink(main_dwo)
@@ -65,26 +66,23 @@ def test_dwos_not_loaded_json_output(self):
6566

6667
# Check the output
6768
output = self.get_dwos_from_json_output()
68-
self.assertFalse(output[exe]["main.dwo"]["loaded"])
69-
self.assertIn("error", output[exe]["main.dwo"])
70-
self.assertTrue(output[exe]["foo.dwo"]["loaded"])
71-
self.assertNotIn("error", output[exe]["foo.dwo"])
69+
self.assertFalse(output[exe]["a.out-main.dwo"]["loaded"])
70+
self.assertIn("error", output[exe]["a.out-main.dwo"])
71+
self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])
72+
self.assertNotIn("error", output[exe]["a.out-foo.dwo"])
7273

7374
# Check with --errors-only
7475
self.runCmd("target modules dump separate-debug-info --json --errors-only")
7576
output = self.get_dwos_from_json_output()
76-
self.assertFalse(output[exe]["main.dwo"]["loaded"])
77-
self.assertIn("error", output[exe]["main.dwo"])
78-
self.assertNotIn("foo.dwo", output[exe])
77+
self.assertFalse(output[exe]["a.out-main.dwo"]["loaded"])
78+
self.assertIn("error", output[exe]["a.out-main.dwo"])
79+
self.assertNotIn("a.out-foo.dwo", output[exe])
7980

80-
@skipIfRemote
81-
@skipIfDarwin
82-
@skipIfWindows
8381
def test_dwos_loaded_table_output(self):
84-
self.build()
82+
self.build_and_skip_if_error()
8583
exe = self.getBuildArtifact("a.out")
86-
main_dwo = self.getBuildArtifact("main.dwo")
87-
foo_dwo = self.getBuildArtifact("foo.dwo")
84+
main_dwo = self.getBuildArtifact("a.out-main.dwo")
85+
foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
8886

8987
# Make sure dwo files exist
9088
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):
104102
],
105103
)
106104

107-
@skipIfRemote
108-
@skipIfDarwin
109-
@skipIfWindows
110105
def test_dwos_not_loaded_table_output(self):
111-
self.build()
106+
self.build_and_skip_if_error()
112107
exe = self.getBuildArtifact("a.out")
113-
main_dwo = self.getBuildArtifact("main.dwo")
114-
foo_dwo = self.getBuildArtifact("foo.dwo")
108+
main_dwo = self.getBuildArtifact("a.out-main.dwo")
109+
foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
115110

116111
# REMOVE the dwo files
117112
os.unlink(main_dwo)
@@ -130,3 +125,26 @@ def test_dwos_not_loaded_table_output(self):
130125
"0x[a-zA-Z0-9]{16}\s+E\s+.*foo\.dwo",
131126
],
132127
)
128+
129+
def test_dwos_loaded_symbols_on_demand(self):
130+
self.build_and_skip_if_error()
131+
exe = self.getBuildArtifact("a.out")
132+
main_dwo = self.getBuildArtifact("a.out-main.dwo")
133+
foo_dwo = self.getBuildArtifact("a.out-foo.dwo")
134+
135+
# Make sure dwo files exist
136+
self.assertTrue(os.path.exists(main_dwo), f'Make sure "{main_dwo}" file exists')
137+
self.assertTrue(os.path.exists(foo_dwo), f'Make sure "{foo_dwo}" file exists')
138+
139+
# Load symbols on-demand
140+
self.runCmd("settings set symbols.load-on-demand true")
141+
142+
target = self.dbg.CreateTarget(exe)
143+
self.assertTrue(target, lldbtest.VALID_TARGET)
144+
145+
self.runCmd("target modules dump separate-debug-info --json")
146+
147+
# Check the output
148+
output = self.get_dwos_from_json_output()
149+
self.assertTrue(output[exe]["a.out-main.dwo"]["loaded"])
150+
self.assertTrue(output[exe]["a.out-foo.dwo"]["loaded"])
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#include "foo.h"
2+
3+
int main(void) { return foo(); }

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

Lines changed: 0 additions & 3 deletions
This file was deleted.

lldb/test/API/commands/target/dump-separate-debug-info/oso/TestDumpOso.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,33 @@ def test_shows_oso_not_loaded_table_output(self):
126126
"0x[a-zA-Z0-9]{16}\s+E\s+.*foo\.o",
127127
],
128128
)
129+
130+
@skipIfRemote
131+
@skipUnlessDarwin
132+
def test_osos_loaded_symbols_on_demand(self):
133+
self.build(debug_info="dwarf")
134+
exe = self.getBuildArtifact("a.out")
135+
main_o = self.getBuildArtifact("main.o")
136+
foo_o = self.getBuildArtifact("foo.o")
137+
138+
# Make sure o files exist
139+
self.assertTrue(os.path.exists(main_o), f'Make sure "{main_o}" file exists')
140+
self.assertTrue(os.path.exists(foo_o), f'Make sure "{foo_o}" file exists')
141+
142+
target = self.dbg.CreateTarget(exe)
143+
self.assertTrue(target, lldbtest.VALID_TARGET)
144+
145+
self.runCmd("target modules dump separate-debug-info --json")
146+
147+
# Load symbols on-demand
148+
self.runCmd("settings set symbols.load-on-demand true")
149+
150+
target = self.dbg.CreateTarget(exe)
151+
self.assertTrue(target, lldbtest.VALID_TARGET)
152+
153+
self.runCmd("target modules dump separate-debug-info --json")
154+
155+
# Check the output
156+
osos = self.get_osos_from_json_output()
157+
self.assertTrue(osos[exe][main_o]["loaded"])
158+
self.assertTrue(osos[exe][foo_o]["loaded"])

0 commit comments

Comments
 (0)