mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Bring up skeleton crashpad_client_ios.
First steps at bringing up the crashpad_client on iOS. Also updates the XCUITest to trigger various crashes, with some swizzling necessary to allow crashes. Change-Id: I87dd36bed1c052b509d14bfa29679ed81e58a377 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2039470 Commit-Queue: Justin Cohen <justincohen@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org> Reviewed-by: Rohit Rao <rohitrao@chromium.org>
This commit is contained in:
parent
faed21a286
commit
9ed8290547
@ -43,6 +43,10 @@ static_library("client") {
|
||||
]
|
||||
}
|
||||
|
||||
if (crashpad_is_ios) {
|
||||
sources += [ "crashpad_client_ios.cc" ]
|
||||
}
|
||||
|
||||
if (crashpad_is_linux || crashpad_is_android) {
|
||||
set_sources_assignment_filter([])
|
||||
sources += [
|
||||
@ -137,7 +141,9 @@ source_set("client_test") {
|
||||
"../util",
|
||||
]
|
||||
|
||||
data_deps = [ "../handler:crashpad_handler" ]
|
||||
if (!crashpad_is_ios) {
|
||||
data_deps = [ "../handler:crashpad_handler" ]
|
||||
}
|
||||
|
||||
if (crashpad_is_win) {
|
||||
data_deps += [ "../handler:crashpad_handler_console" ]
|
||||
|
@ -423,9 +423,21 @@ class CrashpadClient {
|
||||
//!
|
||||
//! \param[in] unhandled_signals The set of unhandled signals
|
||||
void SetUnhandledSignals(const std::set<int>& unhandled_signals);
|
||||
|
||||
#endif // OS_LINUX || OS_ANDROID || DOXYGEN
|
||||
|
||||
#if defined(OS_IOS) || DOXYGEN
|
||||
//! \brief Configures the process to direct its crashes to the iOS in-process
|
||||
//! Crashpad handler.
|
||||
//!
|
||||
//! This method is only defined on iOS.
|
||||
//!
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
//!
|
||||
//! TODO(justincohen): This method will need to take database, metrics_dir,
|
||||
//! url and annotations eventually.
|
||||
bool StartCrashpadInProcessHandler();
|
||||
#endif
|
||||
|
||||
#if defined(OS_MACOSX) || DOXYGEN
|
||||
//! \brief Sets the process’ crash handler to a Mach service registered with
|
||||
//! the bootstrap server.
|
||||
|
75
client/crashpad_client_ios.cc
Normal file
75
client/crashpad_client_ios.cc
Normal file
@ -0,0 +1,75 @@
|
||||
// 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 "client/crashpad_client.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "client/client_argv_handling.h"
|
||||
#include "util/posix/signals.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace {
|
||||
|
||||
// A base class for Crashpad signal handler implementations.
|
||||
class SignalHandler {
|
||||
public:
|
||||
// Returns the currently installed signal hander.
|
||||
static SignalHandler* Get() {
|
||||
static SignalHandler* instance = new SignalHandler();
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool Install(const std::set<int>* unhandled_signals) {
|
||||
return Signals::InstallCrashHandlers(
|
||||
HandleSignal, 0, &old_actions_, unhandled_signals);
|
||||
}
|
||||
|
||||
private:
|
||||
SignalHandler() = default;
|
||||
|
||||
// The base implementation for all signal handlers, suitable for calling
|
||||
// directly to simulate signal delivery.
|
||||
void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
|
||||
// Do Something.
|
||||
|
||||
// Always call system handler.
|
||||
Signals::RestoreHandlerAndReraiseSignalOnReturn(
|
||||
siginfo, old_actions_.ActionForSignal(signo));
|
||||
}
|
||||
|
||||
// The signal handler installed at OS-level.
|
||||
static void HandleSignal(int signo, siginfo_t* siginfo, void* context) {
|
||||
Get()->HandleCrash(signo, siginfo, context);
|
||||
}
|
||||
|
||||
Signals::OldActions old_actions_ = {};
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SignalHandler);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
CrashpadClient::CrashpadClient() {}
|
||||
|
||||
CrashpadClient::~CrashpadClient() {}
|
||||
|
||||
bool CrashpadClient::StartCrashpadInProcessHandler() {
|
||||
return SignalHandler::Get()->Install(nullptr);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
@ -19,7 +19,7 @@ config("compat_config") {
|
||||
|
||||
if (crashpad_is_mac) {
|
||||
include_dirs += [ "mac" ]
|
||||
} else {
|
||||
} else if (!crashpad_is_ios) {
|
||||
include_dirs += [ "non_mac" ]
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ config("compat_config") {
|
||||
}
|
||||
|
||||
template("compat_target") {
|
||||
if (crashpad_is_mac) {
|
||||
if (crashpad_is_mac || crashpad_is_ios) {
|
||||
# There are no sources to compile, which doesn’t mix will with a
|
||||
# static_library.
|
||||
group(target_name) {
|
||||
@ -67,7 +67,7 @@ compat_target("compat") {
|
||||
"mac/mach/mach.h",
|
||||
"mac/sys/resource.h",
|
||||
]
|
||||
} else {
|
||||
} else if (!crashpad_is_ios) {
|
||||
sources += [
|
||||
"non_mac/mach-o/loader.h",
|
||||
"non_mac/mach/mach.h",
|
||||
|
@ -140,25 +140,27 @@ source_set("handler_test") {
|
||||
}
|
||||
}
|
||||
|
||||
crashpad_executable("crashpad_handler") {
|
||||
sources = [ "main.cc" ]
|
||||
if (!crashpad_is_ios) {
|
||||
crashpad_executable("crashpad_handler") {
|
||||
sources = [ "main.cc" ]
|
||||
|
||||
deps = [
|
||||
":handler",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
]
|
||||
deps = [
|
||||
":handler",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
]
|
||||
|
||||
if (crashpad_is_win) {
|
||||
if (crashpad_is_in_chromium || crashpad_is_in_dart) {
|
||||
remove_configs = [ "//build/config/win:console" ]
|
||||
configs = [ "//build/config/win:windowed" ]
|
||||
} else {
|
||||
remove_configs =
|
||||
[ "//third_party/mini_chromium/mini_chromium/build:win_console" ]
|
||||
configs =
|
||||
[ "//third_party/mini_chromium/mini_chromium/build:win_windowed" ]
|
||||
if (crashpad_is_win) {
|
||||
if (crashpad_is_in_chromium || crashpad_is_in_dart) {
|
||||
remove_configs = [ "//build/config/win:console" ]
|
||||
configs = [ "//build/config/win:windowed" ]
|
||||
} else {
|
||||
remove_configs =
|
||||
[ "//third_party/mini_chromium/mini_chromium/build:win_console" ]
|
||||
configs =
|
||||
[ "//third_party/mini_chromium/mini_chromium/build:win_windowed" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -190,19 +192,21 @@ if (crashpad_is_android) {
|
||||
}
|
||||
}
|
||||
|
||||
crashpad_executable("crashpad_handler_test_extended_handler") {
|
||||
testonly = true
|
||||
if (!crashpad_is_ios) {
|
||||
crashpad_executable("crashpad_handler_test_extended_handler") {
|
||||
testonly = true
|
||||
|
||||
sources = [ "crashpad_handler_test_extended_handler.cc" ]
|
||||
sources = [ "crashpad_handler_test_extended_handler.cc" ]
|
||||
|
||||
deps = [
|
||||
":handler",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../minidump:test_support",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../tools:tool_support",
|
||||
]
|
||||
deps = [
|
||||
":handler",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../minidump:test_support",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../tools:tool_support",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (crashpad_is_win) {
|
||||
|
@ -40,6 +40,7 @@ source_set("google_test_runner") {
|
||||
deps = [
|
||||
"../../build:ios_enable_arc",
|
||||
"../../build:ios_xctest",
|
||||
"../../test/ios:google_test_runner_shared_headers",
|
||||
"../../third_party/mini_chromium:base",
|
||||
]
|
||||
libs = [ "UIKit.framework" ]
|
||||
|
@ -14,26 +14,135 @@
|
||||
|
||||
#import <XCTest/XCTest.h>
|
||||
|
||||
#include <objc/runtime.h>
|
||||
#import "Service/Sources/EDOClientService.h"
|
||||
#import "test/ios/host/edo_placeholder.h"
|
||||
#import "test/ios/host/cptest_shared_object.h"
|
||||
|
||||
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
||||
#error "This file requires ARC support."
|
||||
#endif
|
||||
|
||||
@interface CPTestTestCase : XCTestCase
|
||||
@interface CPTestTestCase : XCTestCase {
|
||||
XCUIApplication* _app;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation CPTestTestCase
|
||||
|
||||
- (void)handleCrashUnderSymbol:(id)arg1 {
|
||||
// For now, do nothing. In the future this can be something testable.
|
||||
}
|
||||
|
||||
+ (void)setUp {
|
||||
// Swizzle away the handleCrashUnderSymbol callback. Without this, any time
|
||||
// the host app is intentionally crashed, the test is immediately failed.
|
||||
SEL originalSelector = NSSelectorFromString(@"handleCrashUnderSymbol:");
|
||||
SEL swizzledSelector = @selector(handleCrashUnderSymbol:);
|
||||
|
||||
Method originalMethod = class_getInstanceMethod(
|
||||
objc_getClass("XCUIApplicationImpl"), originalSelector);
|
||||
Method swizzledMethod =
|
||||
class_getInstanceMethod([self class], swizzledSelector);
|
||||
|
||||
method_exchangeImplementations(originalMethod, swizzledMethod);
|
||||
|
||||
// Override EDO default error handler. Without this, the default EDO error
|
||||
// handler will throw an error and fail the test.
|
||||
[EDOClientService setErrorHandler:^(NSError* error){
|
||||
// Do nothing.
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setUp {
|
||||
[[[XCUIApplication alloc] init] launch];
|
||||
_app = [[XCUIApplication alloc] init];
|
||||
[_app launch];
|
||||
}
|
||||
|
||||
- (void)testEDO {
|
||||
EDOPlaceholder* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
NSString* result = [rootObject testEDO];
|
||||
XCTAssertEqualObjects(result, @"crashpad");
|
||||
}
|
||||
|
||||
- (void)testSegv {
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
// Crash the app.
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject crashSegv];
|
||||
|
||||
// Confirm the app is not running.
|
||||
XCTAssertTrue([_app waitForState:XCUIApplicationStateNotRunning timeout:15]);
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateNotRunning);
|
||||
|
||||
// TODO: Query the app for crash data
|
||||
[_app launch];
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
}
|
||||
|
||||
- (void)testKillAbort {
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
// Crash the app.
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject crashKillAbort];
|
||||
|
||||
// Confirm the app is not running.
|
||||
XCTAssertTrue([_app waitForState:XCUIApplicationStateNotRunning timeout:15]);
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateNotRunning);
|
||||
|
||||
// TODO: Query the app for crash data
|
||||
[_app launch];
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
}
|
||||
|
||||
- (void)testTrap {
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
// Crash the app.
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject crashTrap];
|
||||
|
||||
// Confirm the app is not running.
|
||||
XCTAssertTrue([_app waitForState:XCUIApplicationStateNotRunning timeout:15]);
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateNotRunning);
|
||||
|
||||
// TODO: Query the app for crash data
|
||||
[_app launch];
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
}
|
||||
|
||||
- (void)testAbort {
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
// Crash the app.
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject crashAbort];
|
||||
|
||||
// Confirm the app is not running.
|
||||
XCTAssertTrue([_app waitForState:XCUIApplicationStateNotRunning timeout:15]);
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateNotRunning);
|
||||
|
||||
// TODO: Query the app for crash data
|
||||
[_app launch];
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
}
|
||||
|
||||
- (void)testBadAccess {
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
// Crash the app.
|
||||
CPTestSharedObject* rootObject = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject crashBadAccess];
|
||||
|
||||
// Confirm the app is not running.
|
||||
XCTAssertTrue([_app waitForState:XCUIApplicationStateNotRunning timeout:15]);
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateNotRunning);
|
||||
|
||||
// TODO: Query the app for crash data
|
||||
[_app launch];
|
||||
XCTAssertTrue(_app.state == XCUIApplicationStateRunningForeground);
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -22,13 +22,9 @@ if (crashpad_is_in_chromium) {
|
||||
|
||||
source_set("app_shared_sources") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"edo_placeholder.h",
|
||||
]
|
||||
sources = [ "cptest_shared_object.h" ]
|
||||
configs += [ "../../..:crashpad_config" ]
|
||||
deps = [
|
||||
"../../../build:ios_enable_arc",
|
||||
]
|
||||
deps = [ "../../../build:ios_enable_arc" ]
|
||||
libs = [ "UIKit.framework" ]
|
||||
}
|
||||
|
||||
@ -45,6 +41,7 @@ static_library("app_host_sources") {
|
||||
deps = [
|
||||
":app_shared_sources",
|
||||
"../../../build:ios_enable_arc",
|
||||
"../../../client",
|
||||
"../../../third_party/edo",
|
||||
]
|
||||
libs = [
|
||||
@ -56,7 +53,5 @@ static_library("app_host_sources") {
|
||||
ios_app_bundle("ios_crash_xcuitests") {
|
||||
info_plist = "Info.plist"
|
||||
testonly = true
|
||||
deps = [
|
||||
":app_host_sources",
|
||||
]
|
||||
deps = [ ":app_host_sources" ]
|
||||
}
|
||||
|
@ -16,8 +16,9 @@
|
||||
|
||||
#import "Service/Sources/EDOHostNamingService.h"
|
||||
#import "Service/Sources/EDOHostService.h"
|
||||
#include "client/crashpad_client.h"
|
||||
#import "test/ios/host/cptest_shared_object.h"
|
||||
#import "test/ios/host/crash_view_controller.h"
|
||||
#import "test/ios/host/edo_placeholder.h"
|
||||
|
||||
#if !defined(__has_feature) || !__has_feature(objc_arc)
|
||||
#error "This file requires ARC support."
|
||||
@ -28,6 +29,10 @@
|
||||
|
||||
- (BOOL)application:(UIApplication*)application
|
||||
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
|
||||
// Start up crashpad.
|
||||
crashpad::CrashpadClient client;
|
||||
client.StartCrashpadInProcessHandler();
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
[self.window makeKeyAndVisible];
|
||||
self.window.backgroundColor = UIColor.greenColor;
|
||||
@ -37,17 +42,37 @@
|
||||
|
||||
// Start up EDO.
|
||||
[EDOHostService serviceWithPort:12345
|
||||
rootObject:[[EDOPlaceholder alloc] init]
|
||||
rootObject:[[CPTestSharedObject alloc] init]
|
||||
queue:dispatch_get_main_queue()];
|
||||
[EDOHostNamingService.sharedService start];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation EDOPlaceholder
|
||||
@implementation CPTestSharedObject
|
||||
- (NSString*)testEDO {
|
||||
return @"crashpad";
|
||||
}
|
||||
|
||||
- (void)crashBadAccess {
|
||||
strcpy(0, "bla");
|
||||
}
|
||||
|
||||
- (void)crashKillAbort {
|
||||
kill(getpid(), SIGABRT);
|
||||
}
|
||||
|
||||
- (void)crashSegv {
|
||||
long zero = 0;
|
||||
*(long*)zero = 0xC045004d;
|
||||
}
|
||||
|
||||
- (void)crashTrap {
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
- (void)crashAbort {
|
||||
abort();
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -12,13 +12,29 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_TEST_IOS_HOST_EDO_PLACEHOLDER_H_
|
||||
#define CRASHPAD_TEST_IOS_HOST_EDO_PLACEHOLDER_H_
|
||||
#ifndef CRASHPAD_TEST_IOS_HOST_SHARED_OBJECT_H_
|
||||
#define CRASHPAD_TEST_IOS_HOST_SHARED_OBJECT_H_
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface EDOPlaceholder : NSObject
|
||||
@interface CPTestSharedObject : NSObject
|
||||
// Returns the string "crashpad" for testing EDO.
|
||||
- (NSString*)testEDO;
|
||||
|
||||
// Triggers an EXC_BAD_ACCESS exception and crash.
|
||||
- (void)crashBadAccess;
|
||||
|
||||
// Triggers a crash with a call to kill(SIGABRT).
|
||||
- (void)crashKillAbort;
|
||||
|
||||
// Triggers a segfault crash.
|
||||
- (void)crashSegv;
|
||||
|
||||
// Trigger a crash with a __builtin_trap.
|
||||
- (void)crashTrap;
|
||||
|
||||
// Trigger a crash with an abort().
|
||||
- (void)crashAbort;
|
||||
@end
|
||||
|
||||
#endif // CRASHPAD_TEST_IOS_HOST_EDO_PLACEHOLDER_H_
|
||||
#endif // CRASHPAD_TEST_IOS_HOST_SHARED_OBJECT_H_
|
@ -25,29 +25,31 @@ source_set("tool_support") {
|
||||
deps = [ "../third_party/mini_chromium:base" ]
|
||||
}
|
||||
|
||||
crashpad_executable("crashpad_database_util") {
|
||||
sources = [ "crashpad_database_util.cc" ]
|
||||
if (!crashpad_is_ios) {
|
||||
crashpad_executable("crashpad_database_util") {
|
||||
sources = [ "crashpad_database_util.cc" ]
|
||||
|
||||
deps = [
|
||||
":tool_support",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../client",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../util",
|
||||
]
|
||||
}
|
||||
deps = [
|
||||
":tool_support",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../client",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../util",
|
||||
]
|
||||
}
|
||||
|
||||
crashpad_executable("crashpad_http_upload") {
|
||||
sources = [ "crashpad_http_upload.cc" ]
|
||||
crashpad_executable("crashpad_http_upload") {
|
||||
sources = [ "crashpad_http_upload.cc" ]
|
||||
|
||||
deps = [
|
||||
":tool_support",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../util",
|
||||
]
|
||||
deps = [
|
||||
":tool_support",
|
||||
"../build:default_exe_manifest_win",
|
||||
"../compat",
|
||||
"../third_party/mini_chromium:base",
|
||||
"../util",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
crashpad_executable("base94_encoder") {
|
||||
@ -60,7 +62,7 @@ crashpad_executable("base94_encoder") {
|
||||
]
|
||||
}
|
||||
|
||||
if (!crashpad_is_fuchsia) {
|
||||
if (!crashpad_is_fuchsia && !crashpad_is_ios) {
|
||||
crashpad_executable("generate_dump") {
|
||||
sources = [ "generate_dump.cc" ]
|
||||
|
||||
@ -88,7 +90,8 @@ if (!crashpad_is_fuchsia) {
|
||||
}
|
||||
|
||||
if (crashpad_is_win) {
|
||||
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
|
||||
cflags =
|
||||
[ "/wd4201" ] # nonstandard extension used : nameless struct/union
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
#include "util/stdlib/strnlen.h"
|
||||
|
||||
#if defined(OS_MACOSX) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS) && \
|
||||
MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
|
||||
// Redeclare a method only available on Mac OS X 10.7 and later to suppress a
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "build/build_config.h"
|
||||
|
||||
#if defined(OS_MACOSX)
|
||||
#if defined(OS_MACOSX) && !defined(OS_IOS)
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
|
||||
@ -38,7 +38,7 @@ namespace crashpad {
|
||||
//! and not all systems’ standard libraries provide an implementation.
|
||||
size_t strnlen(const char* string, size_t max_length);
|
||||
|
||||
#if !defined(OS_MACOSX) || \
|
||||
#if !defined(OS_MACOSX) || defined(OS_IOS) || \
|
||||
MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_7
|
||||
inline size_t strnlen(const char* string, size_t max_length) {
|
||||
return ::strnlen(string, max_length);
|
||||
|
Loading…
x
Reference in New Issue
Block a user