summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/apk/java/proguard.flags5
-rw-r--r--android_webview/crash_reporter/aw_microdump_crash_reporter.cc20
-rw-r--r--android_webview/crash_reporter/aw_microdump_crash_reporter.h2
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwDebug.java43
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java33
-rw-r--r--android_webview/native/android_webview_jni_registrar.cc2
-rw-r--r--android_webview/native/aw_debug.cc42
-rw-r--r--android_webview/native/aw_debug.h21
-rw-r--r--android_webview/native/webview_native.gyp3
-rw-r--r--components/crash/content/app/breakpad_linux.cc27
10 files changed, 195 insertions, 3 deletions
diff --git a/android_webview/apk/java/proguard.flags b/android_webview/apk/java/proguard.flags
index 8dbce53..d8f80cc 100644
--- a/android_webview/apk/java/proguard.flags
+++ b/android_webview/apk/java/proguard.flags
@@ -75,6 +75,11 @@
public void setSmartClipResultHandler(android.os.Handler);
}
+# AwDebug is accessed by reflection.
+-keep class org.chromium.android_webview.AwDebug {
+ public static boolean dumpWithoutCrashing(...);
+}
+
# Ignore notes and warnings about the support library, which uses reflection and
# may reference classes no longer in the SDK.
-dontnote android.support.**
diff --git a/android_webview/crash_reporter/aw_microdump_crash_reporter.cc b/android_webview/crash_reporter/aw_microdump_crash_reporter.cc
index ce94174..165c4b3 100644
--- a/android_webview/crash_reporter/aw_microdump_crash_reporter.cc
+++ b/android_webview/crash_reporter/aw_microdump_crash_reporter.cc
@@ -5,9 +5,11 @@
#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"
#include "android_webview/common/aw_version_info_values.h"
+#include "base/debug/dump_without_crashing.h"
#include "base/files/file_path.h"
#include "base/lazy_instance.h"
#include "base/scoped_native_library.h"
+#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/app/crash_reporter_client.h"
@@ -19,7 +21,7 @@ namespace {
class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
public:
- AwCrashReporterClient() {}
+ AwCrashReporterClient() : dump_fd_(-1) {}
// crash_reporter::CrashReporterClient implementation.
bool IsRunningUnattended() override { return false; }
@@ -35,7 +37,19 @@ class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
// only when NO_UNWIND_TABLES == 1).
bool ShouldEnableBreakpadMicrodumps() override { return true; }
+ int GetAndroidMinidumpDescriptor() override { return dump_fd_; }
+
+ bool DumpWithoutCrashingToFd(int fd) {
+ base::AutoLock lock(dump_lock_);
+ dump_fd_ = fd;
+ base::debug::DumpWithoutCrashing();
+ dump_fd_ = -1;
+ return true;
+ }
+
private:
+ int dump_fd_;
+ base::Lock dump_lock_;
DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient);
};
@@ -120,5 +134,9 @@ void AddGpuFingerprintToMicrodumpCrashHandler(
breakpad::AddGpuFingerprintToMicrodumpCrashHandler(gpu_fingerprint);
}
+bool DumpWithoutCrashingToFd(int fd) {
+ return g_crash_reporter_client.Pointer()->DumpWithoutCrashingToFd(fd);
+}
+
} // namespace crash_reporter
} // namespace android_webview
diff --git a/android_webview/crash_reporter/aw_microdump_crash_reporter.h b/android_webview/crash_reporter/aw_microdump_crash_reporter.h
index 5fcda99..067363f 100644
--- a/android_webview/crash_reporter/aw_microdump_crash_reporter.h
+++ b/android_webview/crash_reporter/aw_microdump_crash_reporter.h
@@ -13,7 +13,7 @@ namespace crash_reporter {
void EnableMicrodumpCrashReporter();
void AddGpuFingerprintToMicrodumpCrashHandler(
const std::string& gpu_fingerprint);
-
+bool DumpWithoutCrashingToFd(int fd);
} // namespace crash_reporter
} // namespace android_webview
diff --git a/android_webview/java/src/org/chromium/android_webview/AwDebug.java b/android_webview/java/src/org/chromium/android_webview/AwDebug.java
new file mode 100644
index 0000000..72b125a
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwDebug.java
@@ -0,0 +1,43 @@
+// Copyright 2015 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.
+
+package org.chromium.android_webview;
+
+import org.chromium.base.annotations.JNINamespace;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Provides Android WebView debugging entrypoints.
+ *
+ * Methods in this class can be called from any thread, including threads created by
+ * the client of WebView.
+ */
+@JNINamespace("android_webview")
+public class AwDebug {
+ /**
+ * Dump webview state (predominantly a minidump for all threads,
+ * but including other information) to the file descriptor fd.
+ *
+ * It is expected that this method is found by reflection, as it
+ * is not currently exposed by the android framework, and thus it
+ * needs to be protected from the unwanted attention of ProGuard.
+ *
+ * The File argument must refer to a pre-existing file, which must
+ * be able to be re-opened for reading and writing via its
+ * canonical path. The file will be truncated upon re-opening.
+ */
+ public static boolean dumpWithoutCrashing(File dumpFile) {
+ String dumpPath;
+ try {
+ dumpPath = dumpFile.getCanonicalPath();
+ } catch (IOException e) {
+ return false;
+ }
+ return nativeDumpWithoutCrashing(dumpPath);
+ }
+
+ private static native boolean nativeDumpWithoutCrashing(String dumpPath);
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java
new file mode 100644
index 0000000..33bebb6
--- /dev/null
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwDebugTest.java
@@ -0,0 +1,33 @@
+// Copyright 2012 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.
+
+package org.chromium.android_webview.test;
+
+import android.os.Build;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.chromium.android_webview.AwDebug;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.MinAndroidSdkLevel;
+
+import java.io.File;
+
+/**
+ * A test suite for AwDebug class.
+ */
+@MinAndroidSdkLevel(Build.VERSION_CODES.KITKAT)
+public class AwDebugTest extends AwTestBase {
+ @SmallTest
+ @Feature({"AndroidWebView", "Debug"})
+ public void testDump() throws Throwable {
+ File f = File.createTempFile("dump", ".dmp");
+ try {
+ assertTrue(AwDebug.dumpWithoutCrashing(f));
+ assertTrue(f.canRead());
+ assertTrue(f.length() != 0);
+ } finally {
+ assertTrue(f.delete());
+ }
+ }
+}
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index add2d2c..275e29b 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -11,6 +11,7 @@
#include "android_webview/native/aw_contents_client_bridge.h"
#include "android_webview/native/aw_contents_io_thread_client_impl.h"
#include "android_webview/native/aw_contents_statics.h"
+#include "android_webview/native/aw_debug.h"
#include "android_webview/native/aw_dev_tools_server.h"
#include "android_webview/native/aw_form_database.h"
#include "android_webview/native/aw_http_auth_handler.h"
@@ -42,6 +43,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
{ "AwContentsClientBridge", RegisterAwContentsClientBridge },
{ "AwContentsIoThreadClientImpl", RegisterAwContentsIoThreadClientImpl },
{ "AwContentsStatics", RegisterAwContentsStatics },
+ { "AwDebug", RegisterAwDebug },
{ "AwDevToolsServer", RegisterAwDevToolsServer },
{ "AwFormDatabase", RegisterAwFormDatabase },
{ "AwPicture", RegisterAwPicture },
diff --git a/android_webview/native/aw_debug.cc b/android_webview/native/aw_debug.cc
new file mode 100644
index 0000000..fcfb50b
--- /dev/null
+++ b/android_webview/native/aw_debug.cc
@@ -0,0 +1,42 @@
+// Copyright 2015 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 "android_webview/native/aw_debug.h"
+
+#include "android_webview/crash_reporter/aw_microdump_crash_reporter.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/debug/dump_without_crashing.h"
+#include "base/files/file.h"
+#include "base/files/file_path.h"
+#include "base/threading/thread_restrictions.h"
+#include "jni/AwDebug_jni.h"
+
+using base::android::ConvertJavaStringToUTF16;
+using base::android::ConvertUTF8ToJavaString;
+using base::android::ScopedJavaLocalRef;
+
+namespace android_webview {
+
+static jboolean DumpWithoutCrashing(JNIEnv* env,
+ const JavaParamRef<jclass>& clazz,
+ const JavaParamRef<jstring>& dump_path) {
+ // This may be called from any thread, and we might be in a state
+ // where it is impossible to post tasks, so we have to be prepared
+ // to do IO from this thread.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ base::File target(base::FilePath(ConvertJavaStringToUTF8(env, dump_path)),
+ base::File::FLAG_OPEN_TRUNCATED | base::File::FLAG_READ |
+ base::File::FLAG_WRITE);
+ if (!target.IsValid())
+ return false;
+ // breakpad_linux::HandleCrashDump will close this fd once it is done.
+ return crash_reporter::DumpWithoutCrashingToFd(target.TakePlatformFile());
+}
+
+bool RegisterAwDebug(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android_webview
diff --git a/android_webview/native/aw_debug.h b/android_webview/native/aw_debug.h
new file mode 100644
index 0000000..c1eadaa
--- /dev/null
+++ b/android_webview/native/aw_debug.h
@@ -0,0 +1,21 @@
+// Copyright 2015 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.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_
+
+#include <jni.h>
+
+#include "base/android/jni_weak_ref.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/web_contents_observer.h"
+
+namespace android_webview {
+
+bool RegisterAwDebug(JNIEnv* env);
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_AW_DEBUG_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 33d5401..9cdb1eb 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -51,6 +51,8 @@
'aw_contents_io_thread_client_impl.h',
'aw_contents_statics.cc',
'aw_contents_statics.h',
+ 'aw_debug.cc',
+ 'aw_debug.h',
'aw_dev_tools_server.cc',
'aw_dev_tools_server.h',
'aw_form_database.cc',
@@ -132,6 +134,7 @@
'../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java',
'../java/src/org/chromium/android_webview/AwContentsStatics.java',
'../java/src/org/chromium/android_webview/AwCookieManager.java',
+ '../java/src/org/chromium/android_webview/AwDebug.java',
'../java/src/org/chromium/android_webview/AwDevToolsServer.java',
'../java/src/org/chromium/android_webview/AwFormDatabase.java',
'../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
diff --git a/components/crash/content/app/breakpad_linux.cc b/components/crash/content/app/breakpad_linux.cc
index d92953e..f93dda7 100644
--- a/components/crash/content/app/breakpad_linux.cc
+++ b/components/crash/content/app/breakpad_linux.cc
@@ -603,7 +603,7 @@ bool CrashDone(const MinidumpDescriptor& minidump,
return false;
}
- DCHECK(!minidump.IsFD());
+ DCHECK(!(upload && minidump.IsFD()));
BreakpadInfo info = {0};
info.filename = minidump.path();
@@ -812,6 +812,19 @@ void EnableNonBrowserCrashDumping(const std::string& process_type,
nullptr, CrashDoneInProcessNoUpload, nullptr, true, -1);
}
+void GenerateMinidumpOnDemandForAndroid() {
+ // TODO(tobiasjs) this still calls FinalizeCrashDoneAndroid, which
+ // generates logspam. Consider refactoring.
+ int dump_fd = GetCrashReporterClient()->GetAndroidMinidumpDescriptor();
+ if (dump_fd >= 0) {
+ MinidumpDescriptor minidump_descriptor(dump_fd);
+ minidump_descriptor.set_size_limit(-1);
+ ExceptionHandler(minidump_descriptor, nullptr, CrashDoneNoUpload, nullptr,
+ false, -1)
+ .WriteMinidump();
+ }
+}
+
void MicrodumpInfo::SetGpuFingerprint(const std::string& gpu_fingerprint) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!microdump_gpu_fingerprint_);
@@ -860,6 +873,18 @@ void MicrodumpInfo::Initialize(const std::string& process_type,
reinterpret_cast<void*>(is_browser_process),
true, // Install handlers.
-1); // Server file descriptor. -1 for in-process.
+
+ if (process_type == "webview") {
+ // We do not use |DumpProcess()| for handling programatically
+ // generated dumps for WebView because we only know the file
+ // descriptor to which we are dumping at the time of the call to
+ // |DumpWithoutCrashing()|. Therefore we need to construct the
+ // |MinidumpDescriptor| and |ExceptionHandler| instances as
+ // needed, instead of setting up |g_breakpad| at initialization
+ // time.
+ base::debug::SetDumpWithoutCrashingFunction(
+ &GenerateMinidumpOnDemandForAndroid);
+ }
}
#else