ios: Support UserStreamDataSources on iOS.

Adds a parameter to the iOS ProcessIntermediateDumps API to allow for
post-crash user stream processing. Also moves user_stream_data_source.h
to handler:common to avoid a dependency cycle on iOS.

This will be used by gwp-asan.

Change-Id: Ic528725276e3c4d284aef89a86cc86878a7af9b0
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/6340388
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Justin Cohen <justincohen@chromium.org>
This commit is contained in:
Justin Cohen 2025-03-12 15:47:55 -04:00 committed by Crashpad LUCI CQ
parent 04b11f9964
commit e09f5ee484
6 changed files with 57 additions and 21 deletions

View File

@ -43,6 +43,7 @@
#if BUILDFLAG(IS_IOS)
#include "client/upload_behavior_ios.h"
#include "handler/user_stream_data_source.h" // nogncheck
#endif
namespace crashpad {
@ -531,8 +532,13 @@ class CrashpadClient {
//! \param[in] annotations Process annotations to set in each crash report.
//! Useful when adding crash annotations detected on the next run after a
//! crash but before upload.
//! \param[in] user_stream_sources An optional vector containing the
//! extensibility data sources to call on crash. Each time a minidump is
//! created, the sources are called in turn. Any streams returned are
//! added to the minidump.
static void ProcessIntermediateDumps(
const std::map<std::string, std::string>& annotations = {});
const std::map<std::string, std::string>& annotations = {},
const UserStreamDataSources* user_stream_sources = {});
//! \brief Requests that the handler convert a single intermediate dump at \a
//! file generated by DumpWithoutCrashAndDeferProcessingAtPath into a

View File

@ -153,8 +153,10 @@ class CrashHandler : public Thread,
}
void ProcessIntermediateDumps(
const std::map<std::string, std::string>& annotations) {
in_process_handler_.ProcessIntermediateDumps(annotations);
const std::map<std::string, std::string>& annotations,
const UserStreamDataSources* user_stream_sources) {
in_process_handler_.ProcessIntermediateDumps(annotations,
user_stream_sources);
}
void ProcessIntermediateDump(
@ -457,10 +459,11 @@ bool CrashpadClient::StartCrashpadInProcessHandler(
// static
void CrashpadClient::ProcessIntermediateDumps(
const std::map<std::string, std::string>& annotations) {
const std::map<std::string, std::string>& annotations,
const UserStreamDataSources* user_stream_sources) {
CrashHandler* crash_handler = CrashHandler::Get();
DCHECK(crash_handler);
crash_handler->ProcessIntermediateDumps(annotations);
crash_handler->ProcessIntermediateDumps(annotations, user_stream_sources);
}
// static

View File

@ -254,21 +254,23 @@ bool InProcessHandler::MoveIntermediateDumpAtPathToPending(
return MoveFileOrDirectory(path, new_path_unlocked);
}
void InProcessHandler::ProcessIntermediateDumps(
const std::map<std::string, std::string>& annotations) {
const std::map<std::string, std::string>& annotations,
const UserStreamDataSources* user_stream_sources) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
for (auto& file : PendingFiles())
ProcessIntermediateDump(file, annotations);
ProcessIntermediateDump(file, annotations, user_stream_sources);
}
void InProcessHandler::ProcessIntermediateDump(
const base::FilePath& file,
const std::map<std::string, std::string>& annotations) {
const std::map<std::string, std::string>& annotations,
const UserStreamDataSources* user_stream_sources) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
ProcessSnapshotIOSIntermediateDump process_snapshot;
if (process_snapshot.InitializeWithFilePath(file, annotations)) {
SaveSnapshot(process_snapshot);
SaveSnapshot(process_snapshot, user_stream_sources);
}
}
@ -320,7 +322,8 @@ void InProcessHandler::UpdatePruneAndUploadThreads(
}
void InProcessHandler::SaveSnapshot(
ProcessSnapshotIOSIntermediateDump& process_snapshot) {
ProcessSnapshotIOSIntermediateDump& process_snapshot,
const UserStreamDataSources* user_stream_sources) {
std::unique_ptr<CrashReportDatabase::NewReport> new_report;
CrashReportDatabase::OperationStatus database_status =
database_->PrepareNewCrashReport(&new_report);
@ -339,6 +342,8 @@ void InProcessHandler::SaveSnapshot(
MinidumpFileWriter minidump;
minidump.InitializeFromSnapshot(&process_snapshot);
AddUserExtensionStreams(user_stream_sources, &process_snapshot, &minidump);
if (!minidump.WriteEverything(new_report->Writer())) {
Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kMinidumpWriteFailed);

View File

@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef CRASHPAD_CLIENT_IOS_HANDLER_IN_PROCESS_IN_PROCESS_HANDLER_H_
#define CRASHPAD_CLIENT_IOS_HANDLER_IN_PROCESS_IN_PROCESS_HANDLER_H_
#include <mach/mach.h>
#include <stdint.h>
@ -26,6 +29,7 @@
#include "client/ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h"
#include "client/upload_behavior_ios.h"
#include "handler/crash_report_upload_thread.h"
#include "handler/user_stream_data_source.h"
#include "snapshot/ios/process_snapshot_ios_intermediate_dump.h"
#include "util/ios/ios_intermediate_dump_writer.h"
#include "util/ios/ios_system_data_collector.h"
@ -159,17 +163,27 @@ class InProcessHandler {
//! minidumps and trigger an upload if possible.
//!
//! \param[in] annotations Process annotations to set in each crash report.
//! \param[in] user_stream_sources An optional vector containing the
//! extensibility data sources to call on crash. Each time a minidump is
//! created, the sources are called in turn. Any streams returned are
//! added to the minidump.
void ProcessIntermediateDumps(
const std::map<std::string, std::string>& annotations);
const std::map<std::string, std::string>& annotations,
const UserStreamDataSources* user_stream_sources);
//! \brief Requests that the handler convert a specific intermediate dump into
//! a minidump and trigger an upload if possible.
//!
//! \param[in] path Path to the specific intermediate dump.
//! \param[in] annotations Process annotations to set in each crash report.
//! \param[in] user_stream_sources An optional vector containing the
//! extensibility data sources to call on crash. Each time a minidump is
//! created, the sources are called in turn. Any streams returned are
//! added to the minidump.
void ProcessIntermediateDump(
const base::FilePath& path,
const std::map<std::string, std::string>& annotations = {});
const std::map<std::string, std::string>& annotations = {},
const UserStreamDataSources* user_stream_sources = {});
//! \brief Requests that the handler begin in-process uploading of any
//! pending reports.
@ -239,7 +253,12 @@ class InProcessHandler {
//! \brief Writes a minidump to the Crashpad database from the
//! \a process_snapshot, and triggers the upload_thread_ if started.
void SaveSnapshot(ProcessSnapshotIOSIntermediateDump& process_snapshot);
//! \param[in] user_stream_sources An optional vector containing the
//! extensibility data sources to call on crash. Each time a minidump is
//! created, the sources are called in turn. Any streams returned are
//! added to the minidump.
void SaveSnapshot(ProcessSnapshotIOSIntermediateDump& process_snapshot,
const UserStreamDataSources* user_stream_sources = {});
//! \brief Process a maximum of 20 pending intermediate dumps. Dumps named
//! with our bundle id get first priority to prevent spamming.
@ -284,3 +303,5 @@ class InProcessHandler {
} // namespace internal
} // namespace crashpad
#endif // CRASHPAD_CLIENT_IOS_HANDLER_IN_PROCESS_IN_PROCESS_HANDLER_H_

View File

@ -110,35 +110,35 @@ TEST_F(InProcessHandlerTest, TestPendingFileLimit) {
// Only process other app files.
CreateFiles(0, 20);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(0, 0);
ClearFiles();
// Only process our app files.
CreateFiles(20, 20);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(0, 20);
ClearFiles();
// Process all of our files and 10 remaining.
CreateFiles(10, 30);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(0, 20);
ClearFiles();
// Process 20 our files, leaving 10 remaining, and all other files remaining.
CreateFiles(30, 10);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(10, 10);
ClearFiles();
CreateFiles(0, 0);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(0, 0);
ClearFiles();
CreateFiles(10, 0);
handler().ProcessIntermediateDumps({});
handler().ProcessIntermediateDumps({}, {});
VerifyRemainingFileCount(0, 0);
ClearFiles();
}

View File

@ -20,8 +20,6 @@ static_library("handler") {
"handler_main.h",
"prune_crash_reports_thread.cc",
"prune_crash_reports_thread.h",
"user_stream_data_source.cc",
"user_stream_data_source.h",
]
if (crashpad_is_mac) {
@ -98,6 +96,8 @@ static_library("common") {
"crash_report_upload_thread.h",
"minidump_to_upload_parameters.cc",
"minidump_to_upload_parameters.h",
"user_stream_data_source.cc",
"user_stream_data_source.h",
]
if (crashpad_is_apple) {
sources += [
@ -112,6 +112,7 @@ static_library("common") {
]
deps = [
"../client:common",
"../minidump",
"../snapshot",
"../util",
"../util:net",