forked from OSchip/llvm-project
[lldb] Read from the Rosetta shared cache with Xcode 14
Xcode 14 no longer puts the Rosetta expanded shared cache in a directory named "16.0". Instead, it includes the real version number (e.g. 13.0), the build string and the architecture, similar to the device support directory names for iOS, tvOS and watchOS. Currently, when there are multiple directories, we might end up picking the wrong one in GetSDKDirectoryForCurrentOSVersion. The problem is that without the build string we have no way to differentiate between multiple directories with the same version number. This patch fixes the problem by using GetOSBuildString which, as the name implies, returns the build string if known. This also adds a test for Rosetta debugging on Apple Silicon. Depending on whether the Rosetta expanded shared cache is present, the test ensures that there is or isn't a diagnostic about reading out of memory. rdar://97576121 Differential revision: https://reviews.llvm.org/D130540
This commit is contained in:
parent
98647330bf
commit
ecda408178
|
@ -698,6 +698,17 @@ def skipIfTargetAndroid(bugnumber=None, api_levels=None, archs=None):
|
|||
archs),
|
||||
bugnumber)
|
||||
|
||||
def skipUnlessAppleSilicon(func):
|
||||
"""Decorate the item to skip tests unless running on Apple Silicon."""
|
||||
def not_apple_silicon(test):
|
||||
if platform.system() != 'Darwin' or test.getArchitecture() not in [
|
||||
'arm64', 'arm64e'
|
||||
]:
|
||||
return "Test only runs on Apple Silicon"
|
||||
return None
|
||||
|
||||
return skipTestIfFn(not_apple_silicon)(func)
|
||||
|
||||
def skipUnlessSupportedTypeAttribute(attr):
|
||||
"""Decorate the item to skip test unless Clang supports type __attribute__(attr)."""
|
||||
def compiler_doesnt_support_struct_attribute(self):
|
||||
|
|
|
@ -148,11 +148,20 @@ PlatformDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
|
|||
uint32_t i;
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
const uint32_t num_sdk_infos = m_sdk_directory_infos.size();
|
||||
|
||||
// Check to see if the user specified a build string. If they did, then be
|
||||
// sure to match it.
|
||||
std::vector<bool> check_sdk_info(num_sdk_infos, true);
|
||||
ConstString build(m_sdk_build);
|
||||
|
||||
// Prefer the user SDK build string.
|
||||
ConstString build = GetSDKBuild();
|
||||
|
||||
// Fall back to the platform's build string.
|
||||
if (!build) {
|
||||
if (llvm::Optional<std::string> os_build_str = GetOSBuildString()) {
|
||||
build = ConstString(*os_build_str);
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a build string, only check platforms for which the build
|
||||
// string matches.
|
||||
if (build) {
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
check_sdk_info[i] = m_sdk_directory_infos[i].build == build;
|
||||
|
@ -163,14 +172,14 @@ PlatformDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
|
|||
llvm::VersionTuple version = GetOSVersion();
|
||||
if (!version.empty()) {
|
||||
if (UpdateSDKDirectoryInfosIfNeeded()) {
|
||||
// First try for an exact match of major, minor and update
|
||||
// First try for an exact match of major, minor and update.
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version == version)
|
||||
return &m_sdk_directory_infos[i];
|
||||
}
|
||||
}
|
||||
// First try for an exact match of major and minor
|
||||
// Try for an exact match of major and minor.
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version.getMajor() ==
|
||||
|
@ -181,7 +190,7 @@ PlatformDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Lastly try to match of major version only..
|
||||
// Lastly try to match of major version only.
|
||||
for (i = 0; i < num_sdk_infos; ++i) {
|
||||
if (check_sdk_info[i]) {
|
||||
if (m_sdk_directory_infos[i].version.getMajor() ==
|
||||
|
@ -192,7 +201,7 @@ PlatformDarwinDevice::GetSDKDirectoryForCurrentOSVersion() {
|
|||
}
|
||||
}
|
||||
} else if (build) {
|
||||
// No version, just a build number, search for the first one that matches
|
||||
// No version, just a build number, return the first one that matches.
|
||||
for (i = 0; i < num_sdk_infos; ++i)
|
||||
if (check_sdk_info[i])
|
||||
return &m_sdk_directory_infos[i];
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
C_SOURCES := main.c
|
||||
override ARCH = x86_64
|
||||
|
||||
include Makefile.rules
|
|
@ -0,0 +1,55 @@
|
|||
import re
|
||||
import lldb
|
||||
import lldbsuite.test.lldbutil as lldbutil
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test.decorators import *
|
||||
|
||||
|
||||
def get_os_version():
|
||||
try:
|
||||
os_version_str = subprocess.check_output(["sysctl", "kern.osversion"
|
||||
]).decode('utf-8')
|
||||
except subprocess.CalledProcessError:
|
||||
return None
|
||||
m = re.match(r'kern\.osversion: (\w+)', os_version_str)
|
||||
if m:
|
||||
return m.group(1)
|
||||
return None
|
||||
|
||||
|
||||
def has_rosetta_shared_cache(os_version):
|
||||
if not os_version:
|
||||
return False
|
||||
macos_device_support = os.path.join(os.path.expanduser("~"), 'Library',
|
||||
'Developer', 'Xcode',
|
||||
'macOS DeviceSupport')
|
||||
for _, subdirs, _ in os.walk(macos_device_support):
|
||||
for subdir in subdirs:
|
||||
if os_version in subdir:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class TestRosetta(TestBase):
|
||||
|
||||
NO_DEBUG_INFO_TESTCASE = True
|
||||
|
||||
@skipUnlessAppleSilicon
|
||||
def test_rosetta(self):
|
||||
"""There can be many tests in a test case - describe this test here."""
|
||||
self.build()
|
||||
self.main_source_file = lldb.SBFileSpec("main.c")
|
||||
|
||||
broadcaster = self.dbg.GetBroadcaster()
|
||||
listener = lldbutil.start_listening_from(
|
||||
broadcaster, lldb.SBDebugger.eBroadcastBitWarning)
|
||||
|
||||
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
|
||||
self, "Set a breakpoint here", self.main_source_file)
|
||||
|
||||
event = lldb.SBEvent()
|
||||
os_version = get_os_version()
|
||||
if not has_rosetta_shared_cache(os_version):
|
||||
self.assertTrue(listener.GetNextEvent(event))
|
||||
else:
|
||||
self.assertFalse(listener.GetNextEvent(event))
|
|
@ -0,0 +1,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
int i = 0; // Set a breakpoint here
|
||||
return i;
|
||||
}
|
Loading…
Reference in New Issue