brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · bc19c69 Raw
163 lines · python
1"""Test that lldb can create a skinny corefile, and load all available libraries correctly."""2 3 4import os5import re6import subprocess7 8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbutil12 13 14class TestSkinnyCorefile(TestBase):15    @skipIf(16        debug_info=no_match(["dsym"]),17        bugnumber="This test is looking explicitly for a dSYM",18    )19    @skipUnlessDarwin20    @skipIfRemote21    def test_lc_note(self):22        self.build()23        self.aout_exe = self.getBuildArtifact("a.out")24        self.aout_dsym = self.getBuildArtifact("a.out.dSYM")25        self.to_be_removed_dylib = self.getBuildArtifact("libto-be-removed.dylib")26        self.to_be_removed_dsym = self.getBuildArtifact("libto-be-removed.dylib.dSYM")27        self.corefile = self.getBuildArtifact("process.core")28        self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")29 30        # After the corefile is created, we'll move a.out and a.out.dSYM31        # into hide.noindex and lldb will have to use the32        # LLDB_APPLE_DSYMFORUUID_EXECUTABLE script to find them.33        self.hide_dir = self.getBuildArtifact("hide.noindex")34        lldbutil.mkdir_p(self.hide_dir)35        self.hide_aout_exe = self.getBuildArtifact("hide.noindex/a.out")36        self.hide_aout_dsym = self.getBuildArtifact("hide.noindex/a.out.dSYM")37 38        # We can hook in our dsym-for-uuid shell script to lldb with39        # this env var instead of requiring a defaults write.40        os.environ["LLDB_APPLE_DSYMFORUUID_EXECUTABLE"] = self.dsym_for_uuid41        self.addTearDownHook(42            lambda: os.environ.pop("LLDB_APPLE_DSYMFORUUID_EXECUTABLE", None)43        )44 45        dwarfdump_uuid_regex = re.compile(r"UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*")46        dwarfdump_cmd_output = subprocess.check_output(47            ('/usr/bin/dwarfdump --uuid "%s"' % self.aout_exe), shell=True48        ).decode("utf-8")49        aout_uuid = None50        for line in dwarfdump_cmd_output.splitlines():51            match = dwarfdump_uuid_regex.search(line)52            if match:53                aout_uuid = match.group(1)54        self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out")55 56        ###  Create our dsym-for-uuid shell script which returns self.hide_aout_exe.57        shell_cmds = [58            "#! /bin/sh",59            "# the last argument is the uuid",60            "while [ $# -gt 1 ]",61            "do",62            "  shift",63            "done",64            "ret=0",65            'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',66            'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',67            'echo "<plist version=\\"1.0\\">"',68            "",69            'if [ "$1" = "%s" ]' % aout_uuid,70            "then",71            "  uuid=%s" % aout_uuid,72            "  bin=%s" % self.hide_aout_exe,73            "  dsym=%s.dSYM/Contents/Resources/DWARF/%s"74            % (self.hide_aout_exe, os.path.basename(self.hide_aout_exe)),75            "fi",76            'if [ -z "$uuid" -o -z "$bin" -o ! -f "$bin" ]',77            "then",78            '  echo "<key>DBGError</key><string>not found</string>"',79            '  echo "</plist>"',80            "  exit 1",81            "fi",82            'echo "<dict><key>$uuid</key><dict>"',83            "",84            'echo "<key>DBGArchitecture</key><string>x86_64</string>"',85            'echo "<key>DBGDSYMPath</key><string>$dsym</string>"',86            'echo "<key>DBGSymbolRichExecutable</key><string>$bin</string>"',87            'echo "</dict></dict></plist>"',88            "exit $ret",89        ]90 91        with open(self.dsym_for_uuid, "w") as writer:92            for l in shell_cmds:93                writer.write(l + "\n")94 95        os.chmod(self.dsym_for_uuid, 0o755)96 97        # Launch a live process with a.out, libto-be-removed.dylib,98        # libpresent.dylib all in their original locations, create99        # a corefile at the breakpoint.100        (target, process, t, bp) = lldbutil.run_to_source_breakpoint(101            self, "break here", lldb.SBFileSpec("present.c")102        )103 104        self.assertTrue(process.IsValid())105 106        if self.TraceOn():107            self.runCmd("bt")108            self.runCmd("image list")109 110        self.runCmd("process save-core " + self.corefile)111        process.Kill()112        target.Clear()113 114        # Move the main binary and its dSYM into the hide.noindex115        # directory.  Now the only way lldb can find them is with116        # the LLDB_APPLE_DSYMFORUUID_EXECUTABLE shell script -117        # so we're testing that this dSYM discovery method works.118        os.rename(self.aout_exe, self.hide_aout_exe)119        os.rename(self.aout_dsym, self.hide_aout_dsym)120 121        # Completely remove the libto-be-removed.dylib, so we're122        # testing that lldb handles an unavailable binary correctly,123        # and non-dirty memory from this binary (e.g. the executing124        # instructions) are NOT included in the corefile.125        os.unlink(self.to_be_removed_dylib)126        shutil.rmtree(self.to_be_removed_dsym)127 128        # Now load the corefile129        self.target = self.dbg.CreateTarget("")130        self.process = self.target.LoadCore(self.corefile)131        self.assertTrue(self.process.IsValid())132        if self.TraceOn():133            self.runCmd("image list")134            self.runCmd("bt")135 136        self.assertTrue(self.process.IsValid())137        self.assertTrue(self.process.GetSelectedThread().IsValid())138 139        # f0 is present() in libpresent.dylib140        f0 = self.process.GetSelectedThread().GetFrameAtIndex(0)141        to_be_removed_dirty_data = f0.FindVariable("to_be_removed_dirty_data")142        self.assertEqual(to_be_removed_dirty_data.GetValueAsUnsigned(), 20)143 144        present_heap_buf = f0.FindVariable("present_heap_buf")145        self.assertIn("have ints 5 20 20 5", present_heap_buf.GetSummary())146 147        # f1 is to_be_removed() in libto-be-removed.dylib148        # it has been removed since the corefile was created,149        # and the instructions for this frame should NOT be included150        # in the corefile.  They were not dirty pages.151        f1 = self.process.GetSelectedThread().GetFrameAtIndex(1)152        err = lldb.SBError()153        uint = self.process.ReadUnsignedFromMemory(f1.GetPC(), 4, err)154        self.assertTrue(err.Fail())155 156        # TODO Future testing could check that read-only constant data157        # (main_const_data, present_const_data) can be read both as an158        # SBValue and in an expression -- which means lldb needs to read159        # them out of the binaries, they are not present in the corefile.160        # And checking file-scope dirty data (main_dirty_data,161        # present_dirty_data) the same way would be good, instead of just162        # checking the heap and stack like are being done right now.163