1import contextlib
2import os
3import unittest2
4import lldb
5from lldbsuite.test.decorators import *
6from lldbsuite.test.lldbtest import *
7from lldbsuite.test import lldbutil
8
9
10def haswell():
11    features = subprocess.check_output(["sysctl", "machdep.cpu"])
12    return "AVX2" in features.decode('utf-8')
13
14
15def apple_silicon():
16    features = subprocess.check_output(["sysctl", "machdep.cpu"])
17    return "Apple M" in features.decode('utf-8')
18
19
20@contextlib.contextmanager
21def remove_from_env(var):
22    old_environ = os.environ.copy()
23    del os.environ[var]
24    try:
25        yield
26    finally:
27        os.environ.clear()
28        os.environ.update(old_environ)
29
30
31class TestLaunchProcessPosixSpawn(TestBase):
32    NO_DEBUG_INFO_TESTCASE = True
33    mydir = TestBase.compute_mydir(__file__)
34
35    def no_haswell(self):
36        if not haswell():
37            return "Current CPU is not Haswell"
38        return None
39
40    def no_apple_silicon(self):
41        if not apple_silicon():
42            return "Current CPU is not Apple Silicon"
43        return None
44
45    def run_arch(self, exe, arch):
46        self.runCmd('target create -arch {} {}'.format(arch, exe))
47        self.runCmd('run')
48
49        process = self.dbg.GetSelectedTarget().process
50        self.assertEqual(process.GetState(), lldb.eStateExited)
51        self.assertIn('slice: {}'.format(arch), process.GetSTDOUT(1000))
52
53    @skipUnlessDarwin
54    @skipIfDarwinEmbedded
55    @skipTestIfFn(no_haswell)
56    @skipIfReproducer # Test relies on inferior output
57    def test_haswell(self):
58        self.build()
59        exe = self.getBuildArtifact("fat.out")
60        self.run_arch(exe, 'x86_64')
61        self.run_arch(exe, 'x86_64h')
62
63    @skipUnlessDarwin
64    @skipIfDarwinEmbedded
65    @skipTestIfFn(no_apple_silicon)
66    @skipIfReproducer # Test relies on inferior output
67    def test_apple_silicon(self):
68        self.build()
69        exe = self.getBuildArtifact("fat.out")
70
71        # We need to remove LLDB_DEBUGSERVER_PATH from the environment if it's
72        # set so that the Rosetta debugserver is picked for x86_64.
73        with remove_from_env('LLDB_DEBUGSERVER_PATH'):
74            self.run_arch(exe, 'x86_64')
75            self.run_arch(exe, 'arm64')
76