1"""Test that corefiles with an LC_NOTE "kern ver str" load command is used."""
2
3
4
5import os
6import re
7import subprocess
8
9import lldb
10from lldbsuite.test.decorators import *
11from lldbsuite.test.lldbtest import *
12from lldbsuite.test import lldbutil
13
14
15class TestKernVerStrLCNOTE(TestBase):
16
17    @skipIf(debug_info=no_match(["dsym"]), bugnumber="This test is looking explicitly for a dSYM")
18    @skipIf(archs=no_match(['x86_64']))
19    @skipUnlessDarwin
20    def test_lc_note(self):
21        self.build()
22        self.test_exe = self.getBuildArtifact("a.out")
23        self.create_corefile = self.getBuildArtifact("create-empty-corefile")
24        self.dsym_for_uuid = self.getBuildArtifact("dsym-for-uuid.sh")
25        self.corefile = self.getBuildArtifact("core")
26
27        ## We can hook in our dsym-for-uuid shell script to lldb with this env
28        ## var instead of requiring a defaults write.
29        os.environ['LLDB_APPLE_DSYMFORUUID_EXECUTABLE'] = self.dsym_for_uuid
30        self.addTearDownHook(lambda: os.environ.pop('LLDB_APPLE_DSYMFORUUID_EXECUTABLE', None))
31
32        dwarfdump_uuid_regex = re.compile(
33            'UUID: ([-0-9a-fA-F]+) \(([^\(]+)\) .*')
34        dwarfdump_cmd_output = subprocess.check_output(
35                ('/usr/bin/dwarfdump --uuid "%s"' % self.test_exe), shell=True).decode("utf-8")
36        aout_uuid = None
37        for line in dwarfdump_cmd_output.splitlines():
38            match = dwarfdump_uuid_regex.search(line)
39            if match:
40                aout_uuid = match.group(1)
41        self.assertNotEqual(aout_uuid, None, "Could not get uuid of built a.out")
42
43        ###  Create our dsym-for-uuid shell script which returns self.test_exe
44        ###  and its dSYM when given self.test_exe's UUID.
45        shell_cmds = [
46                '#! /bin/sh',
47                'ret=0',
48                'echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?>"',
49                'echo "<!DOCTYPE plist PUBLIC \\"-//Apple//DTD PLIST 1.0//EN\\" \\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\">"',
50                'echo "<plist version=\\"1.0\\">"',
51                '',
52                '# the last argument is probably the uuid',
53                'while [ $# -gt 1 ]',
54                'do',
55                '  shift',
56                'done',
57                'echo "<dict><key>$1</key><dict>"',
58                '',
59                'if [ "$1" = "%s" ]' % aout_uuid,
60                'then',
61                '  echo "<key>DBGArchitecture</key><string>x86_64</string>"',
62                '  echo "<key>DBGDSYMPath</key><string>%s.dSYM/Contents/Resources/DWARF/%s</string>"' % (self.test_exe, os.path.basename(self.test_exe)),
63                '  echo "<key>DBGSymbolRichExecutable</key><string>%s</string>"' % self.test_exe,
64                'else',
65                '  echo "<key>DBGError</key><string>not found</string>"',
66                '  ret=1',
67                'fi',
68                'echo "</dict></dict></plist>"',
69                'exit $ret'
70                ]
71
72        with open(self.dsym_for_uuid, "w") as writer:
73            for l in shell_cmds:
74                writer.write(l + '\n')
75
76        os.chmod(self.dsym_for_uuid, 0o755)
77
78        ### Create our corefile
79        retcode = call(self.create_corefile + " " +  self.corefile + " " + self.test_exe, shell=True)
80
81        ### Now run lldb on the corefile
82        ### which will give us a UUID
83        ### which we call dsym-for-uuid.sh with
84        ### which gives us a binary and dSYM
85        ### which lldb should load!
86
87
88        self.target = self.dbg.CreateTarget('')
89        err = lldb.SBError()
90        self.process = self.target.LoadCore(self.corefile)
91        self.assertEqual(self.process.IsValid(), True)
92        if self.TraceOn():
93            self.runCmd("image list")
94        self.assertEqual(self.target.GetNumModules(), 1)
95        fspec = self.target.GetModuleAtIndex(0).GetFileSpec()
96        filepath = fspec.GetDirectory() + "/" + fspec.GetFilename()
97        self.assertEqual(filepath, self.test_exe)
98