Skip to content

Commit 0efca1b

Browse files
Kevin Freikevinfrei
Kevin Frei
authored andcommitted
Trying to deal with Linux AArch64 test failures :/
1 parent 8004ce2 commit 0efca1b

File tree

3 files changed

+401
-0
lines changed

3 files changed

+401
-0
lines changed

lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,24 @@ llvm::StringRef SymbolVendorELF::GetPluginDescriptionStatic() {
4444
"executables.";
4545
}
4646

47+
// If this is needed elsewhere, it can be exported/moved.
48+
static bool IsDwpSymbolFile(const lldb::ModuleSP &module_sp,
49+
const FileSpec &file_spec) {
50+
DataBufferSP dwp_file_data_sp;
51+
lldb::offset_t dwp_file_data_offset = 0;
52+
// Try to create an ObjectFile from the file_spec.
53+
ObjectFileSP dwp_obj_file = ObjectFile::FindPlugin(
54+
module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
55+
dwp_file_data_sp, dwp_file_data_offset);
56+
// The presence of a debug_cu_index section is the key identifying feature of
57+
// a DWP file. Make sure we don't fill in the section list on dwp_obj_file
58+
// (by calling GetSectionList(false)) as this is invoked before we may have
59+
// all the symbol files collected and available.
60+
return dwp_obj_file && ObjectFileELF::classof(dwp_obj_file.get()) &&
61+
dwp_obj_file->GetSectionList(false)->FindSectionByType(
62+
eSectionTypeDWARFDebugCuIndex, false);
63+
}
64+
4765
// CreateInstance
4866
//
4967
// Platforms can register a callback to use when creating symbol vendors to
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
import os
2+
import shutil
3+
import tempfile
4+
import struct
5+
6+
import lldb
7+
from lldbsuite.test.decorators import *
8+
import lldbsuite.test.lldbutil as lldbutil
9+
from lldbsuite.test.lldbtest import *
10+
11+
12+
def getUUID(aoutuuid):
13+
"""
14+
Pull the 20 byte UUID out of the .note.gnu.build-id section that was dumped
15+
to a file already, as part of the build.
16+
"""
17+
with open(aoutuuid, "rb") as f:
18+
data = f.read(36)
19+
if len(data) != 36:
20+
return None
21+
header = struct.unpack_from("<4I", data)
22+
if len(header) != 4:
23+
return None
24+
# 4 element 'prefix', 20 bytes of uuid, 3 byte long string: 'GNU':
25+
if header[0] != 4 or header[1] != 20 or header[2] != 3 or header[3] != 0x554E47:
26+
return None
27+
return data[16:].hex()
28+
29+
30+
"""
31+
Test support for the DebugInfoD network symbol acquisition protocol.
32+
This one is for simple / no split-dwarf scenarios.
33+
34+
For no-split-dwarf scenarios, there are 2 variations:
35+
1 - A stripped binary with it's corresponding unstripped binary:
36+
2 - A stripped binary with a corresponding --only-keep-debug symbols file
37+
"""
38+
39+
40+
@skipUnlessPlatform(["linux", "freebsd"])
41+
class DebugInfodTests(TestBase):
42+
# No need to try every flavor of debug inf.
43+
NO_DEBUG_INFO_TESTCASE = True
44+
45+
def test_normal_no_symbols(self):
46+
"""
47+
Validate behavior with no symbols or symbol locator.
48+
('baseline negative' behavior)
49+
"""
50+
test_root = self.config_test(["a.out"])
51+
self.try_breakpoint(False)
52+
53+
def test_normal_default(self):
54+
"""
55+
Validate behavior with symbols, but no symbol locator.
56+
('baseline positive' behavior)
57+
"""
58+
test_root = self.config_test(["a.out", "a.out.debug"])
59+
self.try_breakpoint(True)
60+
61+
def test_debuginfod_symbols(self):
62+
"""
63+
Test behavior with the full binary available from Debuginfod as
64+
'debuginfo' from the plug-in.
65+
"""
66+
test_root = self.config_test(["a.out"], "a.out.full")
67+
self.try_breakpoint(True)
68+
69+
def test_debuginfod_executable(self):
70+
"""
71+
Test behavior with the full binary available from Debuginfod as
72+
'executable' from the plug-in.
73+
"""
74+
test_root = self.config_test(["a.out"], None, "a.out.full")
75+
self.try_breakpoint(True)
76+
77+
def test_debuginfod_okd_symbols(self):
78+
"""
79+
Test behavior with the 'only-keep-debug' symbols available from Debuginfod.
80+
"""
81+
test_root = self.config_test(["a.out"], "a.out.debug")
82+
self.try_breakpoint(True)
83+
84+
def try_breakpoint(self, should_have_loc):
85+
"""
86+
This function creates a target from self.aout, sets a function-name
87+
breakpoint, and checks to see if we have a file/line location,
88+
as a way to validate that the symbols have been loaded.
89+
should_have_loc specifies if we're testing that symbols have or
90+
haven't been loaded.
91+
"""
92+
target = self.dbg.CreateTarget(self.aout)
93+
self.assertTrue(target and target.IsValid(), "Target is valid")
94+
95+
bp = target.BreakpointCreateByName("func")
96+
self.assertTrue(bp and bp.IsValid(), "Breakpoint is valid")
97+
self.assertEqual(bp.GetNumLocations(), 1)
98+
99+
loc = bp.GetLocationAtIndex(0)
100+
self.assertTrue(loc and loc.IsValid(), "Location is valid")
101+
addr = loc.GetAddress()
102+
self.assertTrue(addr and addr.IsValid(), "Loc address is valid")
103+
line_entry = addr.GetLineEntry()
104+
self.assertEqual(
105+
should_have_loc,
106+
line_entry != None and line_entry.IsValid(),
107+
"Loc line entry is valid",
108+
)
109+
if should_have_loc:
110+
self.assertEqual(line_entry.GetLine(), 4)
111+
self.assertEqual(
112+
line_entry.GetFileSpec().GetFilename(),
113+
self.main_source_file.GetFilename(),
114+
)
115+
self.dbg.DeleteTarget(target)
116+
shutil.rmtree(self.tmp_dir)
117+
118+
def config_test(self, local_files, debuginfo=None, executable=None):
119+
"""
120+
Set up a test with local_files[] copied to a different location
121+
so that we control which files are, or are not, found in the file system.
122+
Also, create a stand-alone file-system 'hosted' debuginfod server with the
123+
provided debuginfo and executable files (if they exist)
124+
125+
Make the filesystem look like:
126+
127+
/tmp/<tmpdir>/test/[local_files]
128+
129+
/tmp/<tmpdir>/cache (for lldb to use as a temp cache)
130+
131+
/tmp/<tmpdir>/buildid/<uuid>/executable -> <executable>
132+
/tmp/<tmpdir>/buildid/<uuid>/debuginfo -> <debuginfo>
133+
Returns the /tmp/<tmpdir> path
134+
"""
135+
136+
self.build()
137+
138+
uuid = getUUID(self.getBuildArtifact("a.out.uuid"))
139+
if !uuid:
140+
self.fail("Could not get UUID for a.out")
141+
return
142+
self.main_source_file = lldb.SBFileSpec("main.c")
143+
self.tmp_dir = tempfile.mkdtemp()
144+
test_dir = os.path.join(self.tmp_dir, "test")
145+
os.makedirs(test_dir)
146+
147+
self.aout = ""
148+
# Copy the files used by the test:
149+
for f in local_files:
150+
shutil.copy(self.getBuildArtifact(f), test_dir)
151+
# The first item is the binary to be used for the test
152+
if self.aout == "":
153+
self.aout = os.path.join(test_dir, f)
154+
155+
use_debuginfod = debuginfo != None or executable != None
156+
157+
# Populated the 'file://... mocked' Debuginfod server:
158+
if use_debuginfod:
159+
os.makedirs(os.path.join(self.tmp_dir, "cache"))
160+
uuid_dir = os.path.join(self.tmp_dir, "buildid", uuid)
161+
os.makedirs(uuid_dir)
162+
if debuginfo:
163+
shutil.copy(
164+
self.getBuildArtifact(debuginfo),
165+
os.path.join(uuid_dir, "debuginfo"),
166+
)
167+
if executable:
168+
shutil.copy(
169+
self.getBuildArtifact(executable),
170+
os.path.join(uuid_dir, "executable"),
171+
)
172+
173+
# Configure LLDB for the test:
174+
self.runCmd(
175+
"settings set symbols.enable-external-lookup %s"
176+
% str(use_debuginfod).lower()
177+
)
178+
self.runCmd("settings clear plugin.symbol-locator.debuginfod.server-urls")
179+
if use_debuginfod:
180+
self.runCmd(
181+
"settings set plugin.symbol-locator.debuginfod.cache-path %s/cache"
182+
% self.tmp_dir
183+
)
184+
self.runCmd(
185+
"settings insert-before plugin.symbol-locator.debuginfod.server-urls 0 file://%s"
186+
% self.tmp_dir
187+
)

0 commit comments

Comments
 (0)