brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.3 KiB · 437c83a Raw
197 lines · python
1"""2Test support for the DebugInfoD network symbol acquisition protocol.3"""4import os5import shutil6import tempfile7 8import lldb9from lldbsuite.test.decorators import *10import lldbsuite.test.lldbutil as lldbutil11from lldbsuite.test.lldbtest import *12 13 14"""15Test support for the DebugInfoD network symbol acquisition protocol.16This file is for split-dwarf (dwp) scenarios.17 181 - A split binary target with it's corresponding DWP file192 - A stripped, split binary target with an unstripped binary and a DWP file203 - A stripped, split binary target with an --only-keep-debug symbols file and a DWP file21"""22 23 24class DebugInfodDWPTests(TestBase):25    # No need to try every flavor of debug inf.26    NO_DEBUG_INFO_TESTCASE = True27 28    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])29    def test_normal_stripped(self):30        """31        Validate behavior with a stripped binary, no symbols or symbol locator.32        """33        self.config_test(["a.out"])34        self.try_breakpoint(False)35 36    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])37    def test_normal_stripped_split_with_dwp(self):38        """39        Validate behavior with symbols, but no symbol locator.40        """41        self.config_test(["a.out", "a.out.debug", "a.out.dwp"])42        self.try_breakpoint(True)43 44    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])45    def test_normal_stripped_only_dwp(self):46        """47        Validate behavior *with* dwp symbols only, but missing other symbols,48        but no symbol locator. This shouldn't work: without the other symbols49        DWO's appear mostly useless.50        """51        self.config_test(["a.out", "a.out.dwp"])52        self.try_breakpoint(False)53 54    @skipIfCurlSupportMissing55    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])56    def test_debuginfod_dwp_from_service(self):57        """58        Test behavior with the unstripped binary, and DWP from the service.59        """60        self.config_test(["a.out.debug"], "a.out.dwp")61        self.try_breakpoint(True)62 63    @skipIfCurlSupportMissing64    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])65    def test_debuginfod_both_symfiles_from_service(self):66        """67        Test behavior with a stripped binary, with the unstripped binary and68        dwp symbols from Debuginfod.69        """70        self.config_test(["a.out"], "a.out.dwp", "a.out.unstripped")71        self.try_breakpoint(True)72 73    @skipIfCurlSupportMissing74    @skipUnlessPlatform(["linux_freebsd_but_old_dwp_tools_on_build_bots_are_broken"])75    def test_debuginfod_both_okd_symfiles_from_service(self):76        """77        Test behavior with both the only-keep-debug symbols and the dwp symbols78        from Debuginfod.79        """80        self.config_test(["a.out"], "a.out.dwp", "a.out.debug")81        self.try_breakpoint(True)82 83    def try_breakpoint(self, should_have_loc):84        """85        This function creates a target from self.aout, sets a function-name86        breakpoint, and checks to see if we have a file/line location,87        as a way to validate that the symbols have been loaded.88        should_have_loc specifies if we're testing that symbols have or89        haven't been loaded.90        """91        target = self.dbg.CreateTarget(self.aout)92        self.assertTrue(target and target.IsValid(), "Target is valid")93 94        bp = target.BreakpointCreateByName("func")95        self.assertTrue(bp and bp.IsValid(), "Breakpoint is valid")96        self.assertEqual(bp.GetNumLocations(), 1)97 98        loc = bp.GetLocationAtIndex(0)99        self.assertTrue(loc and loc.IsValid(), "Location is valid")100        addr = loc.GetAddress()101        self.assertTrue(addr and addr.IsValid(), "Loc address is valid")102        line_entry = addr.GetLineEntry()103        self.assertEqual(104            should_have_loc,105            line_entry != None and line_entry.IsValid(),106            "Loc line entry is valid",107        )108        if should_have_loc:109            self.assertEqual(line_entry.GetLine(), 4)110            self.assertEqual(111                line_entry.GetFileSpec().GetFilename(),112                self.main_source_file.GetFilename(),113            )114        self.dbg.DeleteTarget(target)115        shutil.rmtree(self.tmp_dir)116 117    def config_test(self, local_files, debuginfo=None, executable=None):118        """119        Set up a test with local_files[] copied to a different location120        so that we control which files are, or are not, found in the file system.121        Also, create a stand-alone file-system 'hosted' debuginfod server with the122        provided debuginfo and executable files (if they exist)123 124        Make the filesystem look like:125 126        /tmp/<tmpdir>/test/[local_files]127 128        /tmp/<tmpdir>/cache (for lldb to use as a temp cache)129 130        /tmp/<tmpdir>/buildid/<uuid>/executable -> <executable>131        /tmp/<tmpdir>/buildid/<uuid>/debuginfo -> <debuginfo>132        Returns the /tmp/<tmpdir> path133        """134 135        self.build()136 137        uuid = self.getUUID("a.out")138        if not uuid:139            self.fail("Could not get UUID for a.out")140            return141        self.main_source_file = lldb.SBFileSpec("main.c")142        self.tmp_dir = tempfile.mkdtemp()143        self.test_dir = os.path.join(self.tmp_dir, "test")144        os.makedirs(self.test_dir)145 146        self.aout = ""147        # Copy the files used by the test:148        for f in local_files:149            shutil.copy(self.getBuildArtifact(f), self.test_dir)150            if self.aout == "":151                self.aout = os.path.join(self.test_dir, f)152 153        use_debuginfod = debuginfo != None or executable != None154 155        # Populated the 'file://... mocked' Debuginfod server:156        if use_debuginfod:157            os.makedirs(os.path.join(self.tmp_dir, "cache"))158            uuid_dir = os.path.join(self.tmp_dir, "buildid", uuid)159            os.makedirs(uuid_dir)160            if debuginfo:161                shutil.copy(162                    self.getBuildArtifact(debuginfo),163                    os.path.join(uuid_dir, "debuginfo"),164                )165            if executable:166                shutil.copy(167                    self.getBuildArtifact(executable),168                    os.path.join(uuid_dir, "executable"),169                )170        os.remove(self.getBuildArtifact("main.dwo"))171        # Configure LLDB for the test:172        self.runCmd(173            "settings set symbols.enable-external-lookup %s"174            % str(use_debuginfod).lower()175        )176        self.runCmd("settings clear plugin.symbol-locator.debuginfod.server-urls")177        if use_debuginfod:178            self.runCmd(179                "settings set plugin.symbol-locator.debuginfod.cache-path %s/cache"180                % self.tmp_dir181            )182            self.runCmd(183                "settings insert-before plugin.symbol-locator.debuginfod.server-urls 0 file://%s"184                % self.tmp_dir185            )186 187    def getUUID(self, filename):188        try:189            spec = lldb.SBModuleSpec()190            spec.SetFileSpec(lldb.SBFileSpec(self.getBuildArtifact(filename)))191            module = lldb.SBModule(spec)192            uuid = module.GetUUIDString().replace("-", "").lower()193            # Don't want lldb's fake 32 bit CRC's for this one194            return uuid if len(uuid) > 8 else None195        except:196            return None197