Commit 000847f8 authored by Adrian Prantl's avatar Adrian Prantl
Browse files

Correctly identify iOS simulator processes in debugserver.

Starting with iOS 13 simulator binaries are identified with an
explicit platform in the new LC_BUILD_VERSION load command.

On older deployment targets using the LC_VERSION_MIN load commands,
this patch detects when an ios process runs on a macOS host and
updates the target triple with the "simulator" environment
accordingly.

(Patch re-applied with bugfix this time).

This is part of https://bugs.swift.org/browse/SR-11971

rdar://problem/58438125

Differential Revision: https://reviews.llvm.org/D75696
parent 4ebe9b49
Loading
Loading
Loading
Loading
+16 −10
Original line number Diff line number Diff line
@@ -1131,6 +1131,20 @@ bool GDBRemoteCommunicationClient::GetDefaultThreadId(lldb::tid_t &tid) {
  return true;
}

static void ParseOSType(llvm::StringRef value, std::string &os_name,
                        std::string &environment) {
  if (value.equals("iossimulator") || value.equals("tvossimulator") ||
      value.equals("watchossimulator")) {
    environment = "simulator";
    os_name = value.drop_back(environment.size()).str();
  } else if (value.equals("maccatalyst")) {
    os_name = "ios";
    environment = "macabi";
  } else {
    os_name = value.str();
  }
}

bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
  Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS));

@@ -1189,11 +1203,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) {
            extractor.GetHexByteString(m_os_kernel);
            ++num_keys_decoded;
          } else if (name.equals("ostype")) {
            if (value.equals("maccatalyst")) {
              os_name = "ios";
              environment = "macabi";
            } else
              os_name = std::string(value);
            ParseOSType(value, os_name, environment);
            ++num_keys_decoded;
          } else if (name.equals("vendor")) {
            vendor_name = std::string(value);
@@ -2053,11 +2063,7 @@ bool GDBRemoteCommunicationClient::GetCurrentProcessInfo(bool allow_lazy) {
          extractor.GetHexByteString(triple);
          ++num_keys_decoded;
        } else if (name.equals("ostype")) {
          if (value.equals("maccatalyst")) {
            os_name = "ios";
            environment = "macabi";
          } else
            os_name = std::string(value);
          ParseOSType(value, os_name, environment);
          ++num_keys_decoded;
        } else if (name.equals("vendor")) {
          vendor_name = std::string(value);
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ class TestGDBRemoteClient(GDBRemoteTestBase):
            def A(self, packet):
                return "E47"

        self.runCmd("log enable gdb-remote packets")
        self.server.responder = MyResponder()

        target = self.createTarget("a.yaml")
+63 −0
Original line number Diff line number Diff line
import lldb
from lldbsuite.test.lldbtest import *
from lldbsuite.test.decorators import *
from gdbclientutils import *

class TestIOSSimulator(GDBRemoteTestBase):
    """
    Test that an ios simulator process is recognized as such.
    """

    class MyResponder(MockGDBServerResponder):
        def __init__(self, host, process):
            self.host_ostype = host
            self.process_ostype = process
            MockGDBServerResponder.__init__(self)

        def respond(self, packet):
            if packet == "qProcessInfo":
                return self.qProcessInfo()
            return MockGDBServerResponder.respond(self, packet)

        def qHostInfo(self):
            return "cputype:16777223;cpusubtype:8;ostype:%s;vendor:apple;os_version:10.15.4;maccatalyst_version:13.4;endian:little;ptrsize:8;"%self.host_ostype
        def qProcessInfo(self):
            return "pid:a860;parent-pid:d2a0;real-uid:1f5;real-gid:14;effective-uid:1f5;effective-gid:14;cputype:1000007;cpusubtype:8;ptrsize:8;ostype:%s;vendor:apple;endian:little;"%self.process_ostype
        def vCont(self):
            return "vCont;"
    
    def platform_test(self, host, process, expected_triple):
        self.server.responder = self.MyResponder(host, process)
        if self.TraceOn():
            self.runCmd("log enable gdb-remote packets")
            self.addTearDownHook(lambda: self.runCmd("log disable gdb-remote packets"))

        target = self.dbg.CreateTargetWithFileAndArch(None, None)
        process = self.connect(target)
        triple = target.GetTriple()
        self.assertEqual(triple, expected_triple)

    @skipIfRemote
    def test_macos(self):
        self.platform_test(host="macosx", process="macosx",
                           expected_triple="x86_64h-apple-macosx-")

    @skipIfRemote
    def test_ios_sim(self):
        self.platform_test(host="macosx", process="iossimulator",
                           expected_triple="x86_64h-apple-ios-simulator")

    @skipIfRemote
    def test_catalyst(self):
        self.platform_test(host="macosx", process="maccatalyst",
                           expected_triple="x86_64h-apple-ios-macabi")

    @skipIfRemote
    def test_tvos_sim(self):
        self.platform_test(host="macosx", process="tvossimulator",
                           expected_triple="x86_64h-apple-tvos-simulator")

    @skipIfRemote
    def test_tvos_sim(self):
        self.platform_test(host="macosx", process="watchossimulator",
                           expected_triple="x86_64h-apple-watchos-simulator")
+21 −6
Original line number Diff line number Diff line
@@ -598,6 +598,16 @@ nub_addr_t MachProcess::GetTSDAddressForThread(
      plo_pthread_tsd_entry_size);
}

/// Determine whether this is running on macOS.
/// Since debugserver runs on the same machine as the process, we can
/// just look at the compilation target.
static bool IsMacOSHost() {
#if TARGET_OS_OSX == 1
  return true;
#else
  return false;
#endif
}

const char *MachProcess::GetDeploymentInfo(const struct load_command& lc,
                                           uint64_t load_command_address,
@@ -619,15 +629,17 @@ const char *MachProcess::GetDeploymentInfo(const struct load_command& lc,
    minor_version = (vers_cmd.sdk >> 8) & 0xffu;
    patch_version = vers_cmd.sdk & 0xffu;

    // Handle the older LC_VERSION load commands, which don't
    // distinguish between simulator and real hardware.
    switch (cmd) {
    case LC_VERSION_MIN_IPHONEOS:
      return "ios";
      return IsMacOSHost() ? "iossimulator": "ios";
    case LC_VERSION_MIN_MACOSX:
      return "macosx";
    case LC_VERSION_MIN_TVOS:
      return "tvos";
      return IsMacOSHost() ? "tvossimulator": "tvos";
    case LC_VERSION_MIN_WATCHOS:
      return "watchos";
      return IsMacOSHost() ? "watchossimulator" : "watchos";
    default:
      return nullptr;
    }
@@ -649,14 +661,17 @@ const char *MachProcess::GetDeploymentInfo(const struct load_command& lc,
    case PLATFORM_MACCATALYST:
      return "maccatalyst";
    case PLATFORM_IOS:
    case PLATFORM_IOSSIMULATOR:
      return "ios";
    case PLATFORM_IOSSIMULATOR:
      return "iossimulator";
    case PLATFORM_TVOS:
    case PLATFORM_TVOSSIMULATOR:
      return "tvos";
    case PLATFORM_TVOSSIMULATOR:
      return "tvossimulator";
    case PLATFORM_WATCHOS:
    case PLATFORM_WATCHOSSIMULATOR:
      return "watchos";
    case PLATFORM_WATCHOSSIMULATOR:
      return "watchossimulator";
    case PLATFORM_BRIDGEOS:
      return "bridgeos";
    case PLATFORM_DRIVERKIT: