Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1248)

Unified Diff: third_party/crashpad/crashpad/handler/handler_main.cc

Issue 2705373005: Revert of Update Crashpad to 6da9708e7cc93e2e1772439d51646e47583cb225 (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/crashpad/crashpad/handler/handler_main.cc
diff --git a/third_party/crashpad/crashpad/handler/handler_main.cc b/third_party/crashpad/crashpad/handler/handler_main.cc
index c7c2b29738bde496f39cd31c8594fc8946ff5456..9433a6af5186ec33ebf6c68fb17948adb227381d 100644
--- a/third_party/crashpad/crashpad/handler/handler_main.cc
+++ b/third_party/crashpad/crashpad/handler/handler_main.cc
@@ -24,10 +24,8 @@
#include <memory>
#include <string>
#include <utility>
-#include <vector>
#include "base/auto_reset.h"
-#include "base/compiler_specific.h"
#include "base/files/file_path.h"
#include "base/files/scoped_file.h"
#include "base/logging.h"
@@ -66,7 +64,6 @@
#include "util/win/exception_handler_server.h"
#include "util/win/handle.h"
#include "util/win/initial_client_data.h"
-#include "util/win/session_end_watcher.h"
#endif // OS_MACOSX
namespace crashpad {
@@ -96,7 +93,6 @@ void Usage(const base::FilePath& me) {
#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"
-" --no-upload-gzip don't use gzip compression when uploading\n"
#if defined(OS_MACOSX)
" --reset-own-crash-exception-port-to-system-default\n"
" reset the server's exception handler to default\n"
@@ -111,65 +107,11 @@ void Usage(const base::FilePath& me) {
ToolSupport::UsageTail(me);
}
-// Calls Metrics::HandlerLifetimeMilestone, but only on the first call. This is
-// to prevent multiple exit events from inadvertently being recorded, which
-// might happen if a crash occurs during destruction in what would otherwise be
-// a normal exit, or if a CallMetricsRecordNormalExit object is destroyed after
-// something else logs an exit event.
-void MetricsRecordExit(Metrics::LifetimeMilestone milestone) {
- static bool once = [](Metrics::LifetimeMilestone milestone) {
- Metrics::HandlerLifetimeMilestone(milestone);
- return true;
- }(milestone);
- ALLOW_UNUSED_LOCAL(once);
-}
-
-// Calls MetricsRecordExit() to record a failure, and returns EXIT_FAILURE for
-// the convenience of callers in main() which can simply write “return
-// ExitFailure();”.
-int ExitFailure() {
- MetricsRecordExit(Metrics::LifetimeMilestone::kFailed);
- return EXIT_FAILURE;
-}
-
-class CallMetricsRecordNormalExit {
- public:
- CallMetricsRecordNormalExit() {}
- ~CallMetricsRecordNormalExit() {
- MetricsRecordExit(Metrics::LifetimeMilestone::kExitedNormally);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CallMetricsRecordNormalExit);
-};
-
#if defined(OS_MACOSX)
-void InstallSignalHandler(const std::vector<int>& signals,
- void (*handler)(int, siginfo_t*, void*)) {
- struct sigaction sa = {};
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = SA_SIGINFO;
- sa.sa_sigaction = handler;
-
- for (int sig : signals) {
- int rv = sigaction(sig, &sa, nullptr);
- PCHECK(rv == 0) << "sigaction " << sig;
- }
-}
-
-void RestoreDefaultSignalHandler(int sig) {
- struct sigaction sa = {};
- sigemptyset(&sa.sa_mask);
- sa.sa_flags = 0;
- sa.sa_handler = SIG_DFL;
- int rv = sigaction(sig, &sa, nullptr);
- DPLOG_IF(ERROR, rv != 0) << "sigaction " << sig;
-}
+struct sigaction g_original_crash_sigaction[NSIG];
void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
- MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed);
-
// Is siginfo->si_code useful? The only interesting values on macOS are 0 (not
// useful, signals generated asynchronously such as by kill() or raise()) and
// small positive numbers (useful, signal generated via a hardware fault). The
@@ -201,17 +143,22 @@ void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
}
Metrics::HandlerCrashed(metrics_code);
- RestoreDefaultSignalHandler(sig);
+ // Restore the previous signal handler.
+ DCHECK_GT(sig, 0);
+ DCHECK_LT(static_cast<size_t>(sig), arraysize(g_original_crash_sigaction));
+ struct sigaction* osa = &g_original_crash_sigaction[sig];
+ int rv = sigaction(sig, osa, nullptr);
+ DPLOG_IF(ERROR, rv != 0) << "sigaction " << sig;
// If the signal was received synchronously resulting from a hardware fault,
// returning from the signal handler will cause the kernel to re-raise it,
// because this handler hasn’t done anything to alleviate the condition that
- // caused the signal to be raised in the first place. With the default signal
- // handler in place, it will cause the same behavior to be taken as though
- // this signal handler had never been installed at all (expected to be a
- // crash). This is ideal, because the signal is re-raised with the same
- // properties and from the same context that initially triggered it, providing
- // the best debugging experience.
+ // caused the signal to be raised in the first place. With the old signal
+ // handler in place (expected to be SIG_DFL), it will cause the same behavior
+ // to be taken as though this signal handler had never been installed at all
+ // (expected to be a crash). This is ideal, because the signal is re-raised
+ // with the same properties and from the same context that initially triggered
+ // it, providing the best debugging experience.
if ((sig != SIGILL && sig != SIGFPE && sig != SIGBUS && sig != SIGSEGV) ||
!si_code_valid) {
@@ -219,7 +166,8 @@ void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
// asynchronously via kill() and raise(), and those arising via hardware
// traps such as int3 (resulting in SIGTRAP but advancing the instruction
// pointer), will not reoccur on their own when returning from the signal
- // handler. Re-raise them.
+ // handler. Re-raise them or call to the previous signal handler as
+ // appropriate.
//
// Unfortunately, when SIGBUS is received asynchronously via kill(),
// siginfo->si_code makes it appear as though it was actually received via a
@@ -232,66 +180,49 @@ void HandleCrashSignal(int sig, siginfo_t* siginfo, void* context) {
// very valuable for debugging and are visible to a Mach exception handler.
// Since SIGBUS is normally received synchronously in response to a hardware
// fault, don’t sweat the unexpected asynchronous case.
- //
- // Because this signal handler executes with the signal blocked, this
- // raise() cannot immediately deliver the signal. Delivery is deferred until
- // this signal handler returns and the signal becomes unblocked. The
- // re-raised signal will appear with the same context as where it was
- // initially triggered.
- int rv = raise(sig);
- DPLOG_IF(ERROR, rv != 0) << "raise";
+ if (osa->sa_handler == SIG_DFL) {
+ // Because this signal handler executes with the signal blocked, this
+ // raise() cannot immediately deliver the signal. Delivery is deferred
+ // until this signal handler returns and the signal becomes unblocked. The
+ // re-raised signal will appear with the same context as where it was
+ // initially triggered.
+ rv = raise(sig);
+ DPLOG_IF(ERROR, rv != 0) << "raise";
+ } else if (osa->sa_handler != SIG_IGN) {
+ if (osa->sa_flags & SA_SIGINFO) {
+ osa->sa_sigaction(sig, siginfo, context);
+ } else {
+ osa->sa_handler(sig);
+ }
+ }
}
}
-void HandleTerminateSignal(int sig, siginfo_t* siginfo, void* context) {
- MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
-
- RestoreDefaultSignalHandler(sig);
-
- // Re-raise the signal. See the explanation in HandleCrashSignal(). Note that
- // no checks for signals arising from synchronous hardware faults are made
- // because termination signals never originate in that way.
- int rv = raise(sig);
- DPLOG_IF(ERROR, rv != 0) << "raise";
-}
-
void InstallCrashHandler() {
+ struct sigaction sa = {};
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = HandleCrashSignal;
+
// These are the core-generating signals from 10.12.3
// xnu-3789.41.3/bsd/sys/signalvar.h sigprop: entries with SA_CORE are in the
// set.
- const int kCrashSignals[] = {SIGQUIT,
- SIGILL,
- SIGTRAP,
- SIGABRT,
- SIGEMT,
- SIGFPE,
- SIGBUS,
- SIGSEGV,
- SIGSYS};
- InstallSignalHandler(
- std::vector<int>(&kCrashSignals[0],
- &kCrashSignals[arraysize(kCrashSignals)]),
- HandleCrashSignal);
-
- // Not a crash handler, but close enough. These are non-core-generating but
- // terminating signals from 10.12.3 xnu-3789.41.3/bsd/sys/signalvar.h sigprop:
- // entries with SA_KILL but not SA_CORE are in the set. SIGKILL is excluded
- // because it is uncatchable.
- const int kTerminateSignals[] = {SIGHUP,
- SIGINT,
- SIGPIPE,
- SIGALRM,
- SIGTERM,
- SIGXCPU,
- SIGXFSZ,
- SIGVTALRM,
- SIGPROF,
- SIGUSR1,
- SIGUSR2};
- InstallSignalHandler(
- std::vector<int>(&kTerminateSignals[0],
- &kTerminateSignals[arraysize(kTerminateSignals)]),
- HandleTerminateSignal);
+ const int kSignals[] = {SIGQUIT,
+ SIGILL,
+ SIGTRAP,
+ SIGABRT,
+ SIGEMT,
+ SIGFPE,
+ SIGBUS,
+ SIGSEGV,
+ SIGSYS};
+
+ for (int sig : kSignals) {
+ DCHECK_GT(sig, 0);
+ DCHECK_LT(static_cast<size_t>(sig), arraysize(g_original_crash_sigaction));
+ int rv = sigaction(sig, &sa, &g_original_crash_sigaction[sig]);
+ PCHECK(rv == 0) << "sigaction " << sig;
+ }
}
struct ResetSIGTERMTraits {
@@ -311,9 +242,6 @@ ExceptionHandlerServer* g_exception_handler_server;
// This signal handler is only operative when being run from launchd.
void HandleSIGTERM(int sig, siginfo_t* siginfo, void* context) {
- // Don’t call MetricsRecordExit(). This is part of the normal exit path when
- // running from launchd.
-
DCHECK(g_exception_handler_server);
g_exception_handler_server->Stop();
}
@@ -323,7 +251,6 @@ void HandleSIGTERM(int sig, siginfo_t* siginfo, void* context) {
LONG(WINAPI* g_original_exception_filter)(EXCEPTION_POINTERS*) = nullptr;
LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
- MetricsRecordExit(Metrics::LifetimeMilestone::kCrashed);
Metrics::HandlerCrashed(exception_pointers->ExceptionRecord->ExceptionCode);
if (g_original_exception_filter)
@@ -332,37 +259,9 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
return EXCEPTION_CONTINUE_SEARCH;
}
-// Handles events like Control-C and Control-Break on a console.
-BOOL WINAPI ConsoleHandler(DWORD console_event) {
- MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
- return false;
-}
-
-// Handles a WM_ENDSESSION message sent when the user session is ending.
-class TerminateHandler final : public SessionEndWatcher {
- public:
- TerminateHandler() : SessionEndWatcher() {}
- ~TerminateHandler() override {}
-
- private:
- // SessionEndWatcher:
- void SessionEnding() override {
- MetricsRecordExit(Metrics::LifetimeMilestone::kTerminated);
- }
-
- DISALLOW_COPY_AND_ASSIGN(TerminateHandler);
-};
-
void InstallCrashHandler() {
g_original_exception_filter =
SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
-
- // These are termination handlers, not crash handlers, but that’s close
- // enough. Note that destroying the TerminateHandler would wait for its thread
- // to exit, which isn’t necessary or desirable.
- SetConsoleCtrlHandler(ConsoleHandler, true);
- static TerminateHandler* terminate_handler = new TerminateHandler();
- ALLOW_UNUSED_LOCAL(terminate_handler);
}
#endif // OS_MACOSX
@@ -371,7 +270,6 @@ void InstallCrashHandler() {
int HandlerMain(int argc, char* argv[]) {
InstallCrashHandler();
- CallMetricsRecordNormalExit metrics_record_normal_exit;
const base::FilePath argv0(
ToolSupport::CommandLineArgumentToFilePathStringType(argv[0]));
@@ -393,7 +291,6 @@ int HandlerMain(int argc, char* argv[]) {
#endif // OS_MACOSX
kOptionMetrics,
kOptionNoRateLimit,
- kOptionNoUploadGzip,
#if defined(OS_MACOSX)
kOptionResetOwnCrashExceptionPortToSystemDefault,
#elif defined(OS_WIN)
@@ -420,13 +317,11 @@ int HandlerMain(int argc, char* argv[]) {
InitialClientData initial_client_data;
#endif // OS_MACOSX
bool rate_limit;
- bool upload_gzip;
} options = {};
#if defined(OS_MACOSX)
options.handshake_fd = -1;
#endif
options.rate_limit = true;
- options.upload_gzip = true;
const option long_options[] = {
{"annotation", required_argument, nullptr, kOptionAnnotation},
@@ -445,7 +340,6 @@ int HandlerMain(int argc, char* argv[]) {
#endif // OS_MACOSX
{"metrics-dir", required_argument, nullptr, kOptionMetrics},
{"no-rate-limit", no_argument, nullptr, kOptionNoRateLimit},
- {"no-upload-gzip", no_argument, nullptr, kOptionNoUploadGzip},
#if defined(OS_MACOSX)
{"reset-own-crash-exception-port-to-system-default",
no_argument,
@@ -468,7 +362,7 @@ int HandlerMain(int argc, char* argv[]) {
std::string value;
if (!SplitStringFirst(optarg, '=', &key, &value)) {
ToolSupport::UsageHint(me, "--annotation requires KEY=VALUE");
- return ExitFailure();
+ return EXIT_FAILURE;
}
std::string old_value;
if (!MapInsertOrReplace(&options.annotations, key, value, &old_value)) {
@@ -487,7 +381,7 @@ int HandlerMain(int argc, char* argv[]) {
options.handshake_fd < 0) {
ToolSupport::UsageHint(me,
"--handshake-fd requires a file descriptor");
- return ExitFailure();
+ return EXIT_FAILURE;
}
break;
}
@@ -500,7 +394,7 @@ int HandlerMain(int argc, char* argv[]) {
if (!options.initial_client_data.InitializeFromString(optarg)) {
ToolSupport::UsageHint(
me, "failed to parse --initial-client-data");
- return ExitFailure();
+ return EXIT_FAILURE;
}
break;
}
@@ -513,10 +407,6 @@ int HandlerMain(int argc, char* argv[]) {
options.rate_limit = false;
break;
}
- case kOptionNoUploadGzip: {
- options.upload_gzip = false;
- break;
- }
#if defined(OS_MACOSX)
case kOptionResetOwnCrashExceptionPortToSystemDefault: {
options.reset_own_crash_exception_port_to_system_default = true;
@@ -534,17 +424,15 @@ int HandlerMain(int argc, char* argv[]) {
}
case kOptionHelp: {
Usage(me);
- MetricsRecordExit(Metrics::LifetimeMilestone::kExitedEarly);
return EXIT_SUCCESS;
}
case kOptionVersion: {
ToolSupport::Version(me);
- MetricsRecordExit(Metrics::LifetimeMilestone::kExitedEarly);
return EXIT_SUCCESS;
}
default: {
ToolSupport::UsageHint(me, nullptr);
- return ExitFailure();
+ return EXIT_FAILURE;
}
}
}
@@ -554,34 +442,34 @@ int HandlerMain(int argc, char* argv[]) {
#if defined(OS_MACOSX)
if (options.handshake_fd < 0 && options.mach_service.empty()) {
ToolSupport::UsageHint(me, "--handshake-fd or --mach-service is required");
- return ExitFailure();
+ return EXIT_FAILURE;
}
if (options.handshake_fd >= 0 && !options.mach_service.empty()) {
ToolSupport::UsageHint(
me, "--handshake-fd and --mach-service are incompatible");
- return ExitFailure();
+ return EXIT_FAILURE;
}
#elif defined(OS_WIN)
if (!options.initial_client_data.IsValid() && options.pipe_name.empty()) {
ToolSupport::UsageHint(me,
"--initial-client-data or --pipe-name is required");
- return ExitFailure();
+ return EXIT_FAILURE;
}
if (options.initial_client_data.IsValid() && !options.pipe_name.empty()) {
ToolSupport::UsageHint(
me, "--initial-client-data and --pipe-name are incompatible");
- return ExitFailure();
+ return EXIT_FAILURE;
}
#endif // OS_MACOSX
if (!options.database) {
ToolSupport::UsageHint(me, "--database is required");
- return ExitFailure();
+ return EXIT_FAILURE;
}
if (argc) {
ToolSupport::UsageHint(me, nullptr);
- return ExitFailure();
+ return EXIT_FAILURE;
}
#if defined(OS_MACOSX)
@@ -606,7 +494,7 @@ int HandlerMain(int argc, char* argv[]) {
}
if (!receive_right.is_valid()) {
- return ExitFailure();
+ return EXIT_FAILURE;
}
ExceptionHandlerServer exception_handler_server(
@@ -623,7 +511,6 @@ int HandlerMain(int argc, char* argv[]) {
// launchd.plist(5).
//
// Set up a SIGTERM handler that will call exception_handler_server.Stop().
- // This replaces the HandleTerminateSignal handler for SIGTERM.
struct sigaction sa = {};
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
@@ -657,20 +544,18 @@ int HandlerMain(int argc, char* argv[]) {
}
}
- Metrics::HandlerLifetimeMilestone(Metrics::LifetimeMilestone::kStarted);
-
std::unique_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize(
base::FilePath(ToolSupport::CommandLineArgumentToFilePathStringType(
options.database))));
if (!database) {
- return ExitFailure();
+ return EXIT_FAILURE;
}
// TODO(scottmg): options.rate_limit should be removed when we have a
// configurable database setting to control upload limiting.
// See https://crashpad.chromium.org/bug/23.
CrashReportUploadThread upload_thread(
- database.get(), options.url, options.rate_limit, options.upload_gzip);
+ database.get(), options.url, options.rate_limit);
upload_thread.Start();
PruneCrashReportThread prune_thread(database.get(),
« no previous file with comments | « third_party/crashpad/crashpad/handler/handler.gyp ('k') | third_party/crashpad/crashpad/minidump/minidump_context.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698