mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
ios: Add iOS crashpad overview documentation.
Adds an overview of the limitations of crashpad on the iOS platform, including explanations of the in-process client and handler, and the intermediate dump format used. Bug: crashpad: 31 Change-Id: I1eb6add115570147e2de1be1002c5a4aa366184b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2706018 Commit-Queue: Justin Cohen <justincohen@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
6b55b8adba
commit
2dbd019bc2
@ -485,18 +485,37 @@ class CrashpadClient {
|
||||
//! \brief Requests that the handler begin in-process uploading of any
|
||||
//! pending reports.
|
||||
//!
|
||||
//! Once called the handler will start looking for pending reports to upload
|
||||
//! on another thread. This method does not block.
|
||||
//!
|
||||
//! A handler must have already been installed before calling this method.
|
||||
void EnableUploading();
|
||||
void StartProcesingPendingReports();
|
||||
|
||||
// TODO(justincohen): This method is purely for bringing up iOS interfaces.
|
||||
//! \brief Requests that the handler capture a dump even though there hasn't
|
||||
//! been a crash.
|
||||
//! \brief Requests that the handler capture an intermediate dump even though
|
||||
//! there hasn't been a crash. The intermediate dump will be converted
|
||||
//! to a mindump immediately. If StartProcesingPendingReports() has been
|
||||
//! called, this will also trigger an upload.
|
||||
//!
|
||||
//! For internal use only. Clients should use CRASHPAD_SIMULATE_CRASH().
|
||||
//!
|
||||
//! A handler must have already been installed before calling this method.
|
||||
//!
|
||||
//! \param[in] context A NativeCPUContext, generally captured by
|
||||
//! CaptureContext() or similar.
|
||||
static void DumpWithoutCrash(NativeCPUContext* context);
|
||||
|
||||
//! \brief Requests that the handler capture an intermediate dump even though
|
||||
//! there hasn't been a crash. The intermediate dump will not be converted
|
||||
//! to a mindump until ProcessIntermediateDumps() is called.
|
||||
//!
|
||||
//! For internal use only. Clients should use
|
||||
//! CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING().
|
||||
//!
|
||||
//! A handler must have already been installed before calling this method.
|
||||
//!
|
||||
//! \param[in] context A NativeCPUContext, generally captured by
|
||||
//! CaptureContext() or similar.
|
||||
static void DumpWithoutCrashAndDeferProcessing(NativeCPUContext* context);
|
||||
#endif
|
||||
|
||||
#if defined(OS_APPLE) || DOXYGEN
|
||||
|
@ -234,7 +234,7 @@ void CrashpadClient::ProcessIntermediateDumps(
|
||||
}
|
||||
|
||||
// static
|
||||
void CrashpadClient::EnableUploading() {
|
||||
void CrashpadClient::StartProcesingPendingReports() {
|
||||
// TODO(justincohen): Start the CrashReportUploadThread.
|
||||
}
|
||||
|
||||
@ -243,7 +243,17 @@ void CrashpadClient::DumpWithoutCrash(NativeCPUContext* context) {
|
||||
CrashHandler* crash_handler = CrashHandler::Get();
|
||||
DCHECK(crash_handler);
|
||||
crash_handler->DumpWithoutCrash(context);
|
||||
// TODO(justincohen): Change this to only process the dump from above, not all
|
||||
// intermediate dump files.
|
||||
crash_handler->ProcessIntermediateDumps();
|
||||
}
|
||||
|
||||
// static
|
||||
void CrashpadClient::DumpWithoutCrashAndDeferProcessing(
|
||||
NativeCPUContext* context) {
|
||||
CrashHandler* crash_handler = CrashHandler::Get();
|
||||
DCHECK(crash_handler);
|
||||
crash_handler->DumpWithoutCrash(context);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "client/simulate_crash.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "test/scoped_temp_dir.h"
|
||||
#include "testing/platform_test.h"
|
||||
@ -33,9 +34,7 @@ TEST_F(CrashpadIOSClient, DumpWithoutCrash) {
|
||||
ScopedTempDir database_dir;
|
||||
client.StartCrashpadInProcessHandler(
|
||||
base::FilePath(database_dir.path()), "", {});
|
||||
NativeCPUContext context;
|
||||
CaptureContext(&context);
|
||||
client.DumpWithoutCrash(&context);
|
||||
CRASHPAD_SIMULATE_CRASH();
|
||||
}
|
||||
|
||||
// This test is covered by a similar XCUITest, but for development purposes it's
|
||||
|
@ -20,7 +20,11 @@
|
||||
|
||||
//! \file
|
||||
|
||||
//! \brief Captures the CPU context and captures a dump without an exception.
|
||||
//! \brief Captures the CPU context and creates a minidump dump without an
|
||||
//! exception. The minidump will immediately become eligible for further
|
||||
//! processing, including upload.
|
||||
//!
|
||||
//! \sa CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING
|
||||
#define CRASHPAD_SIMULATE_CRASH() \
|
||||
do { \
|
||||
crashpad::NativeCPUContext cpu_context; \
|
||||
@ -28,4 +32,19 @@
|
||||
crashpad::CrashpadClient::DumpWithoutCrash(&cpu_context); \
|
||||
} while (false)
|
||||
|
||||
//! \brief Captures the CPU context and captures an intermediate dump without an
|
||||
//! exception. Does not convert the intermediate dump into a minidump.
|
||||
//!
|
||||
//! Deferring processing is useful when the application may be in an unstable
|
||||
//! state, such as during a hang.
|
||||
//!
|
||||
//! \sa CRASHPAD_SIMULATE_CRASH
|
||||
#define CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING() \
|
||||
do { \
|
||||
crashpad::NativeCPUContext cpu_context; \
|
||||
crashpad::CaptureContext(&cpu_context); \
|
||||
crashpad::CrashpadClient::DumpWithoutCrashAndDeferProcessing( \
|
||||
&cpu_context); \
|
||||
} while (false)
|
||||
|
||||
#endif // CRASHPAD_CLIENT_SIMULATE_CRASH_IOS_H_
|
||||
|
104
doc/ios_overview_design.md
Normal file
104
doc/ios_overview_design.md
Normal file
@ -0,0 +1,104 @@
|
||||
<!--
|
||||
Copyright 2021 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.
|
||||
-->
|
||||
|
||||
# iOS Crashpad Overview Design
|
||||
|
||||
[TOC]
|
||||
|
||||
## iOS Limitations
|
||||
|
||||
Crashpad on other platforms captures exceptions out-of-process. The iOS sandbox,
|
||||
however, restricts applications from delegating work to separate processes.
|
||||
This limitation means Crashpad on iOS must combine the work of the handler and
|
||||
the client into the same process as the main application.
|
||||
|
||||
## The Crashpad In-Process Handler
|
||||
|
||||
In-process handling comes with a number of limitations and difficulties. It is
|
||||
not possible to catch the specific Mach exception `EXC_CRASH`, so certain groups
|
||||
of crashes cannot be captured. This includes some major ones, like out-of-memory
|
||||
crashes. This also introduces difficulties in capturing all the relevant crash
|
||||
data and writing the minidump, as the process itself is in an unsafe state.
|
||||
|
||||
While handling an exception, the handler may not, for example:
|
||||
|
||||
- Allocate memory.
|
||||
- Use libc, or most any library call.
|
||||
|
||||
While handling an exception, the handler may only:
|
||||
|
||||
- Use audited syscalls.
|
||||
- access memory via `vm_read`.
|
||||
|
||||
In conjunction with Crashpad’s existing minidump writer and structural
|
||||
limitations of the minidump format, it is not possible to write a minidump
|
||||
immediately from the crash handler. Instead, an intermediate dump is written
|
||||
when a handler would normally write a minidump (such as during an exception or a
|
||||
forced dump without crashing). The intermediate dump file will be converted to
|
||||
a minidump on the next run (or when the application decides it's safe to do so).
|
||||
|
||||
During Crashpad initialization, the handler gathers basic system information
|
||||
and opens a pending intermediate dump adjacent to the Crashpad database.
|
||||
|
||||
## The Crashpad IntermediateDump Format
|
||||
|
||||
Due to the limitations of in-process handling, an intermediate dump file is
|
||||
written during exceptions. The data is streamed to a file, which will be used to
|
||||
generate a final minidump when appropriate.
|
||||
|
||||
The file format is similar to binary JSON, supporting keyed properties, maps and
|
||||
arrays.
|
||||
|
||||
- `Property` [key:int, length:int, value:intarray]
|
||||
- `StartMap` [key:int], followed by repeating Properties until `EndMap`
|
||||
- `StartArray` [key:int], followed by repeating Maps until `EndArray`
|
||||
- `EndMap`, `EndArray`, `EndDocument`
|
||||
|
||||
Similar to JSON, maps can contain other maps, arrays and properties.
|
||||
|
||||
## The Crashpad In-Process Client
|
||||
|
||||
Other Crashpad platforms handle exceptions and upload minidumps out-of-process.
|
||||
On iOS, everything must happen in-process. Once started, the client will
|
||||
automatically handle exceptions and capture the crashed process state in an
|
||||
intermediate dump file. Converting that intermediate dump file into a minidump
|
||||
is likely not safe to do from within a crashed process, and uploading a minidump
|
||||
is definitely unsafe to do at crash time. Applications are expected to process
|
||||
intermediate dumps into pending minidumps and begin processing pending
|
||||
minidumps, possibly for upload, at suitable times following the next application
|
||||
restart.
|
||||
|
||||
|
||||
### `ProcessIntermediateDumps`
|
||||
For performance and stability reasons applications may choose the correct time
|
||||
to convert intermediate dumps, as well as append metadata to the pending
|
||||
intermediate dumps. This is expected to happen during application startup, when
|
||||
suitable. After converting, a minidump will be written to the Crashpad database,
|
||||
similar to how other platforms write a minidump on exception handling. If
|
||||
uploading is enabled, this minidump will also be immediately uploaded. New
|
||||
intermediate dumps generated by exceptions or by
|
||||
`CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING` will will not be processed until
|
||||
the next call to `ProcessIntermediateDumps`. Conversely,
|
||||
`CRASHPAD_SIMULATE_CRASH` can be called when the client has no performance or
|
||||
stability concerns. In this case, intermediate dumps are automatically
|
||||
converted to minidumps and immediately eligable for uploading.
|
||||
|
||||
### `StartProcesingPendingReports`
|
||||
For similar reasons, applications may choose the correct time to begin uploading
|
||||
pending reports, such as when ideal network conditions exist. By default,
|
||||
clients start with uploading disabled. Applications should call this API when
|
||||
it is determined that it is appropriate to do so (such as on a few seconds after
|
||||
startup, or when network connectivity is appropriate).
|
@ -93,7 +93,8 @@ The handler runs in a separate process from the client or clients. It is
|
||||
responsible for snapshotting the crashing client process’ state on a crash,
|
||||
saving it to a crash dump, and transmitting the crash dump to an upstream
|
||||
server. Clients register with the handler to allow it to capture and upload
|
||||
their crashes.
|
||||
their crashes. On iOS, there is no separate process for the handler.
|
||||
[This is a limitation of iOS.](ios_overview_design.md#ios-limitations)
|
||||
|
||||
### The Crashpad handler
|
||||
|
||||
@ -213,6 +214,12 @@ Crashpad provides a facility for a process to disassociate (unregister) with an
|
||||
existing crash handler, which can be necessary when an older client spawns an
|
||||
updated version.
|
||||
|
||||
#### iOS
|
||||
|
||||
iOS registers both a signal handler for `SIGABRT` and a Mach exception handler
|
||||
with a subset of available exceptions. [This is a limitation of
|
||||
iOS.](ios_overview_design.md#ios-limitations)
|
||||
|
||||
#### Windows
|
||||
|
||||
There are two modes of registration on Windows. In both cases the handler is
|
||||
@ -272,6 +279,14 @@ dispatched to the Mach port by the kernel, on macOS, exceptions can be handled
|
||||
entirely from the Crashpad handler without the need to run any code in the crash
|
||||
process at the time of the exception.
|
||||
|
||||
#### iOS
|
||||
|
||||
On iOS, the operating system will notify the handler of crashes via the Mach
|
||||
exception port or the signal handler. As exceptions are handled in-process, an
|
||||
intermediate dump file is generated rather than a minidump. See more
|
||||
information about the [iOS in-process
|
||||
handler.](ios_overview_design.md#ios-in-process-handler)
|
||||
|
||||
#### Windows
|
||||
|
||||
On Windows, the OS dispatches exceptions in the context of the crashing thread.
|
||||
@ -415,6 +430,14 @@ details of how these properties are stored vary between platforms.
|
||||
The macOS implementation simply stores database properties on the minidump files
|
||||
in filesystem extended attributes.
|
||||
|
||||
#### iOS
|
||||
|
||||
The iOS implementation also stores database properties of minidump files in
|
||||
filesystem extended attributes. Separate from the database, iOS also stores its
|
||||
intermediate dump files adjacent to the database. See more information about
|
||||
[iOS intermediate
|
||||
dumps.](ios_overview_design.md#the-crashpad-intermediatedump-format)
|
||||
|
||||
#### Windows
|
||||
|
||||
The Windows implementation stores database properties in a binary file named
|
||||
|
Loading…
x
Reference in New Issue
Block a user