| Index: third_party/crashpad/crashpad/client/crashpad_client_win.cc
|
| diff --git a/third_party/crashpad/crashpad/client/crashpad_client_win.cc b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
|
| index 78c1ed0d20526e870ed94debf6228edc5dc7cdb1..becfc01907cee73ab0763bec6e4009478aa6ee1d 100644
|
| --- a/third_party/crashpad/crashpad/client/crashpad_client_win.cc
|
| +++ b/third_party/crashpad/crashpad/client/crashpad_client_win.cc
|
| @@ -15,6 +15,7 @@
|
| #include "client/crashpad_client.h"
|
|
|
| #include <windows.h>
|
| +#include <signal.h>
|
| #include <stdint.h>
|
| #include <string.h>
|
|
|
| @@ -31,6 +32,7 @@
|
| #include "util/file/file_io.h"
|
| #include "util/misc/random_string.h"
|
| #include "util/win/address_types.h"
|
| +#include "util/win/capture_context.h"
|
| #include "util/win/command_line.h"
|
| #include "util/win/critical_section_with_debug_info.h"
|
| #include "util/win/get_function.h"
|
| @@ -108,13 +110,12 @@ StartupState BlockUntilHandlerStartedOrFailed() {
|
| }
|
|
|
| #if defined(ADDRESS_SANITIZER)
|
| -extern "C" LONG
|
| -__asan_unhandled_exception_filter(EXCEPTION_POINTERS* info);
|
| +extern "C" LONG __asan_unhandled_exception_filter(EXCEPTION_POINTERS* info);
|
| #endif
|
|
|
| LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
| - // In ASan builds, delegate to the ASan exception filter.
|
| #if defined(ADDRESS_SANITIZER)
|
| + // In ASan builds, delegate to the ASan exception filter.
|
| LONG status = __asan_unhandled_exception_filter(exception_pointers);
|
| if (status != EXCEPTION_CONTINUE_SEARCH)
|
| return status;
|
| @@ -175,6 +176,28 @@ LONG WINAPI UnhandledExceptionHandler(EXCEPTION_POINTERS* exception_pointers) {
|
| return EXCEPTION_CONTINUE_SEARCH;
|
| }
|
|
|
| +void HandleAbortSignal(int signum) {
|
| + DCHECK_EQ(signum, SIGABRT);
|
| +
|
| + CONTEXT context;
|
| + CaptureContext(&context);
|
| +
|
| + EXCEPTION_RECORD record = {};
|
| + record.ExceptionCode = STATUS_FATAL_APP_EXIT;
|
| + record.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
| +#if defined(ARCH_CPU_64_BITS)
|
| + record.ExceptionAddress = reinterpret_cast<void*>(context.Rip);
|
| +#else
|
| + record.ExceptionAddress = reinterpret_cast<void*>(context.Eip);
|
| +#endif // ARCH_CPU_64_BITS
|
| +
|
| + EXCEPTION_POINTERS exception_pointers;
|
| + exception_pointers.ContextRecord = &context;
|
| + exception_pointers.ExceptionRecord = &record;
|
| +
|
| + UnhandledExceptionHandler(&exception_pointers);
|
| +}
|
| +
|
| std::wstring FormatArgumentString(const std::string& name,
|
| const std::wstring& value) {
|
| return std::wstring(L"--") + base::UTF8ToUTF16(name) + L"=" + value;
|
| @@ -512,6 +535,32 @@ void CommonInProcessInitialization() {
|
| g_non_crash_dump_lock = new base::Lock();
|
| }
|
|
|
| +void RegisterHandlers() {
|
| + SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
| +
|
| + // The Windows CRT's signal.h lists:
|
| + // - SIGINT
|
| + // - SIGILL
|
| + // - SIGFPE
|
| + // - SIGSEGV
|
| + // - SIGTERM
|
| + // - SIGBREAK
|
| + // - SIGABRT
|
| + // SIGILL and SIGTERM are documented as not being generated. SIGBREAK and
|
| + // SIGINT are for Ctrl-Break and Ctrl-C, and aren't something for which
|
| + // capturing a dump is warranted. SIGFPE and SIGSEGV are captured as regular
|
| + // exceptions through the unhandled exception filter. This leaves SIGABRT. In
|
| + // the standard CRT, abort() is implemented as a synchronous call to the
|
| + // SIGABRT signal handler if installed, but after doing so, the unhandled
|
| + // exception filter is not triggered (it instead __fastfail()s). So, register
|
| + // to handle SIGABRT to catch abort() calls, as client code might use this and
|
| + // expect it to cause a crash dump. This will only work when the abort()
|
| + // that's called in client code is the same (or has the same behavior) as the
|
| + // one in use here.
|
| + void (*rv)(int) = signal(SIGABRT, HandleAbortSignal);
|
| + DCHECK_NE(rv, SIG_ERR);
|
| +}
|
| +
|
| } // namespace
|
|
|
| CrashpadClient::CrashpadClient() : ipc_pipe_(), handler_start_thread_() {}
|
| @@ -548,7 +597,7 @@ bool CrashpadClient::StartHandler(
|
|
|
| CommonInProcessInitialization();
|
|
|
| - SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
| + RegisterHandlers();
|
|
|
| auto data = new BackgroundHandlerStartThreadData(handler,
|
| database,
|
| @@ -621,7 +670,8 @@ bool CrashpadClient::SetHandlerIPCPipe(const std::wstring& ipc_pipe) {
|
| }
|
|
|
| SetHandlerStartupState(StartupState::kSucceeded);
|
| - SetUnhandledExceptionFilter(&UnhandledExceptionHandler);
|
| +
|
| + RegisterHandlers();
|
|
|
| // The server returns these already duplicated to be valid in this process.
|
| g_signal_exception =
|
|
|