ios: Split bootstrap out from mach_extensions
mach_extensions is sensible on iOS, but bootstrap is not available
outside of macOS. To allow mach_extensions to be used cleanly on iOS,
the bootstrap code is moved into its own macOS-specific file.
Bug: crashpad:31
Change-Id: I30902bc18e71bf985160ff0e3acf5b84f03de853
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2154529
Reviewed-by: Justin Cohen <justincohen@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
GitOrigin-RevId: ba24acb86ca66277cc5fc7311961825850b04570
diff --git a/client/crashpad_client_mac.cc b/client/crashpad_client_mac.cc
index 22bd538..2fa8729 100644
--- a/client/crashpad_client_mac.cc
+++ b/client/crashpad_client_mac.cc
@@ -26,6 +26,7 @@
#include "base/mac/mach_logging.h"
#include "base/strings/stringprintf.h"
#include "util/mac/mac_util.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/child_port_handshake.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
diff --git a/handler/handler_main.cc b/handler/handler_main.cc
index e0a262c..69da0f6 100644
--- a/handler/handler_main.cc
+++ b/handler/handler_main.cc
@@ -74,8 +74,8 @@
#include "handler/mac/crash_report_exception_handler.h"
#include "handler/mac/exception_handler_server.h"
#include "handler/mac/file_limit_annotation.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/child_port_handshake.h"
-#include "util/mach/mach_extensions.h"
#include "util/posix/close_stdio.h"
#include "util/posix/signals.h"
#elif defined(OS_WIN)
diff --git a/handler/mac/crash_report_exception_handler.cc b/handler/mac/crash_report_exception_handler.cc
index 9919e95..cccf1e9 100644
--- a/handler/mac/crash_report_exception_handler.cc
+++ b/handler/mac/crash_report_exception_handler.cc
@@ -28,6 +28,7 @@
#include "snapshot/crashpad_info_client_options.h"
#include "snapshot/mac/process_snapshot_mac.h"
#include "util/file/file_writer.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/exc_client_variants.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/exception_types.h"
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 32dc298..047c786 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -57,14 +57,19 @@
}
}
+ if (crashpad_is_mac || crashpad_is_ios) {
+ sources += [
+ "mac/mach_errors.cc",
+ "mac/mach_errors.h",
+ ]
+ }
+
if (crashpad_is_mac) {
sources += [
"mac/dyld.cc",
"mac/dyld.h",
"mac/exception_swallower.cc",
"mac/exception_swallower.h",
- "mac/mach_errors.cc",
- "mac/mach_errors.h",
"mac/mach_multiprocess.cc",
"mac/mach_multiprocess.h",
]
diff --git a/test/mac/exception_swallower.cc b/test/mac/exception_swallower.cc
index 18c5cf7..946938f 100644
--- a/test/mac/exception_swallower.cc
+++ b/test/mac/exception_swallower.cc
@@ -24,6 +24,7 @@
#include "base/mac/scoped_mach_port.h"
#include "base/strings/stringprintf.h"
#include "handler/mac/exception_handler_server.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
diff --git a/test/mac/mach_errors.cc b/test/mac/mach_errors.cc
index b68448f..db8ed66 100644
--- a/test/mac/mach_errors.cc
+++ b/test/mac/mach_errors.cc
@@ -14,8 +14,6 @@
#include "test/mac/mach_errors.h"
-#include <servers/bootstrap.h>
-
#include "base/strings/stringprintf.h"
namespace {
@@ -50,28 +48,5 @@
FormatMachErrorNumber(mach_err).c_str());
}
-std::string BootstrapErrorMessage(kern_return_t bootstrap_err,
- const std::string& base) {
- switch (bootstrap_err) {
- case BOOTSTRAP_SUCCESS:
- case BOOTSTRAP_NOT_PRIVILEGED:
- case BOOTSTRAP_NAME_IN_USE:
- case BOOTSTRAP_UNKNOWN_SERVICE:
- case BOOTSTRAP_SERVICE_ACTIVE:
- case BOOTSTRAP_BAD_COUNT:
- case BOOTSTRAP_NO_MEMORY:
- case BOOTSTRAP_NO_CHILDREN:
- // Show known bootstrap errors in decimal because that's how they're
- // defined in <servers/bootstrap.h>.
- return base::StringPrintf("%s%s (%d)",
- FormatBase(base).c_str(),
- bootstrap_strerror(bootstrap_err),
- bootstrap_err);
-
- default:
- return MachErrorMessage(bootstrap_err, base);
- }
-}
-
} // namespace test
} // namespace crashpad
diff --git a/test/mac/mach_errors.h b/test/mac/mach_errors.h
index 9e43ef2..0afcdad 100644
--- a/test/mac/mach_errors.h
+++ b/test/mac/mach_errors.h
@@ -22,9 +22,9 @@
namespace crashpad {
namespace test {
-// These functions format messages in a similar way to the logging macros in
-// base/mac/mach_logging.h. They exist to interoperate with gtest assertions,
-// which don’t interoperate with logging but can be streamed to.
+// This function formats messages in a similar way to the Mach error logging
+// macros in base/mac/mach_logging.h. It exists to interoperate with gtest
+// assertions, which don’t interoperate with logging but can be streamed to.
//
// Where non-test code could do:
// MACH_CHECK(kr == KERN_SUCCESS, kr) << "vm_deallocate";
@@ -47,23 +47,6 @@
std::string MachErrorMessage(mach_error_t mach_err,
const std::string& base = std::string());
-//! \brief Formats a bootstrap error message.
-//!
-//! The returned string will combine the \a base string, if supplied, with a
-//! textual and numeric description of the error.
-//!
-//! \param[in] bootstrap_err The bootstrap error code.
-//! \param[in] base A string to prepend to the error description.
-//!
-//! \return A string of the format `"Permission denied (1100)"` if \a
-//! bootstrap_err has the value `BOOTSTRAP_NOT_PRIVILEGED` on a system where
-//! this is defined to be 1100. If \a base is not empty, it will be
-//! prepended to this string, separated by a colon. If \a bootstrap_err is
-//! not a valid bootstrap error code, it will be interpreted as a Mach error
-//! code in the manner of MachErrorMessage().
-std::string BootstrapErrorMessage(kern_return_t bootstrap_err,
- const std::string& base = std::string());
-
} // namespace test
} // namespace crashpad
diff --git a/test/mac/mach_multiprocess.cc b/test/mac/mach_multiprocess.cc
index f29a8b0..59aa653 100644
--- a/test/mac/mach_multiprocess.cc
+++ b/test/mac/mach_multiprocess.cc
@@ -27,6 +27,7 @@
#include "test/errors.h"
#include "test/mac/mach_errors.h"
#include "util/file/file_io.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/mach_message.h"
#include "util/misc/implicit_cast.h"
diff --git a/tools/mac/catch_exception_tool.cc b/tools/mac/catch_exception_tool.cc
index d4dc3c1..4f40372 100644
--- a/tools/mac/catch_exception_tool.cc
+++ b/tools/mac/catch_exception_tool.cc
@@ -28,6 +28,7 @@
#include "base/logging.h"
#include "base/mac/mach_logging.h"
#include "tools/tool_support.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/exc_server_variants.h"
#include "util/mach/exception_behaviors.h"
#include "util/mach/exception_types.h"
diff --git a/tools/mac/exception_port_tool.cc b/tools/mac/exception_port_tool.cc
index a047e96..b9d3fdd 100644
--- a/tools/mac/exception_port_tool.cc
+++ b/tools/mac/exception_port_tool.cc
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "tools/tool_support.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/exception_ports.h"
#include "util/mach/mach_extensions.h"
#include "util/mach/symbolic_constants_mach.h"
diff --git a/util/BUILD.gn b/util/BUILD.gn
index 7fe02f2..fdd2fe1 100644
--- a/util/BUILD.gn
+++ b/util/BUILD.gn
@@ -248,6 +248,8 @@
sources += [
"mac/xattr.cc",
"mac/xattr.h",
+ "mach/mach_extensions.cc",
+ "mach/mach_extensions.h",
"misc/clock_mac.cc",
"misc/paths_mac.cc",
"synchronization/semaphore_mac.cc",
@@ -263,6 +265,8 @@
"mac/mac_util.h",
"mac/service_management.cc",
"mac/service_management.h",
+ "mach/bootstrap.cc",
+ "mach/bootstrap.h",
"mach/child_port_handshake.cc",
"mach/child_port_handshake.h",
"mach/child_port_server.cc",
@@ -280,8 +284,6 @@
"mach/exception_ports.h",
"mach/exception_types.cc",
"mach/exception_types.h",
- "mach/mach_extensions.cc",
- "mach/mach_extensions.h",
"mach/mach_message.cc",
"mach/mach_message.h",
"mach/mach_message_server.cc",
@@ -659,7 +661,10 @@
}
if (crashpad_is_mac || crashpad_is_ios) {
- sources += [ "mac/xattr_test.cc" ]
+ sources += [
+ "mac/xattr_test.cc",
+ "mach/mach_extensions_test.cc",
+ ]
}
if (crashpad_is_mac) {
@@ -667,6 +672,7 @@
"mac/launchd_test.mm",
"mac/mac_util_test.mm",
"mac/service_management_test.mm",
+ "mach/bootstrap_test.cc",
"mach/child_port_handshake_test.cc",
"mach/child_port_server_test.cc",
"mach/composite_mach_message_server_test.cc",
@@ -675,7 +681,6 @@
"mach/exception_behaviors_test.cc",
"mach/exception_ports_test.cc",
"mach/exception_types_test.cc",
- "mach/mach_extensions_test.cc",
"mach/mach_message_server_test.cc",
"mach/mach_message_test.cc",
"mach/notify_server_test.cc",
diff --git a/util/mach/bootstrap.cc b/util/mach/bootstrap.cc
new file mode 100644
index 0000000..f553437
--- /dev/null
+++ b/util/mach/bootstrap.cc
@@ -0,0 +1,109 @@
+// Copyright 2020 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/mach/bootstrap.h"
+
+#include <mach/mach.h>
+#include <servers/bootstrap.h>
+
+#include "base/mac/mach_logging.h"
+
+namespace {
+
+// This forms the internal implementation for BootstrapCheckIn() and
+// BootstrapLookUp(), which follow the same logic aside from the routine called
+// and the right type returned.
+
+struct BootstrapCheckInTraits {
+ using Type = base::mac::ScopedMachReceiveRight;
+ static kern_return_t Call(mach_port_t bootstrap_port,
+ const char* service_name,
+ mach_port_t* service_port) {
+ return bootstrap_check_in(bootstrap_port, service_name, service_port);
+ }
+ static constexpr char kName[] = "bootstrap_check_in";
+};
+constexpr char BootstrapCheckInTraits::kName[];
+
+struct BootstrapLookUpTraits {
+ using Type = base::mac::ScopedMachSendRight;
+ static kern_return_t Call(mach_port_t bootstrap_port,
+ const char* service_name,
+ mach_port_t* service_port) {
+ return bootstrap_look_up(bootstrap_port, service_name, service_port);
+ }
+ static constexpr char kName[] = "bootstrap_look_up";
+};
+constexpr char BootstrapLookUpTraits::kName[];
+
+template <typename Traits>
+typename Traits::Type BootstrapCheckInOrLookUp(
+ const std::string& service_name) {
+ // bootstrap_check_in() and bootstrap_look_up() silently truncate service
+ // names longer than BOOTSTRAP_MAX_NAME_LEN. This check ensures that the name
+ // will not be truncated.
+ if (service_name.size() >= BOOTSTRAP_MAX_NAME_LEN) {
+ LOG(ERROR) << Traits::kName << " " << service_name << ": name too long";
+ return typename Traits::Type(MACH_PORT_NULL);
+ }
+
+ mach_port_t service_port;
+ kern_return_t kr =
+ Traits::Call(bootstrap_port, service_name.c_str(), &service_port);
+ if (kr != BOOTSTRAP_SUCCESS) {
+ BOOTSTRAP_LOG(ERROR, kr) << Traits::kName << " " << service_name;
+ service_port = MACH_PORT_NULL;
+ }
+
+ return typename Traits::Type(service_port);
+}
+
+} // namespace
+
+namespace crashpad {
+
+base::mac::ScopedMachReceiveRight BootstrapCheckIn(
+ const std::string& service_name) {
+ return BootstrapCheckInOrLookUp<BootstrapCheckInTraits>(service_name);
+}
+
+base::mac::ScopedMachSendRight BootstrapLookUp(
+ const std::string& service_name) {
+ base::mac::ScopedMachSendRight send(
+ BootstrapCheckInOrLookUp<BootstrapLookUpTraits>(service_name));
+
+ // It’s possible to race the bootstrap server when the receive right
+ // corresponding to the looked-up send right is destroyed immediately before
+ // the bootstrap_look_up() call. If the bootstrap server believes that
+ // |service_name| is still registered before processing the port-destroyed
+ // notification sent to it by the kernel, it will respond to a
+ // bootstrap_look_up() request with a send right that has become a dead name,
+ // which will be returned to the bootstrap_look_up() caller, translated into
+ // the caller’s IPC port name space, as the special MACH_PORT_DEAD port name.
+ // Check for that and return MACH_PORT_NULL in its place, as though the
+ // bootstrap server had fully processed the port-destroyed notification before
+ // responding to bootstrap_look_up().
+ if (send.get() == MACH_PORT_DEAD) {
+ LOG(ERROR) << "bootstrap_look_up " << service_name << ": service is dead";
+ send.reset();
+ }
+
+ return send;
+}
+
+base::mac::ScopedMachSendRight SystemCrashReporterHandler() {
+ return BootstrapLookUp("com.apple.ReportCrash");
+}
+
+} // namespace crashpad
diff --git a/util/mach/bootstrap.h b/util/mach/bootstrap.h
new file mode 100644
index 0000000..680f5b9
--- /dev/null
+++ b/util/mach/bootstrap.h
@@ -0,0 +1,63 @@
+// Copyright 2020 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef CRASHPAD_UTIL_MACH_BOOTSTRAP_H_
+#define CRASHPAD_UTIL_MACH_BOOTSTRAP_H_
+
+#include <string>
+
+#include "base/mac/scoped_mach_port.h"
+
+namespace crashpad {
+
+//! \brief Makes a `boostrap_check_in()` call to the process’ bootstrap server.
+//!
+//! This function is provided to make it easier to call `bootstrap_check_in()`
+//! while avoiding accidental leaks of the returned receive right.
+//!
+//! \param[in] service_name The service name to check in.
+//!
+//! \return On success, a receive right to the service port. On failure,
+//! `MACH_PORT_NULL` with a message logged.
+base::mac::ScopedMachReceiveRight BootstrapCheckIn(
+ const std::string& service_name);
+
+//! \brief Makes a `boostrap_look_up()` call to the process’ bootstrap server.
+//!
+//! This function is provided to make it easier to call `bootstrap_look_up()`
+//! while avoiding accidental leaks of the returned send right.
+//!
+//! \param[in] service_name The service name to look up.
+//!
+//! \return On success, a send right to the service port. On failure,
+//! `MACH_PORT_NULL` with a message logged.
+base::mac::ScopedMachSendRight BootstrapLookUp(const std::string& service_name);
+
+//! \brief Obtains the system’s default Mach exception handler for crash-type
+//! exceptions.
+//!
+//! This is obtained by looking up `"com.apple.ReportCrash"` with the bootstrap
+//! server. The service name comes from the first launch agent loaded by
+//! `launchd` with a `MachServices` entry having `ExceptionServer` set. This
+//! launch agent is normally loaded from
+//! `/System/Library/LaunchAgents/com.apple.ReportCrash.plist`.
+//!
+//! \return On success, a send right to an `exception_handler_t` corresponding
+//! to the system’s default crash reporter. On failure, `MACH_PORT_NULL`,
+//! with a message logged.
+base::mac::ScopedMachSendRight SystemCrashReporterHandler();
+
+} // namespace crashpad
+
+#endif // CRASHPAD_UTIL_MACH_BOOTSTRAP_H_
diff --git a/util/mach/bootstrap_test.cc b/util/mach/bootstrap_test.cc
new file mode 100644
index 0000000..44587d0
--- /dev/null
+++ b/util/mach/bootstrap_test.cc
@@ -0,0 +1,70 @@
+// Copyright 2020 The Crashpad Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "util/mach/bootstrap.h"
+
+#include "base/mac/scoped_mach_port.h"
+#include "gtest/gtest.h"
+#include "util/mach/mach_extensions.h"
+#include "util/misc/random_string.h"
+
+namespace crashpad {
+namespace test {
+namespace {
+
+TEST(Bootstrap, BootstrapCheckInAndLookUp) {
+ // This should always exist.
+ base::mac::ScopedMachSendRight report_crash(
+ BootstrapLookUp("com.apple.ReportCrash"));
+ EXPECT_NE(report_crash, kMachPortNull);
+
+ std::string service_name = "org.chromium.crashpad.test.bootstrap_check_in.";
+ service_name.append(RandomString());
+
+ {
+ // The new service hasn’t checked in yet, so this should fail.
+ base::mac::ScopedMachSendRight send(BootstrapLookUp(service_name));
+ EXPECT_EQ(send, kMachPortNull);
+
+ // Check it in.
+ base::mac::ScopedMachReceiveRight receive(BootstrapCheckIn(service_name));
+ EXPECT_NE(receive, kMachPortNull);
+
+ // Now it should be possible to look up the new service.
+ send = BootstrapLookUp(service_name);
+ EXPECT_NE(send, kMachPortNull);
+
+ // It shouldn’t be possible to check the service in while it’s active.
+ base::mac::ScopedMachReceiveRight receive_2(BootstrapCheckIn(service_name));
+ EXPECT_EQ(receive_2, kMachPortNull);
+ }
+
+ // The new service should be gone now.
+ base::mac::ScopedMachSendRight send(BootstrapLookUp(service_name));
+ EXPECT_EQ(send, kMachPortNull);
+
+ // It should be possible to check it in again.
+ base::mac::ScopedMachReceiveRight receive(BootstrapCheckIn(service_name));
+ EXPECT_NE(receive, kMachPortNull);
+}
+
+TEST(Bootstrap, SystemCrashReporterHandler) {
+ base::mac::ScopedMachSendRight system_crash_reporter_handler(
+ SystemCrashReporterHandler());
+ EXPECT_TRUE(system_crash_reporter_handler.is_valid());
+}
+
+} // namespace
+} // namespace test
+} // namespace crashpad
diff --git a/util/mach/child_port_handshake.cc b/util/mach/child_port_handshake.cc
index 1891f91..3ff9828 100644
--- a/util/mach/child_port_handshake.cc
+++ b/util/mach/child_port_handshake.cc
@@ -34,6 +34,7 @@
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "util/file/file_io.h"
+#include "util/mach/bootstrap.h"
#include "util/mach/child_port.h"
#include "util/mach/child_port_server.h"
#include "util/mach/mach_extensions.h"
diff --git a/util/mach/mach_extensions.cc b/util/mach/mach_extensions.cc
index 5450ab2..9e31012 100644
--- a/util/mach/mach_extensions.cc
+++ b/util/mach/mach_extensions.cc
@@ -14,66 +14,14 @@
#include "util/mach/mach_extensions.h"
+#include <Availability.h>
#include <AvailabilityMacros.h>
#include <pthread.h>
-#include <servers/bootstrap.h>
#include "base/mac/mach_logging.h"
+#include "build/build_config.h"
#include "util/mac/mac_util.h"
-namespace {
-
-// This forms the internal implementation for BootstrapCheckIn() and
-// BootstrapLookUp(), which follow the same logic aside from the routine called
-// and the right type returned.
-
-struct BootstrapCheckInTraits {
- using Type = base::mac::ScopedMachReceiveRight;
- static kern_return_t Call(mach_port_t bootstrap_port,
- const char* service_name,
- mach_port_t* service_port) {
- return bootstrap_check_in(bootstrap_port, service_name, service_port);
- }
- static constexpr char kName[] = "bootstrap_check_in";
-};
-constexpr char BootstrapCheckInTraits::kName[];
-
-struct BootstrapLookUpTraits {
- using Type = base::mac::ScopedMachSendRight;
- static kern_return_t Call(mach_port_t bootstrap_port,
- const char* service_name,
- mach_port_t* service_port) {
- return bootstrap_look_up(bootstrap_port, service_name, service_port);
- }
- static constexpr char kName[] = "bootstrap_look_up";
-};
-constexpr char BootstrapLookUpTraits::kName[];
-
-template <typename Traits>
-typename Traits::Type BootstrapCheckInOrLookUp(
- const std::string& service_name) {
- // bootstrap_check_in() and bootstrap_look_up() silently truncate service
- // names longer than BOOTSTRAP_MAX_NAME_LEN. This check ensures that the name
- // will not be truncated.
- if (service_name.size() >= BOOTSTRAP_MAX_NAME_LEN) {
- LOG(ERROR) << Traits::kName << " " << service_name << ": name too long";
- return typename Traits::Type(MACH_PORT_NULL);
- }
-
- mach_port_t service_port;
- kern_return_t kr = Traits::Call(bootstrap_port,
- service_name.c_str(),
- &service_port);
- if (kr != BOOTSTRAP_SUCCESS) {
- BOOTSTRAP_LOG(ERROR, kr) << Traits::kName << " " << service_name;
- service_port = MACH_PORT_NULL;
- }
-
- return typename Traits::Type(service_port);
-}
-
-} // namespace
-
namespace crashpad {
thread_t MachThreadSelf() {
@@ -97,7 +45,12 @@
// 10.9.4 xnu-2422.110.17/osfmk/mach/ipc_host.c and
// xnu-2422.110.17/osfmk/mach/ipc_tt.c.
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
+// iOS 7 ≅ macOS 10.9.
+#error This code was not ported to iOS versions older than 7
+#endif
+
+#if !defined(OS_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
const int mac_os_x_minor_version = MacOSXMinorVersion();
#endif
@@ -114,7 +67,7 @@
EXC_MASK_MACH_SYSCALL |
EXC_MASK_RPC_ALERT |
EXC_MASK_MACHINE;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
+#if !defined(OS_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_8
if (mac_os_x_minor_version < 8) {
return kExcMaskAll_10_6;
}
@@ -124,7 +77,7 @@
// xnu-2050.48.11/osfmk/mach/exception_types.h.
constexpr exception_mask_t kExcMaskAll_10_8 =
kExcMaskAll_10_6 | EXC_MASK_RESOURCE;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
+#if !defined(OS_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9
if (mac_os_x_minor_version < 9) {
return kExcMaskAll_10_8;
}
@@ -139,7 +92,12 @@
exception_mask_t ExcMaskValid() {
const exception_mask_t kExcMaskValid_10_6 = ExcMaskAll() | EXC_MASK_CRASH;
-#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11
+#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0
+// iOS 9 ≅ macOS 10.11.
+#error This code was not ported to iOS versions older than 9
+#endif
+
+#if !defined(OS_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11
if (MacOSXMinorVersion() < 11) {
return kExcMaskValid_10_6;
}
@@ -151,37 +109,4 @@
return kExcMaskValid_10_11;
}
-base::mac::ScopedMachReceiveRight BootstrapCheckIn(
- const std::string& service_name) {
- return BootstrapCheckInOrLookUp<BootstrapCheckInTraits>(service_name);
-}
-
-base::mac::ScopedMachSendRight BootstrapLookUp(
- const std::string& service_name) {
- base::mac::ScopedMachSendRight send(
- BootstrapCheckInOrLookUp<BootstrapLookUpTraits>(service_name));
-
- // It’s possible to race the bootstrap server when the receive right
- // corresponding to the looked-up send right is destroyed immediately before
- // the bootstrap_look_up() call. If the bootstrap server believes that
- // |service_name| is still registered before processing the port-destroyed
- // notification sent to it by the kernel, it will respond to a
- // bootstrap_look_up() request with a send right that has become a dead name,
- // which will be returned to the bootstrap_look_up() caller, translated into
- // the caller’s IPC port name space, as the special MACH_PORT_DEAD port name.
- // Check for that and return MACH_PORT_NULL in its place, as though the
- // bootstrap server had fully processed the port-destroyed notification before
- // responding to bootstrap_look_up().
- if (send.get() == MACH_PORT_DEAD) {
- LOG(ERROR) << "bootstrap_look_up " << service_name << ": service is dead";
- send.reset();
- }
-
- return send;
-}
-
-base::mac::ScopedMachSendRight SystemCrashReporterHandler() {
- return BootstrapLookUp("com.apple.ReportCrash");
-}
-
} // namespace crashpad
diff --git a/util/mach/mach_extensions.h b/util/mach/mach_extensions.h
index 25e401c..9247ce9 100644
--- a/util/mach/mach_extensions.h
+++ b/util/mach/mach_extensions.h
@@ -17,10 +17,6 @@
#include <mach/mach.h>
-#include <string>
-
-#include "base/mac/scoped_mach_port.h"
-
namespace crashpad {
//! \brief `MACH_PORT_NULL` with the correct type for a Mach port,
@@ -119,43 +115,6 @@
//! support is present.
exception_mask_t ExcMaskValid();
-//! \brief Makes a `boostrap_check_in()` call to the process’ bootstrap server.
-//!
-//! This function is provided to make it easier to call `bootstrap_check_in()`
-//! while avoiding accidental leaks of the returned receive right.
-//!
-//! \param[in] service_name The service name to check in.
-//!
-//! \return On success, a receive right to the service port. On failure,
-//! `MACH_PORT_NULL` with a message logged.
-base::mac::ScopedMachReceiveRight BootstrapCheckIn(
- const std::string& service_name);
-
-//! \brief Makes a `boostrap_look_up()` call to the process’ bootstrap server.
-//!
-//! This function is provided to make it easier to call `bootstrap_look_up()`
-//! while avoiding accidental leaks of the returned send right.
-//!
-//! \param[in] service_name The service name to look up.
-//!
-//! \return On success, a send right to the service port. On failure,
-//! `MACH_PORT_NULL` with a message logged.
-base::mac::ScopedMachSendRight BootstrapLookUp(const std::string& service_name);
-
-//! \brief Obtains the system’s default Mach exception handler for crash-type
-//! exceptions.
-//!
-//! This is obtained by looking up `"com.apple.ReportCrash"` with the bootstrap
-//! server. The service name comes from the first launch agent loaded by
-//! `launchd` with a `MachServices` entry having `ExceptionServer` set. This
-//! launch agent is normally loaded from
-//! `/System/Library/LaunchAgents/com.apple.ReportCrash.plist`.
-//!
-//! \return On success, a send right to an `exception_handler_t` corresponding
-//! to the system’s default crash reporter. On failure, `MACH_PORT_NULL`,
-//! with a message logged.
-base::mac::ScopedMachSendRight SystemCrashReporterHandler();
-
} // namespace crashpad
#endif // CRASHPAD_UTIL_MACH_MACH_EXTENSIONS_H_
diff --git a/util/mach/mach_extensions_test.cc b/util/mach/mach_extensions_test.cc
index 1c5b368..748e0aa 100644
--- a/util/mach/mach_extensions_test.cc
+++ b/util/mach/mach_extensions_test.cc
@@ -15,10 +15,10 @@
#include "util/mach/mach_extensions.h"
#include "base/mac/scoped_mach_port.h"
+#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/mac/mach_errors.h"
#include "util/mac/mac_util.h"
-#include "util/misc/random_string.h"
namespace crashpad {
namespace test {
@@ -80,6 +80,11 @@
EXPECT_FALSE(exc_mask_all & EXC_MASK_CRASH);
EXPECT_FALSE(exc_mask_all & EXC_MASK_CORPSE_NOTIFY);
+#if defined(OS_IOS)
+ // Assume at least iOS 7 (≅ macOS 10.9).
+ EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE);
+ EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD);
+#else // OS_IOS
const int mac_os_x_minor_version = MacOSXMinorVersion();
if (mac_os_x_minor_version >= 8) {
EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE);
@@ -92,6 +97,7 @@
} else {
EXPECT_FALSE(exc_mask_all & EXC_MASK_GUARD);
}
+#endif // OS_IOS
// Bit 0 should not be set.
EXPECT_FALSE(ExcMaskAll() & 1);
@@ -106,6 +112,12 @@
EXPECT_TRUE(exc_mask_valid & EXC_MASK_CRASH);
+#if defined(OS_IOS)
+ // Assume at least iOS 9 (≅ macOS 10.11).
+ EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE);
+ EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD);
+ EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);
+#else // OS_IOS
const int mac_os_x_minor_version = MacOSXMinorVersion();
if (mac_os_x_minor_version >= 8) {
EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE);
@@ -124,6 +136,7 @@
} else {
EXPECT_FALSE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);
}
+#endif // OS_IOS
// Bit 0 should not be set.
EXPECT_FALSE(ExcMaskValid() & 1);
@@ -132,48 +145,6 @@
EXPECT_TRUE(ExcMaskValid() & ~ExcMaskAll());
}
-TEST(MachExtensions, BootstrapCheckInAndLookUp) {
- // This should always exist.
- base::mac::ScopedMachSendRight
- report_crash(BootstrapLookUp("com.apple.ReportCrash"));
- EXPECT_NE(report_crash, kMachPortNull);
-
- std::string service_name = "org.chromium.crashpad.test.bootstrap_check_in.";
- service_name.append(RandomString());
-
- {
- // The new service hasn’t checked in yet, so this should fail.
- base::mac::ScopedMachSendRight send(BootstrapLookUp(service_name));
- EXPECT_EQ(send, kMachPortNull);
-
- // Check it in.
- base::mac::ScopedMachReceiveRight receive(BootstrapCheckIn(service_name));
- EXPECT_NE(receive, kMachPortNull);
-
- // Now it should be possible to look up the new service.
- send = BootstrapLookUp(service_name);
- EXPECT_NE(send, kMachPortNull);
-
- // It shouldn’t be possible to check the service in while it’s active.
- base::mac::ScopedMachReceiveRight receive_2(BootstrapCheckIn(service_name));
- EXPECT_EQ(receive_2, kMachPortNull);
- }
-
- // The new service should be gone now.
- base::mac::ScopedMachSendRight send(BootstrapLookUp(service_name));
- EXPECT_EQ(send, kMachPortNull);
-
- // It should be possible to check it in again.
- base::mac::ScopedMachReceiveRight receive(BootstrapCheckIn(service_name));
- EXPECT_NE(receive, kMachPortNull);
-}
-
-TEST(MachExtensions, SystemCrashReporterHandler) {
- base::mac::ScopedMachSendRight
- system_crash_reporter_handler(SystemCrashReporterHandler());
- EXPECT_TRUE(system_crash_reporter_handler.is_valid());
-}
-
} // namespace
} // namespace test
} // namespace crashpad