-
Notifications
You must be signed in to change notification settings - Fork 13.6k
DebugInfoD tests + fixing issues exposed by tests #85693
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
fc0eda9
Tests (w/fixes) for initial DebugInfoD LLDB integration
edf4924
Skip the tests for non-*nix platforms
972b8e2
Removed an inadvertent auto-formatter change
c2ca52d
Fixed formatting for the Python tests
ba22dea
Address PR feedback from JDevlieghere
2b38c7d
Updated with @clayborg's feedback
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,10 @@ | ||
# Order matters here: the first symbol locator prevents further searching. | ||
# For DWARF binaries that are both stripped and split, the Default plugin | ||
# will return the stripped binary when asked for the ObjectFile, which then | ||
# prevents an unstripped binary from being requested from the Debuginfod | ||
# provider. | ||
add_subdirectory(Debuginfod) | ||
add_subdirectory(Default) | ||
if (CMAKE_SYSTEM_NAME MATCHES "Darwin") | ||
add_subdirectory(DebugSymbols) | ||
endif() | ||
add_subdirectory(Debuginfod) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
C_SOURCES := main.c | ||
|
||
# For normal (non DWP) Debuginfod tests, we need: | ||
|
||
# * The "full" binary: a.out.debug | ||
# Produced by Makefile.rules with KEEP_FULL_DEBUG_BINARY set to YES and | ||
# SPLIT_DEBUG_SYMBOLS set to YES | ||
|
||
# * The stripped binary (a.out) | ||
# Produced by Makefile.rules with SPLIT_DEBUG_SYMBOLS set to YES | ||
|
||
# * The 'only-keep-debug' binary (a.out.dbg) | ||
# Produced below | ||
|
||
# * The .uuid file (for a little easier testing code) | ||
# Produced below | ||
|
||
# Don't strip the debug info from a.out: | ||
SPLIT_DEBUG_SYMBOLS := YES | ||
SAVE_FULL_DEBUG_BINARY := YES | ||
GEN_GNU_BUILD_ID := YES | ||
|
||
all: a.out.uuid a.out | ||
|
||
include Makefile.rules |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,185 @@ | ||
import os | ||
import shutil | ||
import tempfile | ||
import struct | ||
|
||
import lldb | ||
from lldbsuite.test.decorators import * | ||
import lldbsuite.test.lldbutil as lldbutil | ||
from lldbsuite.test.lldbtest import * | ||
|
||
|
||
def getUUID(aoutuuid): | ||
""" | ||
Pull the 20 byte UUID out of the .note.gnu.build-id section that was dumped | ||
to a file already, as part of the build. | ||
""" | ||
with open(aoutuuid, "rb") as f: | ||
data = f.read(36) | ||
if len(data) != 36: | ||
return None | ||
header = struct.unpack_from("<4I", data) | ||
if len(header) != 4: | ||
return None | ||
# 4 element 'prefix', 20 bytes of uuid, 3 byte long string: 'GNU': | ||
if header[0] != 4 or header[1] != 20 or header[2] != 3 or header[3] != 0x554E47: | ||
return None | ||
return data[16:].hex() | ||
|
||
|
||
""" | ||
Test support for the DebugInfoD network symbol acquisition protocol. | ||
This one is for simple / no split-dwarf scenarios. | ||
|
||
For no-split-dwarf scenarios, there are 2 variations: | ||
1 - A stripped binary with it's corresponding unstripped binary: | ||
2 - A stripped binary with a corresponding --only-keep-debug symbols file | ||
""" | ||
|
||
|
||
@skipUnlessPlatform(["linux", "freebsd"]) | ||
class DebugInfodTests(TestBase): | ||
# No need to try every flavor of debug inf. | ||
NO_DEBUG_INFO_TESTCASE = True | ||
|
||
def test_normal_no_symbols(self): | ||
""" | ||
Validate behavior with no symbols or symbol locator. | ||
('baseline negative' behavior) | ||
""" | ||
test_root = self.config_test(["a.out"]) | ||
self.try_breakpoint(False) | ||
|
||
def test_normal_default(self): | ||
""" | ||
Validate behavior with symbols, but no symbol locator. | ||
('baseline positive' behavior) | ||
""" | ||
test_root = self.config_test(["a.out", "a.out.debug"]) | ||
self.try_breakpoint(True) | ||
|
||
def test_debuginfod_symbols(self): | ||
""" | ||
Test behavior with the full binary available from Debuginfod as | ||
'debuginfo' from the plug-in. | ||
""" | ||
test_root = self.config_test(["a.out"], "a.out.full") | ||
self.try_breakpoint(True) | ||
|
||
def test_debuginfod_executable(self): | ||
""" | ||
Test behavior with the full binary available from Debuginfod as | ||
'executable' from the plug-in. | ||
""" | ||
test_root = self.config_test(["a.out"], None, "a.out.full") | ||
self.try_breakpoint(True) | ||
|
||
def test_debuginfod_okd_symbols(self): | ||
""" | ||
Test behavior with the 'only-keep-debug' symbols available from Debuginfod. | ||
""" | ||
test_root = self.config_test(["a.out"], "a.out.debug") | ||
self.try_breakpoint(True) | ||
|
||
def try_breakpoint(self, should_have_loc): | ||
""" | ||
This function creates a target from self.aout, sets a function-name | ||
breakpoint, and checks to see if we have a file/line location, | ||
as a way to validate that the symbols have been loaded. | ||
should_have_loc specifies if we're testing that symbols have or | ||
haven't been loaded. | ||
""" | ||
target = self.dbg.CreateTarget(self.aout) | ||
self.assertTrue(target and target.IsValid(), "Target is valid") | ||
|
||
bp = target.BreakpointCreateByName("func") | ||
self.assertTrue(bp and bp.IsValid(), "Breakpoint is valid") | ||
self.assertEqual(bp.GetNumLocations(), 1) | ||
|
||
loc = bp.GetLocationAtIndex(0) | ||
self.assertTrue(loc and loc.IsValid(), "Location is valid") | ||
addr = loc.GetAddress() | ||
self.assertTrue(addr and addr.IsValid(), "Loc address is valid") | ||
line_entry = addr.GetLineEntry() | ||
self.assertEqual( | ||
should_have_loc, | ||
line_entry != None and line_entry.IsValid(), | ||
"Loc line entry is valid", | ||
) | ||
if should_have_loc: | ||
self.assertEqual(line_entry.GetLine(), 4) | ||
self.assertEqual( | ||
line_entry.GetFileSpec().GetFilename(), | ||
self.main_source_file.GetFilename(), | ||
) | ||
self.dbg.DeleteTarget(target) | ||
shutil.rmtree(self.tmp_dir) | ||
|
||
def config_test(self, local_files, debuginfo=None, executable=None): | ||
""" | ||
Set up a test with local_files[] copied to a different location | ||
so that we control which files are, or are not, found in the file system. | ||
Also, create a stand-alone file-system 'hosted' debuginfod server with the | ||
provided debuginfo and executable files (if they exist) | ||
|
||
Make the filesystem look like: | ||
|
||
/tmp/<tmpdir>/test/[local_files] | ||
|
||
/tmp/<tmpdir>/cache (for lldb to use as a temp cache) | ||
|
||
/tmp/<tmpdir>/buildid/<uuid>/executable -> <executable> | ||
/tmp/<tmpdir>/buildid/<uuid>/debuginfo -> <debuginfo> | ||
Returns the /tmp/<tmpdir> path | ||
""" | ||
|
||
self.build() | ||
|
||
uuid = getUUID(self.getBuildArtifact("a.out.uuid")) | ||
|
||
self.main_source_file = lldb.SBFileSpec("main.c") | ||
self.tmp_dir = tempfile.mkdtemp() | ||
test_dir = os.path.join(self.tmp_dir, "test") | ||
os.makedirs(test_dir) | ||
|
||
self.aout = "" | ||
# Copy the files used by the test: | ||
for f in local_files: | ||
shutil.copy(self.getBuildArtifact(f), test_dir) | ||
# The first item is the binary to be used for the test | ||
if self.aout == "": | ||
self.aout = os.path.join(test_dir, f) | ||
|
||
use_debuginfod = debuginfo != None or executable != None | ||
|
||
# Populated the 'file://... mocked' Debuginfod server: | ||
if use_debuginfod: | ||
os.makedirs(os.path.join(self.tmp_dir, "cache")) | ||
uuid_dir = os.path.join(self.tmp_dir, "buildid", uuid) | ||
os.makedirs(uuid_dir) | ||
if debuginfo: | ||
shutil.copy( | ||
self.getBuildArtifact(debuginfo), | ||
os.path.join(uuid_dir, "debuginfo"), | ||
) | ||
if executable: | ||
shutil.copy( | ||
self.getBuildArtifact(executable), | ||
os.path.join(uuid_dir, "executable"), | ||
) | ||
|
||
# Configure LLDB for the test: | ||
self.runCmd( | ||
"settings set symbols.enable-external-lookup %s" | ||
% str(use_debuginfod).lower() | ||
) | ||
self.runCmd("settings clear plugin.symbol-locator.debuginfod.server-urls") | ||
if use_debuginfod: | ||
self.runCmd( | ||
"settings set plugin.symbol-locator.debuginfod.cache-path %s/cache" | ||
% self.tmp_dir | ||
) | ||
self.runCmd( | ||
"settings insert-before plugin.symbol-locator.debuginfod.server-urls 0 file://%s" | ||
% self.tmp_dir | ||
) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.