ios: Build util/mach/exc_server_variants.cc, support code, and tests

This makes UniversalMachExcServer available on iOS.
UniversalMachExcServer is the foundation for a Mach exc and mach_exc
server.

Some code in UniversalMachExcServer needs to be evaluated to ensure that
portions that run in the same process that has sustained the exception
are safe to do so at that time. For example,
SimplifiedExcServer<ExcTraits>::Interface instantiates and appends to a
std::vector<>, which is generally unsafe in this context. However, that
code responds to exc requests. The mach_exc equivalent,
SimplifiedMachExcServer<MachExcTraits>::Interface, does not use a vector
at all.

This also enables support code in the form of CompositeMachMessageServer
and UniversalExceptionRaise, all of the tests for
CompositeMachMessageServer, and most of the test for
exc_server_variants.cc. The multiprocess-based exc_server_variants tests
remain disabled on iOS.

Bug: crashpad:31
Change-Id: I838ed770a33ca29c37383c32245eb340fb3ad2fb
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2159287
Reviewed-by: Justin Cohen <justincohen@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Mark Mentovai 2020-04-21 11:59:44 -04:00 committed by Commit Bot
parent 1bfd7d06ed
commit 64b8791f45
5 changed files with 27 additions and 14 deletions

View File

@ -288,6 +288,12 @@ static_library("util") {
sources += [ sources += [
"mac/xattr.cc", "mac/xattr.cc",
"mac/xattr.h", "mac/xattr.h",
"mach/composite_mach_message_server.cc",
"mach/composite_mach_message_server.h",
"mach/exc_client_variants.cc",
"mach/exc_client_variants.h",
"mach/exc_server_variants.cc",
"mach/exc_server_variants.h",
"mach/exception_behaviors.cc", "mach/exception_behaviors.cc",
"mach/exception_behaviors.h", "mach/exception_behaviors.h",
"mach/exception_ports.cc", "mach/exception_ports.cc",
@ -320,12 +326,6 @@ static_library("util") {
"mach/child_port_server.cc", "mach/child_port_server.cc",
"mach/child_port_server.h", "mach/child_port_server.h",
"mach/child_port_types.h", "mach/child_port_types.h",
"mach/composite_mach_message_server.cc",
"mach/composite_mach_message_server.h",
"mach/exc_client_variants.cc",
"mach/exc_client_variants.h",
"mach/exc_server_variants.cc",
"mach/exc_server_variants.h",
"mach/exception_types.cc", "mach/exception_types.cc",
"mach/exception_types.h", "mach/exception_types.h",
"mach/notify_server.cc", "mach/notify_server.cc",
@ -704,6 +704,8 @@ source_set("util_test") {
if (crashpad_is_mac || crashpad_is_ios) { if (crashpad_is_mac || crashpad_is_ios) {
sources += [ sources += [
"mac/xattr_test.cc", "mac/xattr_test.cc",
"mach/composite_mach_message_server_test.cc",
"mach/exc_server_variants_test.cc",
"mach/exception_behaviors_test.cc", "mach/exception_behaviors_test.cc",
"mach/mach_extensions_test.cc", "mach/mach_extensions_test.cc",
"mach/mach_message_test.cc", "mach/mach_message_test.cc",
@ -718,9 +720,7 @@ source_set("util_test") {
"mach/bootstrap_test.cc", "mach/bootstrap_test.cc",
"mach/child_port_handshake_test.cc", "mach/child_port_handshake_test.cc",
"mach/child_port_server_test.cc", "mach/child_port_server_test.cc",
"mach/composite_mach_message_server_test.cc",
"mach/exc_client_variants_test.cc", "mach/exc_client_variants_test.cc",
"mach/exc_server_variants_test.cc",
"mach/exception_ports_test.cc", "mach/exception_ports_test.cc",
"mach/exception_types_test.cc", "mach/exception_types_test.cc",
"mach/mach_message_server_test.cc", "mach/mach_message_server_test.cc",

View File

@ -22,6 +22,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "build/build_config.h"
#include "util/mac/mac_util.h" #include "util/mac/mac_util.h"
#include "util/mach/composite_mach_message_server.h" #include "util/mach/composite_mach_message_server.h"
#include "util/mach/exc.h" #include "util/mach/exc.h"
@ -682,7 +683,7 @@ kern_return_t ExcServerSuccessfulReturnValue(exception_type_t exception,
exception_behavior_t behavior, exception_behavior_t behavior,
bool set_thread_state) { bool set_thread_state) {
if (exception == EXC_CRASH if (exception == EXC_CRASH
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11 #if !defined(OS_IOS) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11
&& MacOSXMinorVersion() >= 11 && MacOSXMinorVersion() >= 11
#endif #endif
) { ) {

View File

@ -25,13 +25,16 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "test/mac/mach_errors.h" #include "test/mac/mach_errors.h"
#include "test/mac/mach_multiprocess.h"
#include "util/mac/mac_util.h" #include "util/mac/mac_util.h"
#include "util/mach/exception_behaviors.h" #include "util/mach/exception_behaviors.h"
#include "util/mach/exception_types.h" #include "util/mach/exception_types.h"
#include "util/mach/mach_message.h" #include "util/mach/mach_message.h"
#include "util/misc/implicit_cast.h" #include "util/misc/implicit_cast.h"
#if !defined(OS_IOS)
#include "test/mac/mach_multiprocess.h"
#endif // !OS_IOS
namespace crashpad { namespace crashpad {
namespace test { namespace test {
namespace { namespace {
@ -958,6 +961,8 @@ TEST(ExcServerVariants, MachMessageServerRequestIDs) {
expect_request_ids); expect_request_ids);
} }
#if !defined(OS_IOS)
class TestExcServerVariants : public MachMultiprocess, class TestExcServerVariants : public MachMultiprocess,
public UniversalMachExcServer::Interface { public UniversalMachExcServer::Interface {
public: public:
@ -1193,9 +1198,16 @@ TEST(ExcServerVariants, ThreadStates) {
} }
} }
#endif // !OS_IOS
TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) { TEST(ExcServerVariants, ExcServerSuccessfulReturnValue) {
#if defined(OS_IOS)
// iOS 9 ≅ OS X 10.11.
const kern_return_t prefer_not_set_thread_state = KERN_SUCCESS;
#else
const kern_return_t prefer_not_set_thread_state = const kern_return_t prefer_not_set_thread_state =
MacOSXMinorVersion() < 11 ? MACH_RCV_PORT_DIED : KERN_SUCCESS; MacOSXMinorVersion() < 11 ? MACH_RCV_PORT_DIED : KERN_SUCCESS;
#endif
const struct { const struct {
exception_type_t exception; exception_type_t exception;

View File

@ -46,7 +46,7 @@ exception_mask_t ExcMaskAll() {
// xnu-2422.110.17/osfmk/mach/ipc_tt.c. // xnu-2422.110.17/osfmk/mach/ipc_tt.c.
#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0 #if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
// iOS 7 ≅ macOS 10.9. // iOS 7 ≅ OS X 10.9.
#error This code was not ported to iOS versions older than 7 #error This code was not ported to iOS versions older than 7
#endif #endif
@ -93,7 +93,7 @@ exception_mask_t ExcMaskAll() {
exception_mask_t ExcMaskValid() { exception_mask_t ExcMaskValid() {
const exception_mask_t kExcMaskValid_10_6 = ExcMaskAll() | EXC_MASK_CRASH; const exception_mask_t kExcMaskValid_10_6 = ExcMaskAll() | EXC_MASK_CRASH;
#if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0 #if defined(OS_IOS) && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0
// iOS 9 ≅ macOS 10.11. // iOS 9 ≅ OS X 10.11.
#error This code was not ported to iOS versions older than 9 #error This code was not ported to iOS versions older than 9
#endif #endif

View File

@ -81,7 +81,7 @@ TEST(MachExtensions, ExcMaskAll) {
EXPECT_FALSE(exc_mask_all & EXC_MASK_CORPSE_NOTIFY); EXPECT_FALSE(exc_mask_all & EXC_MASK_CORPSE_NOTIFY);
#if defined(OS_IOS) #if defined(OS_IOS)
// Assume at least iOS 7 (≅ macOS 10.9). // Assume at least iOS 7 (≅ OS X 10.9).
EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE); EXPECT_TRUE(exc_mask_all & EXC_MASK_RESOURCE);
EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD); EXPECT_TRUE(exc_mask_all & EXC_MASK_GUARD);
#else // OS_IOS #else // OS_IOS
@ -113,7 +113,7 @@ TEST(MachExtensions, ExcMaskValid) {
EXPECT_TRUE(exc_mask_valid & EXC_MASK_CRASH); EXPECT_TRUE(exc_mask_valid & EXC_MASK_CRASH);
#if defined(OS_IOS) #if defined(OS_IOS)
// Assume at least iOS 9 (≅ macOS 10.11). // Assume at least iOS 9 (≅ OS X 10.11).
EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE); EXPECT_TRUE(exc_mask_valid & EXC_MASK_RESOURCE);
EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD); EXPECT_TRUE(exc_mask_valid & EXC_MASK_GUARD);
EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY); EXPECT_TRUE(exc_mask_valid & EXC_MASK_CORPSE_NOTIFY);