Skip to content

Commit c399d6d

Browse files
committed
[lldb] Fix platform selection on Apple Silicon (again)
This patch is another attempt to fix platform selection on Apple Silicon. It partially undoes D117340 which tried to fix the issue by always instantiating a remote-ios platform for "iPhone and iPad Apps on Apple Silicon Macs". While the previous patch worked for attaching, it broke launching and everything else that expects the remote platform to be connected. I made an attempt to work around that, but quickly found out that there were just too may places that had this assumption baked in. This patch takes a different approach and reverts back to marking the host platform compatible with iOS triples. This brings us back to the original situation where platform selection was broken for remote iOS debugging on Apple Silicon. To fix that, we now look at the process' host architecture to differentiate between iOS binaries running remotely and iOS binaries running locally. I tested the following scenarios, which now all uses the desired platform: - Launching an iOS binary on macOS: uses the host platform - Attaching to an iOS binary on macOS: uses the host platform - Attaching to a remote iOS binary: uses the remote-ios platform rdar://89840215 Differential revision: https://reviews.llvm.org/D121444 (cherry picked from commit c22c7a6)
1 parent 3bcf4d7 commit c399d6d

File tree

6 files changed

+235
-2
lines changed

6 files changed

+235
-2
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
from lldbsuite.test.gdbclientutils import *
5+
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6+
7+
8+
class TestPlatformMacOSX(GDBRemoteTestBase):
9+
10+
mydir = TestBase.compute_mydir(__file__)
11+
12+
class MyResponder(MockGDBServerResponder):
13+
14+
def __init__(self, host):
15+
self.host_ostype = host
16+
MockGDBServerResponder.__init__(self)
17+
18+
def respond(self, packet):
19+
if packet == "qProcessInfo":
20+
return self.qProcessInfo()
21+
return MockGDBServerResponder.respond(self, packet)
22+
23+
def qHostInfo(self):
24+
return "cputype:16777223;cpusubtype:2;ostype:%s;vendor:apple;os_version:10.15.4;maccatalyst_version:13.4;endian:little;ptrsize:8;" % self.host_ostype
25+
26+
def qProcessInfo(self):
27+
return "pid:a860;parent-pid:d2a0;real-uid:1f5;real-gid:14;effective-uid:1f5;effective-gid:14;cputype:100000c;cpusubtype:2;ptrsize:8;ostype:ios;vendor:apple;endian:little;"
28+
29+
def vCont(self):
30+
return "vCont;"
31+
32+
def platform_test(self, host, expected_triple, expected_platform):
33+
self.server.responder = self.MyResponder(host)
34+
if self.TraceOn():
35+
self.runCmd("log enable gdb-remote packets")
36+
self.addTearDownHook(
37+
lambda: self.runCmd("log disable gdb-remote packets"))
38+
39+
target = self.dbg.CreateTargetWithFileAndArch(None, None)
40+
process = self.connect(target)
41+
42+
triple = target.GetTriple()
43+
self.assertEqual(triple, expected_triple)
44+
45+
platform = target.GetPlatform()
46+
self.assertEqual(platform.GetName(), expected_platform)
47+
48+
@skipIfRemote
49+
def test_ios(self):
50+
self.platform_test(host="ios",
51+
expected_triple="arm64e-apple-ios-",
52+
expected_platform="remote-ios")
53+
54+
@skipIfRemote
55+
@skipUnlessDarwin
56+
@skipUnlessArch("arm64")
57+
def test_macos(self):
58+
self.platform_test(host="macosx",
59+
expected_triple="arm64e-apple-ios-",
60+
expected_platform="host")
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===-- PlatformMacOSXTest.cpp ------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "gtest/gtest.h"
10+
11+
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
12+
#include "TestingSupport/SubsystemRAII.h"
13+
#include "lldb/Host/FileSystem.h"
14+
#include "lldb/Host/HostInfo.h"
15+
#include "lldb/Target/Platform.h"
16+
17+
using namespace lldb;
18+
using namespace lldb_private;
19+
20+
class PlatformMacOSXTest : public ::testing::Test {
21+
SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX> subsystems;
22+
};
23+
24+
static bool containsArch(const std::vector<ArchSpec> &archs,
25+
const ArchSpec &arch) {
26+
return std::find_if(archs.begin(), archs.end(), [&](const ArchSpec &other) {
27+
return arch.IsExactMatch(other);
28+
}) != archs.end();
29+
}
30+
31+
TEST_F(PlatformMacOSXTest, TestGetSupportedArchitectures) {
32+
PlatformMacOSX platform;
33+
34+
const ArchSpec x86_macosx_arch("x86_64-apple-macosx");
35+
36+
EXPECT_TRUE(containsArch(platform.GetSupportedArchitectures(x86_macosx_arch),
37+
x86_macosx_arch));
38+
EXPECT_TRUE(
39+
containsArch(platform.GetSupportedArchitectures({}), x86_macosx_arch));
40+
41+
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
42+
const ArchSpec arm64_macosx_arch("arm64-apple-macosx");
43+
const ArchSpec arm64_ios_arch("arm64-apple-ios");
44+
45+
EXPECT_TRUE(containsArch(
46+
platform.GetSupportedArchitectures(arm64_macosx_arch), arm64_ios_arch));
47+
EXPECT_TRUE(
48+
containsArch(platform.GetSupportedArchitectures({}), arm64_ios_arch));
49+
EXPECT_FALSE(containsArch(platform.GetSupportedArchitectures(arm64_ios_arch),
50+
arm64_ios_arch));
51+
#endif
52+
}

lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,6 @@ std::vector<ArchSpec>
137137
PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
138138
std::vector<ArchSpec> result;
139139
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
140-
// macOS for ARM64 support both native and translated x86_64 processes
141-
142140
// When cmdline lldb is run on iOS, watchOS, etc, it is still
143141
// using "PlatformMacOSX".
144142
llvm::Triple::OSType host_os = GetHostOSType();
@@ -152,6 +150,16 @@ PlatformMacOSX::GetSupportedArchitectures(const ArchSpec &process_host_arch) {
152150
result.push_back(ArchSpec("x86_64-apple-ios-macabi"));
153151
result.push_back(ArchSpec("arm64-apple-ios-macabi"));
154152
result.push_back(ArchSpec("arm64e-apple-ios-macabi"));
153+
154+
// On Apple Silicon, the host platform is compatible with iOS triples to
155+
// support unmodified "iPhone and iPad Apps on Apple Silicon Macs". Because
156+
// the binaries are identical, we must rely on the host architecture to
157+
// tell them apart and mark the host platform as compatible or not.
158+
if (!process_host_arch ||
159+
process_host_arch.GetTriple().getOS() == llvm::Triple::MacOSX) {
160+
result.push_back(ArchSpec("arm64-apple-ios"));
161+
result.push_back(ArchSpec("arm64e-apple-ios"));
162+
}
155163
}
156164
#else
157165
x86GetSupportedArchitectures(result);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import lldb
2+
from lldbsuite.test.lldbtest import *
3+
from lldbsuite.test.decorators import *
4+
from lldbsuite.test.gdbclientutils import *
5+
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
6+
7+
8+
class TestPlatformMacOSX(GDBRemoteTestBase):
9+
10+
mydir = TestBase.compute_mydir(__file__)
11+
12+
class MyResponder(MockGDBServerResponder):
13+
14+
def __init__(self, host):
15+
self.host_ostype = host
16+
MockGDBServerResponder.__init__(self)
17+
18+
def respond(self, packet):
19+
if packet == "qProcessInfo":
20+
return self.qProcessInfo()
21+
return MockGDBServerResponder.respond(self, packet)
22+
23+
def qHostInfo(self):
24+
return "cputype:16777223;cpusubtype:2;ostype:%s;vendor:apple;os_version:10.15.4;maccatalyst_version:13.4;endian:little;ptrsize:8;" % self.host_ostype
25+
26+
def qProcessInfo(self):
27+
return "pid:a860;parent-pid:d2a0;real-uid:1f5;real-gid:14;effective-uid:1f5;effective-gid:14;cputype:100000c;cpusubtype:2;ptrsize:8;ostype:ios;vendor:apple;endian:little;"
28+
29+
def vCont(self):
30+
return "vCont;"
31+
32+
def platform_test(self, host, expected_triple, expected_platform):
33+
self.server.responder = self.MyResponder(host)
34+
if self.TraceOn():
35+
self.runCmd("log enable gdb-remote packets")
36+
self.addTearDownHook(
37+
lambda: self.runCmd("log disable gdb-remote packets"))
38+
39+
target = self.dbg.CreateTargetWithFileAndArch(None, None)
40+
process = self.connect(target)
41+
42+
triple = target.GetTriple()
43+
self.assertEqual(triple, expected_triple)
44+
45+
platform = target.GetPlatform()
46+
self.assertEqual(platform.GetName(), expected_platform)
47+
48+
@skipIfRemote
49+
def test_ios(self):
50+
self.platform_test(host="ios",
51+
expected_triple="arm64e-apple-ios-",
52+
expected_platform="remote-ios")
53+
54+
@skipIfRemote
55+
@skipUnlessDarwin
56+
@skipUnlessArch("arm64")
57+
def test_macos(self):
58+
self.platform_test(host="macosx",
59+
expected_triple="arm64e-apple-ios-",
60+
expected_platform="host")

