1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"
7 #include "android_webview/common/aw_version_info_values.h"
8 #include "base/files/file_path.h"
9 #include "base/lazy_instance.h"
10 #include "base/scoped_native_library.h"
11 #include "build/build_config.h"
12 #include "components/crash/app/breakpad_linux.h"
13 #include "components/crash/app/crash_reporter_client.h"
15 namespace android_webview
{
16 namespace crash_reporter
{
20 class AwCrashReporterClient
: public ::crash_reporter::CrashReporterClient
{
22 AwCrashReporterClient() {}
24 // crash_reporter::CrashReporterClient implementation.
25 bool IsRunningUnattended() override
{ return false; }
26 bool GetCollectStatsConsent() override
{ return false; }
28 void GetProductNameAndVersion(const char** product_name
,
29 const char** version
) override
{
30 *product_name
= "WebView";
31 *version
= PRODUCT_VERSION
;
33 // Microdumps are always enabled in WebView builds, conversely to what happens
34 // in the case of the other Chrome for Android builds (where they are enabled
35 // only when NO_UNWIND_TABLES == 1).
36 bool ShouldEnableBreakpadMicrodumps() override
{ return true; }
39 DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient
);
42 base::LazyInstance
<AwCrashReporterClient
>::Leaky g_crash_reporter_client
=
43 LAZY_INSTANCE_INITIALIZER
;
45 bool g_enabled
= false;
47 #if defined(ARCH_CPU_X86_FAMILY)
48 bool SafeToUseSignalHandler() {
49 // On X86/64 there are binary translators that handle SIGSEGV in userspace and
50 // may get chained after our handler - see http://crbug.com/477444
51 // We attempt to detect this to work out when it's safe to install breakpad.
52 // If anything doesn't seem right we assume it's not safe.
54 // type and mangled name of android::NativeBridgeInitialized
55 typedef bool (*InitializedFunc
)();
56 const char kInitializedSymbol
[] = "_ZN7android23NativeBridgeInitializedEv";
57 // type and mangled name of android::NativeBridgeGetVersion
58 typedef uint32_t (*VersionFunc
)();
59 const char kVersionSymbol
[] = "_ZN7android22NativeBridgeGetVersionEv";
61 base::ScopedNativeLibrary
lib_native_bridge(
62 base::FilePath("libnativebridge.so"));
63 if (!lib_native_bridge
.is_valid()) {
64 DLOG(WARNING
) << "Couldn't load libnativebridge";
68 InitializedFunc NativeBridgeInitialized
= reinterpret_cast<InitializedFunc
>(
69 lib_native_bridge
.GetFunctionPointer(kInitializedSymbol
));
70 if (NativeBridgeInitialized
== nullptr) {
71 DLOG(WARNING
) << "Couldn't tell if native bridge initialized";
74 if (!NativeBridgeInitialized()) {
75 // Native process, safe to use breakpad.
79 VersionFunc NativeBridgeGetVersion
= reinterpret_cast<VersionFunc
>(
80 lib_native_bridge
.GetFunctionPointer(kVersionSymbol
));
81 if (NativeBridgeGetVersion
== nullptr) {
82 DLOG(WARNING
) << "Couldn't get native bridge version";
85 uint32_t version
= NativeBridgeGetVersion();
87 // Native bridge at least version 2, safe to use breakpad.
90 DLOG(WARNING
) << "Native bridge ver=" << version
<< "; too low";
98 void EnableMicrodumpCrashReporter() {
100 NOTREACHED() << "EnableMicrodumpCrashReporter called more than once";
104 #if defined(ARCH_CPU_X86_FAMILY)
105 if (!SafeToUseSignalHandler()) {
106 LOG(WARNING
) << "Can't use breakpad to handle WebView crashes";
111 ::crash_reporter::SetCrashReporterClient(g_crash_reporter_client
.Pointer());
113 // |process_type| is not really relevant here, as long as it not empty.
114 breakpad::InitNonBrowserCrashReporterForAndroid("webview" /* process_type */);
118 } // namespace crash_reporter
119 } // namespace android_webview