diff --git a/DEPS b/DEPS index f3edda6c..f4a8d97a 100644 --- a/DEPS +++ b/DEPS @@ -25,7 +25,7 @@ deps = { '93cc6e2c23e4d5ebd179f388e67aa907d0dfd43d', 'crashpad/third_party/mini_chromium/mini_chromium': Var('chromium_git') + '/chromium/mini_chromium@' + - '7800285e83df4286981bb933e3335edade7c8308', + '438bd4f4d8d38dd5c31e78a0d605cc4cf6be5229', 'buildtools': Var('chromium_git') + '/chromium/buildtools.git@' + 'f8fc76ea5ce4a60cda2fa5d7df3d4a62935b3113', diff --git a/client/crashpad_client.h b/client/crashpad_client.h index 61338a3c..f8f1a612 100644 --- a/client/crashpad_client.h +++ b/client/crashpad_client.h @@ -55,6 +55,9 @@ class CrashpadClient { //! \param[in] handler The path to a Crashpad handler executable. //! \param[in] database The path to a Crashpad database. The handler will be //! started with this path as its `--database` argument. + //! \param[in] metrics_dir The path to an already existing directory where + //! metrics files can be stored. The handler will be started with this + //! path as its `--metrics-dir` argument. //! \param[in] url The URL of an upload server. The handler will be started //! with this URL as its `--url` argument. //! \param[in] annotations Process annotations to set in each crash report. @@ -72,6 +75,7 @@ class CrashpadClient { //! \return `true` on success, `false` on failure with a message logged. bool StartHandler(const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments, diff --git a/client/crashpad_client_mac.cc b/client/crashpad_client_mac.cc index 89a2e275..c1e305ae 100644 --- a/client/crashpad_client_mac.cc +++ b/client/crashpad_client_mac.cc @@ -121,6 +121,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { static base::mac::ScopedMachSendRight InitialStart( const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments, @@ -159,6 +160,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { if (!CommonStart(handler, database, + metrics_dir, url, annotations, arguments, @@ -170,7 +172,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { if (handler_restarter && handler_restarter->StartRestartThread( - handler, database, url, annotations, arguments)) { + handler, database, metrics_dir, url, annotations, arguments)) { // The thread owns the object now. ignore_result(handler_restarter.release()); } @@ -201,6 +203,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { // be called again for another try. CommonStart(handler_, database_, + metrics_dir_, url_, annotations_, arguments_, @@ -216,6 +219,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { : NotifyServer::DefaultInterface(), handler_(), database_(), + metrics_dir_(), url_(), annotations_(), arguments_(), @@ -244,6 +248,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { //! rendezvous with it via ChildPortHandshake. static bool CommonStart(const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments, @@ -320,6 +325,9 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { if (!database.value().empty()) { argv.push_back(FormatArgumentString("database", database.value())); } + if (!metrics_dir.value().empty()) { + argv.push_back(FormatArgumentString("metrics-dir", metrics_dir.value())); + } if (!url.empty()) { argv.push_back(FormatArgumentString("url", url)); } @@ -445,11 +453,13 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { bool StartRestartThread(const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments) { handler_ = handler; database_ = database; + metrics_dir_ = metrics_dir; url_ = url; annotations_ = annotations; arguments_ = arguments; @@ -501,6 +511,7 @@ class HandlerStarter final : public NotifyServer::DefaultInterface { base::FilePath handler_; base::FilePath database_; + base::FilePath metrics_dir_; std::string url_; std::map annotations_; std::vector arguments_; @@ -522,6 +533,7 @@ CrashpadClient::~CrashpadClient() { bool CrashpadClient::StartHandler( const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments, @@ -534,6 +546,7 @@ bool CrashpadClient::StartHandler( base::mac::ScopedMachSendRight exception_port( HandlerStarter::InitialStart(handler, database, + metrics_dir, url, annotations, arguments, diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc index 537e18ab..40a3b093 100644 --- a/client/crashpad_client_win.cc +++ b/client/crashpad_client_win.cc @@ -200,6 +200,7 @@ CrashpadClient::~CrashpadClient() { bool CrashpadClient::StartHandler( const base::FilePath& handler, const base::FilePath& database, + const base::FilePath& metrics_dir, const std::string& url, const std::map& annotations, const std::vector& arguments, @@ -232,6 +233,11 @@ bool CrashpadClient::StartHandler( database.value()), &command_line); } + if (!metrics_dir.value().empty()) { + AppendCommandLineArgument( + FormatArgumentString("metrics-dir", metrics_dir.value()), + &command_line); + } if (!url.empty()) { AppendCommandLineArgument(FormatArgumentString("url", base::UTF8ToUTF16(url)), diff --git a/client/crashpad_client_win_test.cc b/client/crashpad_client_win_test.cc index fdf773fd..0c222cc8 100644 --- a/client/crashpad_client_win_test.cc +++ b/client/crashpad_client_win_test.cc @@ -31,6 +31,7 @@ void StartAndUseHandler() { CrashpadClient client; ASSERT_TRUE(client.StartHandler(handler_path, temp_dir.path(), + base::FilePath(), "", std::map(), std::vector(), diff --git a/handler/handler_main.cc b/handler/handler_main.cc index 3240cd38..ad6d5acc 100644 --- a/handler/handler_main.cc +++ b/handler/handler_main.cc @@ -27,6 +27,7 @@ #include "base/files/file_path.h" #include "base/files/scoped_file.h" #include "base/logging.h" +#include "base/metrics/persistent_histogram_allocator.h" #include "base/scoped_generic.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -78,6 +79,7 @@ void Usage(const base::FilePath& me) { " --handshake-handle=HANDLE\n" " create a new pipe and send its name via HANDLE\n" #endif // OS_MACOSX +" --metrics-dir=DIR store metrics files in DIR (only in Chromium)\n" " --no-rate-limit don't rate limit crash uploads\n" #if defined(OS_MACOSX) " --reset-own-crash-exception-port-to-system-default\n" @@ -136,6 +138,7 @@ int HandlerMain(int argc, char* argv[]) { #elif defined(OS_WIN) kOptionHandshakeHandle, #endif // OS_MACOSX + kOptionMetrics, kOptionNoRateLimit, #if defined(OS_MACOSX) kOptionResetOwnCrashExceptionPortToSystemDefault, @@ -153,6 +156,7 @@ int HandlerMain(int argc, char* argv[]) { std::map annotations; std::string url; const char* database; + const char* metrics; #if defined(OS_MACOSX) int handshake_fd; std::string mach_service; @@ -179,6 +183,7 @@ int HandlerMain(int argc, char* argv[]) { #elif defined(OS_WIN) {"handshake-handle", required_argument, nullptr, kOptionHandshakeHandle}, #endif // OS_MACOSX + {"metrics-dir", required_argument, nullptr, kOptionMetrics}, {"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit}, #if defined(OS_MACOSX) {"reset-own-crash-exception-port-to-system-default", @@ -243,6 +248,10 @@ int HandlerMain(int argc, char* argv[]) { break; } #endif // OS_MACOSX + case kOptionMetrics: { + options.metrics = optarg; + break; + } case kOptionNoRateLimit: { options.rate_limit = false; break; @@ -386,6 +395,19 @@ int HandlerMain(int argc, char* argv[]) { } #endif // OS_MACOSX + base::GlobalHistogramAllocator* histogram_allocator = nullptr; + if (options.metrics) { + const base::FilePath metrics_dir( + ToolSupport::CommandLineArgumentToFilePathStringType(options.metrics)); + static const char kMetricsName[] = "CrashpadMetrics"; + const size_t kMetricsFileSize = 1 << 20; + if (base::GlobalHistogramAllocator::CreateWithActiveFileInDir( + metrics_dir, kMetricsFileSize, 0, kMetricsName)) { + histogram_allocator = base::GlobalHistogramAllocator::Get(); + histogram_allocator->CreateTrackingHistograms(kMetricsName); + } + } + std::unique_ptr database(CrashReportDatabase::Initialize( base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType( options.database)))); @@ -412,6 +434,9 @@ int HandlerMain(int argc, char* argv[]) { upload_thread.Stop(); prune_thread.Stop(); + if (histogram_allocator) + histogram_allocator->DeletePersistentLocation(); + return EXIT_SUCCESS; } diff --git a/handler/win/crashy_test_program.cc b/handler/win/crashy_test_program.cc index d04e55ca..021233ce 100644 --- a/handler/win/crashy_test_program.cc +++ b/handler/win/crashy_test_program.cc @@ -178,6 +178,7 @@ int CrashyMain(int argc, wchar_t* argv[]) { } else if (argc == 3) { if (!client.StartHandler(base::FilePath(argv[1]), base::FilePath(argv[2]), + base::FilePath(), std::string(), std::map(), std::vector(),