diff --git third_party/crashpad/crashpad/client/prune_crash_reports.cc third_party/crashpad/crashpad/client/prune_crash_reports.cc index 077694f541d57..928a520485414 100644 --- third_party/crashpad/crashpad/client/prune_crash_reports.cc +++ third_party/crashpad/crashpad/client/prune_crash_reports.cc @@ -75,13 +75,19 @@ size_t PruneCrashReportDatabase(CrashReportDatabase* database, } // static -std::unique_ptr PruneCondition::GetDefault() { +std::unique_ptr PruneCondition::GetDefault( + int max_size_in_mb, + int max_age_in_days) { // DatabaseSizePruneCondition must be the LHS so that it is always evaluated, // due to the short-circuting behavior of BinaryPruneCondition. + if (max_size_in_mb <= 0) + max_size_in_mb = 128; + if (max_age_in_days <= 0) + max_age_in_days = 365; return std::make_unique( BinaryPruneCondition::OR, - new DatabaseSizePruneCondition(1024 * 128), - new AgePruneCondition(365)); + new DatabaseSizePruneCondition(1024 * max_size_in_mb), + new AgePruneCondition(max_age_in_days)); } static const time_t kSecondsInDay = 60 * 60 * 24; diff --git third_party/crashpad/crashpad/client/prune_crash_reports.h third_party/crashpad/crashpad/client/prune_crash_reports.h index b362e0aadbadd..1588232a6e4d4 100644 --- third_party/crashpad/crashpad/client/prune_crash_reports.h +++ third_party/crashpad/crashpad/client/prune_crash_reports.h @@ -58,7 +58,8 @@ class PruneCondition { //! of 128 MB. //! //! \return A PruneCondition for use with PruneCrashReportDatabase(). - static std::unique_ptr GetDefault(); + static std::unique_ptr GetDefault(int max_size_in_mb, + int max_age_in_days); virtual ~PruneCondition() {} diff --git third_party/crashpad/crashpad/client/settings.cc third_party/crashpad/crashpad/client/settings.cc index 5e4119e2175c7..e66600089be04 100644 --- third_party/crashpad/crashpad/client/settings.cc +++ third_party/crashpad/crashpad/client/settings.cc @@ -117,7 +117,7 @@ void ScopedLockedFileHandleTraits::Free(FileHandle handle) { struct Settings::Data { static constexpr uint32_t kSettingsMagic = 'CPds'; - static constexpr uint32_t kSettingsVersion = 1; + static constexpr uint32_t kSettingsVersion = 2; enum Options : uint32_t { kUploadsEnabled = 1 << 0, @@ -128,6 +128,9 @@ struct Settings::Data { options(0), padding_0(0), last_upload_attempt_time(0), + next_upload_attempt_time(0), + backoff_step(0), + padding_1(0), client_id() {} uint32_t magic; @@ -135,6 +138,9 @@ struct Settings::Data { uint32_t options; uint32_t padding_0; int64_t last_upload_attempt_time; // time_t + int64_t next_upload_attempt_time; // time_t + uint32_t backoff_step; + uint32_t padding_1; UUID client_id; }; @@ -234,6 +240,56 @@ bool Settings::IsLockExpired(const base::FilePath& file_path, } #endif // !CRASHPAD_FLOCK_ALWAYS_SUPPORTED +bool Settings::GetNextUploadAttemptTime(time_t* time) { + DCHECK(initialized_.is_valid()); + + Data settings; + if (!OpenAndReadSettings(&settings)) + return false; + + *time = InRangeCast(settings.next_upload_attempt_time, + std::numeric_limits::max()); + return true; +} + +bool Settings::SetNextUploadAttemptTime(time_t time) { + DCHECK(initialized_.is_valid()); + + Data settings; + ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings); + if (!handle.is_valid()) + return false; + + settings.next_upload_attempt_time = InRangeCast(time, 0); + + return WriteSettings(handle.get(), settings); +} + +bool Settings::GetBackoffStep(int* step) { + DCHECK(initialized_.is_valid()); + + Data settings; + if (!OpenAndReadSettings(&settings)) + return false; + + *step = InRangeCast(settings.backoff_step, + std::numeric_limits::max()); + return true; +} + +bool Settings::SetBackoffStep(int step) { + DCHECK(initialized_.is_valid()); + + Data settings; + ScopedLockedFileHandle handle = OpenForWritingAndReadSettings(&settings); + if (!handle.is_valid()) + return false; + + settings.backoff_step = InRangeCast(step, 0); + + return WriteSettings(handle.get(), settings); +} + // static Settings::ScopedLockedFileHandle Settings::MakeScopedLockedFileHandle( const internal::MakeScopedLockedFileHandleOptions& options, diff --git third_party/crashpad/crashpad/client/settings.h third_party/crashpad/crashpad/client/settings.h index 39b2de869d225..5a4e621c650ee 100644 --- third_party/crashpad/crashpad/client/settings.h +++ third_party/crashpad/crashpad/client/settings.h @@ -156,6 +156,11 @@ class Settings { time_t lockfile_ttl); #endif // !CRASHPAD_FLOCK_ALWAYS_SUPPORTED + bool GetNextUploadAttemptTime(time_t* time); + bool SetNextUploadAttemptTime(time_t time); + bool GetBackoffStep(int* step); + bool SetBackoffStep(int step); + private: struct Data; diff --git third_party/crashpad/crashpad/handler/BUILD.gn third_party/crashpad/crashpad/handler/BUILD.gn index 02bf11a6de045..48d00a9c44123 100644 --- third_party/crashpad/crashpad/handler/BUILD.gn +++ third_party/crashpad/crashpad/handler/BUILD.gn @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import("//cef/libcef/features/features.gni") import("../build/crashpad_buildconfig.gni") static_library("handler") { @@ -62,6 +63,17 @@ static_library("handler") { ] } + if (enable_cef) { + sources += [ + "//cef/libcef/common/cef_crash_report_upload_thread.cc", + "//cef/libcef/common/cef_crash_report_upload_thread.h", + "//cef/libcef/common/cef_crash_report_utils.cc", + "//cef/libcef/common/cef_crash_report_utils.h", + ] + + configs += [ "//cef/libcef/features:config" ] + } + public_configs = [ "..:crashpad_config" ] public_deps = [ @@ -77,6 +89,7 @@ static_library("handler") { "../snapshot", "../third_party/mini_chromium:chromeos_buildflags", "../tools:tool_support", + "//cef/libcef/features", ] if (crashpad_is_win) { diff --git third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc index 5bd2889eda975..bf3ff4bfcf5c8 100644 --- third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc +++ third_party/crashpad/crashpad/handler/crash_report_upload_thread.cc @@ -297,6 +297,8 @@ CrashReportUploadThread::UploadResult CrashReportUploadThread::UploadReport( if (minidump_process_snapshot.Initialize(reader)) { parameters = BreakpadHTTPFormParametersFromMinidump(&minidump_process_snapshot); + if (!parameters.empty()) + parameters = FilterParameters(parameters); } if (!reader->SeekSet(start_offset)) { diff --git third_party/crashpad/crashpad/handler/crash_report_upload_thread.h third_party/crashpad/crashpad/handler/crash_report_upload_thread.h index 22bb26e31893b..87c80604e5f7a 100644 --- third_party/crashpad/crashpad/handler/crash_report_upload_thread.h +++ third_party/crashpad/crashpad/handler/crash_report_upload_thread.h @@ -16,6 +16,7 @@ #define CRASHPAD_HANDLER_CRASH_REPORT_UPLOAD_THREAD_H_ #include +#include #include #include #include @@ -128,7 +129,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate, //! \return `true` if the thread is running, `false` if it is not. bool is_running() const { return thread_.is_running(); } - private: + protected: //! \brief The result code from UploadReport(). enum class UploadResult { //! \brief The crash report was uploaded successfully. @@ -156,7 +157,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate, //! object was constructed with \a watch_pending_reports, it will also scan //! the crash report database for other pending reports, and process those as //! well. - void ProcessPendingReports(); + virtual void ProcessPendingReports(); //! \brief Processes a single pending report from the database. //! @@ -170,7 +171,7 @@ class CrashReportUploadThread : public WorkerThread::Delegate, //! remain in the “pending” state. If the upload fails and no more retries are //! desired, or report upload is disabled, it will be marked as “completed” in //! the database without ever having been uploaded. - void ProcessPendingReport(const CrashReportDatabase::Report& report); + virtual void ProcessPendingReport(const CrashReportDatabase::Report& report); //! \brief Attempts to upload a crash report. //! @@ -187,6 +188,11 @@ class CrashReportUploadThread : public WorkerThread::Delegate, UploadResult UploadReport(const CrashReportDatabase::UploadReport* report, std::string* response_body); + using ParameterMap = std::map; + virtual ParameterMap FilterParameters(const ParameterMap& parameters) { + return parameters; + } + // WorkerThread::Delegate: //! \brief Calls ProcessPendingReports() in response to ReportPending() having //! been called on any thread, as well as periodically on a timer. diff --git third_party/crashpad/crashpad/handler/handler_main.cc third_party/crashpad/crashpad/handler/handler_main.cc index b7ba6b14bb9b3..0567343c99325 100644 --- third_party/crashpad/crashpad/handler/handler_main.cc +++ third_party/crashpad/crashpad/handler/handler_main.cc @@ -39,6 +39,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" +#include "cef/libcef/features/features.h" #include "client/crash_report_database.h" #include "client/crashpad_client.h" #include "client/crashpad_info.h" @@ -89,6 +90,10 @@ #include "util/win/session_end_watcher.h" #endif // BUILDFLAG(IS_APPLE) +#if BUILDFLAG(ENABLE_CEF) +#include "cef/libcef/common/cef_crash_report_upload_thread.h" +#endif + namespace crashpad { namespace { @@ -248,6 +253,9 @@ struct Options { bool periodic_tasks; bool rate_limit; bool upload_gzip; + int max_uploads; + int max_database_size; + int max_database_age; #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) bool use_cros_crash_reporter = false; base::FilePath minidump_dir_for_tests; @@ -622,6 +630,9 @@ int HandlerMain(int argc, kOptionTraceParentWithException, #endif kOptionURL, + kOptionMaxUploads, + kOptionMaxDatabaseSize, + kOptionMaxDatabaseAge, #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) kOptionUseCrosCrashReporter, kOptionMinidumpDirForTests, @@ -722,6 +733,9 @@ int HandlerMain(int argc, #endif // BUILDFLAG(IS_ANDROID) {"help", no_argument, nullptr, kOptionHelp}, {"version", no_argument, nullptr, kOptionVersion}, + {"max-uploads", required_argument, nullptr, kOptionMaxUploads}, + {"max-db-size", required_argument, nullptr, kOptionMaxDatabaseSize}, + {"max-db-age", required_argument, nullptr, kOptionMaxDatabaseAge}, {nullptr, 0, nullptr, 0}, }; @@ -879,6 +893,27 @@ int HandlerMain(int argc, options.url = optarg; break; } + case kOptionMaxUploads: { + if (base::StringToInt(optarg, &options.max_uploads)) { + if (options.max_uploads < 0) + options.max_uploads = 0; + } + break; + } + case kOptionMaxDatabaseSize: { + if (base::StringToInt(optarg, &options.max_database_size)) { + if (options.max_database_size < 0) + options.max_database_size = 0; + } + break; + } + case kOptionMaxDatabaseAge: { + if (base::StringToInt(optarg, &options.max_database_age)) { + if (options.max_database_age < 0) + options.max_database_age = 0; + } + break; + } #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) case kOptionUseCrosCrashReporter: { options.use_cros_crash_reporter = true; @@ -1028,11 +1063,20 @@ int HandlerMain(int argc, upload_thread_options.upload_gzip = options.upload_gzip; upload_thread_options.watch_pending_reports = options.periodic_tasks; +#if BUILDFLAG(ENABLE_CEF) + upload_thread.Reset(new CefCrashReportUploadThread( + database.get(), + options.url, + upload_thread_options, + CrashReportUploadThread::ProcessPendingReportsObservationCallback(), + options.max_uploads)); +#else upload_thread.Reset(new CrashReportUploadThread( database.get(), options.url, upload_thread_options, CrashReportUploadThread::ProcessPendingReportsObservationCallback())); +#endif upload_thread.Get()->Start(); } @@ -1103,7 +1147,8 @@ int HandlerMain(int argc, ScopedStoppable prune_thread; if (options.periodic_tasks) { prune_thread.Reset(new PruneCrashReportThread( - database.get(), PruneCondition::GetDefault())); + database.get(), PruneCondition::GetDefault(options.max_database_size, + options.max_database_age))); prune_thread.Get()->Start(); }