From 202283a85c33595fde5da730e3add2c4df9df835 Mon Sep 17 00:00:00 2001 From: Justin Cohen Date: Wed, 14 Jul 2021 20:28:17 -0400 Subject: [PATCH] ios: Add API to DumpWithoutCrashAndDeferProcessingAtPath. DumpWithoutCrashAndDeferProcessingAtPath(path) generate an intermediate dump that can only be processed if ProcessIntermediateDump(file) is called. This means the client retains ownership of cleaning up the intermediate dump if for whatever reason it is no longer needed. This is useful for Chromium hang reports, which are speculatively generated during a hang, but are later deleted if a hang recovers or if the hang leads to an actual crash. Bug: crashpad: 31 Change-Id: Ie424b375ceae3f5c0da320e766c990ea10df2f52 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3021668 Reviewed-by: Mark Mentovai Commit-Queue: Justin Cohen --- client/crashpad_client.h | 40 ++++++++++++++++++++++++++++++++--- client/crashpad_client_ios.cc | 23 ++++++++++++++++++++ client/simulate_crash_ios.h | 8 +++++++ 3 files changed, 68 insertions(+), 3 deletions(-) diff --git a/client/crashpad_client.h b/client/crashpad_client.h index ec6c5e56..10ad4047 100644 --- a/client/crashpad_client.h +++ b/client/crashpad_client.h @@ -462,7 +462,7 @@ class CrashpadClient { //! \param[in] database The path to a Crashpad database. //! \param[in] url The URL of an upload server. //! \param[in] annotations Process annotations to set in each crash report. - void StartCrashpadInProcessHandler( + static void StartCrashpadInProcessHandler( const base::FilePath& database, const std::string& url, const std::map& annotations); @@ -479,7 +479,24 @@ 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. - void ProcessIntermediateDumps( + static void ProcessIntermediateDumps( + const std::map& annotations = {}); + + //! \brief Requests that the handler convert a single intermediate dump at \a + //! file generated by DumpWithoutCrashAndDeferProcessingAtPath into a + //! minidump and trigger an upload if possible. + //! + //! A handler must have already been installed before calling this method. + //! This method should be called when an application is ready to start + //! processing previously created intermediate dumps. Processing will block, + //! so this should not be called on the main UI thread. + //! + //! \param[in] file The intermediate dump to process. + //! \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. + static void ProcessIntermediateDump( + const base::FilePath& file, const std::map& annotations = {}); //! \brief Requests that the handler begin in-process uploading of any @@ -489,7 +506,7 @@ class CrashpadClient { //! on another thread. This method does not block. //! //! A handler must have already been installed before calling this method. - void StartProcesingPendingReports(); + static void StartProcesingPendingReports(); //! \brief Requests that the handler capture an intermediate dump even though //! there hasn't been a crash. The intermediate dump will be converted @@ -516,6 +533,23 @@ class CrashpadClient { //! \param[in] context A NativeCPUContext, generally captured by //! CaptureContext() or similar. static void DumpWithoutCrashAndDeferProcessing(NativeCPUContext* context); + + //! \brief Requests that the handler capture an intermediate dump and store it + //! in path, even though there hasn't been a crash. The intermediate dump + //! will not be converted to a mindump until ProcessIntermediateDump() is + //! called. + //! + //! For internal use only. Clients should use + //! CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING_AT_PATH(). + //! + //! A handler must have already been installed before calling this method. + //! + //! \param[in] context A NativeCPUContext, generally captured by + //! CaptureContext() or similar. + //! \param[in] path The path for writing the intermediate dump. + static void DumpWithoutCrashAndDeferProcessingAtPath( + NativeCPUContext* context, + const base::FilePath path); #endif #if defined(OS_APPLE) || DOXYGEN diff --git a/client/crashpad_client_ios.cc b/client/crashpad_client_ios.cc index 69e90d8c..5c1f1ee4 100644 --- a/client/crashpad_client_ios.cc +++ b/client/crashpad_client_ios.cc @@ -55,6 +55,10 @@ class CrashHandler : public Thread, public UniversalMachExcServer::Interface { void ProcessIntermediateDumps( const std::map& annotations = {}) {} + void ProcessIntermediateDump( + const base::FilePath& file, + const std::map& annotations = {}) {} + void DumpWithoutCrash(NativeCPUContext* context) { INITIALIZATION_STATE_DCHECK_VALID(initialized_); mach_exception_data_type_t code[2] = {}; @@ -219,6 +223,15 @@ void CrashpadClient::ProcessIntermediateDumps( crash_handler->ProcessIntermediateDumps(annotations); } +// static +void CrashpadClient::ProcessIntermediateDump( + const base::FilePath& file, + const std::map& annotations) { + CrashHandler* crash_handler = CrashHandler::Get(); + DCHECK(crash_handler); + crash_handler->ProcessIntermediateDump(file, annotations); +} + // static void CrashpadClient::StartProcesingPendingReports() { // TODO(justincohen): Start the CrashReportUploadThread. @@ -242,4 +255,14 @@ void CrashpadClient::DumpWithoutCrashAndDeferProcessing( crash_handler->DumpWithoutCrash(context); } +// static +void CrashpadClient::DumpWithoutCrashAndDeferProcessingAtPath( + NativeCPUContext* context, + const base::FilePath path) { + CrashHandler* crash_handler = CrashHandler::Get(); + DCHECK(crash_handler); + // TODO(justincohen): Change to DumpWithoutCrashAtPath(context, path). + crash_handler->DumpWithoutCrash(context); +} + } // namespace crashpad diff --git a/client/simulate_crash_ios.h b/client/simulate_crash_ios.h index 87a94578..14e1e153 100644 --- a/client/simulate_crash_ios.h +++ b/client/simulate_crash_ios.h @@ -47,4 +47,12 @@ &cpu_context); \ } while (false) +#define CRASHPAD_SIMULATE_CRASH_AND_DEFER_PROCESSING_AT_PATH(path) \ + do { \ + crashpad::NativeCPUContext cpu_context; \ + crashpad::CaptureContext(&cpu_context); \ + crashpad::CrashpadClient::DumpWithoutCrashAndDeferProcessingAtPath( \ + &cpu_context, path); \ + } while (false) + #endif // CRASHPAD_CLIENT_SIMULATE_CRASH_IOS_H_