Chromium Code Reviews| Index: components/crash/content/app/fallback_crash_handling_win.cc |
| diff --git a/components/crash/content/app/fallback_crash_handling_win.cc b/components/crash/content/app/fallback_crash_handling_win.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..b9a7cc0c4d591ddb9ae10c37f28df113c2490133 |
| --- /dev/null |
| +++ b/components/crash/content/app/fallback_crash_handling_win.cc |
| @@ -0,0 +1,100 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/crash/content/app/fallback_crash_handling_win.h" |
| + |
| +#include <memory> |
| + |
| +#include "base/base_switches.h" |
| +#include "base/command_line.h" |
| +#include "base/logging.h" |
| +#include "components/crash/content/app/crash_switches.h" |
| +#include "components/crash/content/app/fallback_crash_handler_launcher_win.h" |
| +#include "components/crash/content/app/fallback_crash_handler_win.h" |
| + |
| +namespace crash_reporter { |
| + |
| +namespace switches { |
| +const char kFallbackCrashHandler[] = "fallback-handler"; |
| +} |
| + |
| +const uint32_t kFallbackCrashTerminationCode = 0xFFFF8001; |
| + |
| +namespace { |
| + |
| +std::unique_ptr<FallbackCrashHandlerLauncher> g_fallback_crash_handler_launcher; |
| + |
| +LONG WINAPI FallbackUnhandledExceptionFilter(EXCEPTION_POINTERS* exc_ptrs) { |
| + if (!g_fallback_crash_handler_launcher) |
| + return EXCEPTION_CONTINUE_SEARCH; |
| + |
| + return g_fallback_crash_handler_launcher->LaunchAndWaitForHandler(exc_ptrs); |
| +} |
| + |
| +} // namespace |
| + |
| +bool SetupFallbackCrashHandling(const base::CommandLine& command_line) { |
| + DCHECK(!g_fallback_crash_handler_launcher); |
| + |
| + // Run the same program. |
| + base::CommandLine base_command_line(command_line.GetProgram()); |
| + base_command_line.AppendSwitchASCII("type", switches::kFallbackCrashHandler); |
| + |
| + // This is to support testing under gtest. |
| + if (command_line.HasSwitch(::switches::kTestChildProcess)) { |
| + base_command_line.AppendSwitchASCII( |
| + ::switches::kTestChildProcess, |
| + command_line.GetSwitchValueASCII(::switches::kTestChildProcess)); |
| + } |
| + |
| + // Get the database path. |
| + base::FilePath database_path = command_line.GetSwitchValuePath("database"); |
| + if (database_path.empty()) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + |
| + std::unique_ptr<FallbackCrashHandlerLauncher> fallback_launcher( |
| + new FallbackCrashHandlerLauncher()); |
| + |
| + if (!fallback_launcher->Initialize(base_command_line, database_path)) { |
| + NOTREACHED(); |
| + return false; |
| + } |
| + |
| + // Success, pass ownership to the global. |
| + g_fallback_crash_handler_launcher = std::move(fallback_launcher); |
| + |
| + SetUnhandledExceptionFilter(&FallbackUnhandledExceptionFilter); |
|
scottmg
2017/01/16 18:32:57
I have the feeling this won't do anything, due to
Sigurður Ásgeirsson
2017/01/16 18:52:44
I think you may be right - I haven't tested this i
|
| + |
| + return true; |
| +} |
| + |
| +int RunAsFallbackCrashHandler(const base::CommandLine& command_line, |
| + std::string product_name, |
| + std::string version, |
| + std::string channel_name) { |
| + FallbackCrashHandler fallback_handler; |
| + |
| + if (!fallback_handler.ParseCommandLine(command_line)) { |
| + // TODO(siggi): Figure out how to UMA from this process, if need be. |
| + return 1; |
| + } |
| + |
| + if (!fallback_handler.GenerateCrashDump( |
| + product_name, version, channel_name, |
| + crash_reporter::switches::kCrashpadHandler)) { |
| + // TODO(siggi): Figure out how to UMA from this process, if need be. |
| + return 2; |
| + } |
| + |
| + if (!fallback_handler.process().Terminate(kFallbackCrashTerminationCode, |
| + false)) { |
| + return 3; |
| + } |
| + |
| + return 0; |
| +} |
| + |
| +} // namespace crash_reporter |