lldb/unittests/Platform/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_lldb_unittest(LLDBPlatformTests
22
PlatformAppleSimulatorTest.cpp
33
PlatformDarwinTest.cpp
4+
PlatformMacOSXTest.cpp
45

56
LINK_LIBS
67
lldbPluginPlatformMacOSX
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//===-- PlatformMacOSXTest.cpp ------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "gtest/gtest.h"
10+
11+
#include "Plugins/Platform/MacOSX/PlatformMacOSX.h"
12+
#include "TestingSupport/SubsystemRAII.h"
13+
#include "lldb/Host/FileSystem.h"
14+
#include "lldb/Host/HostInfo.h"
15+
#include "lldb/Target/Platform.h"
16+
17+
using namespace lldb;
18+
using namespace lldb_private;
19+
20+
class PlatformMacOSXTest : public ::testing::Test {
21+
SubsystemRAII<FileSystem, HostInfo, PlatformMacOSX> subsystems;
22+
};
23+
24+
static bool containsArch(const std::vector<ArchSpec> &archs,
25+
const ArchSpec &arch) {
26+
return std::find_if(archs.begin(), archs.end(), [&](const ArchSpec &other) {
27+
return arch.IsExactMatch(other);
28+
}) != archs.end();
29+
}
30+
31+
TEST_F(PlatformMacOSXTest, TestGetSupportedArchitectures) {
32+
PlatformMacOSX platform;
33+
34+
const ArchSpec x86_macosx_arch("x86_64-apple-macosx");
35+
36+
EXPECT_TRUE(containsArch(platform.GetSupportedArchitectures(x86_macosx_arch),
37+
x86_macosx_arch));
38+
EXPECT_TRUE(
39+
containsArch(platform.GetSupportedArchitectures({}), x86_macosx_arch));
40+
41+
#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
42+
const ArchSpec arm64_macosx_arch("arm64-apple-macosx");
43+
const ArchSpec arm64_ios_arch("arm64-apple-ios");
44+
45+
EXPECT_TRUE(containsArch(
46+
platform.GetSupportedArchitectures(arm64_macosx_arch), arm64_ios_arch));
47+
EXPECT_TRUE(
48+
containsArch(platform.GetSupportedArchitectures({}), arm64_ios_arch));
49+
EXPECT_FALSE(containsArch(platform.GetSupportedArchitectures(arm64_ios_arch),
50+
arm64_ios_arch));
51+
#endif
52+
}

0 commit comments

Comments
 (0)