summaryrefslogtreecommitdiff
path: root/chromium/components/crash
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-13 16:23:34 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-02-14 10:37:21 +0000
commit38a9a29f4f9436cace7f0e7abf9c586057df8a4e (patch)
treec4e8c458dc595bc0ddb435708fa2229edfd00bd4 /chromium/components/crash
parente684a3455bcc29a6e3e66a004e352dea4e1141e7 (diff)
downloadqtwebengine-chromium-38a9a29f4f9436cace7f0e7abf9c586057df8a4e.tar.gz
BASELINE: Update Chromium to 73.0.3683.37
Change-Id: I08c9af2948b645f671e5d933aca1f7a90ea372f2 Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/crash')
-rw-r--r--chromium/components/crash/android/BUILD.gn42
-rw-r--r--chromium/components/crash/android/DEPS3
-rw-r--r--chromium/components/crash/android/crashpad_main.cc25
-rw-r--r--chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java80
-rw-r--r--chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashpadMain.java26
-rw-r--r--chromium/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java75
-rw-r--r--chromium/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java147
-rw-r--r--chromium/components/crash/content/app/BUILD.gn20
-rw-r--r--chromium/components/crash/content/app/DEPS1
-rw-r--r--chromium/components/crash/content/app/breakpad_win.cc4
-rw-r--r--chromium/components/crash/content/app/crash_reporter_client.cc10
-rw-r--r--chromium/components/crash/content/app/crash_reporter_client.h15
-rw-r--r--chromium/components/crash/content/app/crashpad.cc11
-rw-r--r--chromium/components/crash/content/app/crashpad.h14
-rw-r--r--chromium/components/crash/content/app/crashpad_linux.cc399
-rw-r--r--chromium/components/crash/content/app/crashpad_win.cc5
-rw-r--r--chromium/components/crash/content/browser/BUILD.gn14
-rw-r--r--chromium/components/crash/content/browser/child_exit_observer_android.cc30
-rw-r--r--chromium/components/crash/content/browser/child_exit_observer_android.h15
-rw-r--r--chromium/components/crash/content/browser/child_process_crash_observer_android.cc60
-rw-r--r--chromium/components/crash/content/browser/child_process_crash_observer_android.h18
-rw-r--r--chromium/components/crash/content/browser/crash_dump_manager_android.cc172
-rw-r--r--chromium/components/crash/content/browser/crash_dump_manager_android.h105
-rw-r--r--chromium/components/crash/content/browser/crash_dump_manager_android_unittest.cc160
-rw-r--r--chromium/components/crash/content/browser/crash_handler_host_linux.cc39
-rw-r--r--chromium/components/crash/content/browser/crash_handler_host_linux.h3
-rw-r--r--chromium/components/crash/content/browser/crash_metrics_reporter_android.cc36
-rw-r--r--chromium/components/crash/content/browser/crash_metrics_reporter_android.h5
-rw-r--r--chromium/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc30
-rwxr-xr-xchromium/components/crash/content/tools/generate_breakpad_symbols.py43
-rw-r--r--chromium/components/crash/core/browser/crashes_ui_util.cc4
-rw-r--r--chromium/components/crash/core/common/BUILD.gn5
-rw-r--r--chromium/components/crash/core/common/crash_key.h2
-rw-r--r--chromium/components/crash/core/common/crash_key_crashpad.cc2
-rw-r--r--chromium/components/crash/core/common/crash_key_unittest.cc5
-rw-r--r--chromium/components/crash/core/common/crash_keys.cc7
36 files changed, 698 insertions, 934 deletions
diff --git a/chromium/components/crash/android/BUILD.gn b/chromium/components/crash/android/BUILD.gn
index 05cc295fe4f..c61e6713ed9 100644
--- a/chromium/components/crash/android/BUILD.gn
+++ b/chromium/components/crash/android/BUILD.gn
@@ -6,7 +6,7 @@ import("//build/config/android/rules.gni")
_jni_sources = [
"java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java",
- "java/src/org/chromium/components/crash/browser/CrashDumpManager.java",
+ "java/src/org/chromium/components/crash/browser/PackagePaths.java",
"java/src/org/chromium/components/crash/CrashKeys.java",
]
@@ -41,18 +41,6 @@ source_set("crash_android") {
]
}
-android_library("javatests") {
- testonly = true
- deps = [
- ":java",
- "//base:base_java",
- "//base:base_java_test_support",
- "//third_party/android_support_test_runner:runner_java",
- "//third_party/junit",
- ]
- java_files = [ "javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java" ]
-}
-
source_set("unit_tests") {
testonly = true
sources = [
@@ -64,3 +52,31 @@ source_set("unit_tests") {
"//testing/gtest",
]
}
+
+_java_handler_jni_sources =
+ [ "java/src/org/chromium/components/crash/browser/CrashpadMain.java" ]
+
+generate_jni("java_handler_jni_headers") {
+ sources = _java_handler_jni_sources
+ jni_package = "crashpad"
+}
+
+android_library("handler_java") {
+ deps = [
+ "//base:base_java",
+ ]
+ java_files = _java_handler_jni_sources
+}
+
+static_library("crashpad_main") {
+ sources = [
+ "crashpad_main.cc",
+ ]
+
+ deps = [
+ ":java_handler_jni_headers",
+ "//base",
+ "//third_party/crashpad/crashpad/client",
+ "//third_party/crashpad/crashpad/handler",
+ ]
+}
diff --git a/chromium/components/crash/android/DEPS b/chromium/components/crash/android/DEPS
index 1129c7b690d..fb4880eab96 100644
--- a/chromium/components/crash/android/DEPS
+++ b/chromium/components/crash/android/DEPS
@@ -1,3 +1,4 @@
include_rules = [
"+jni",
-] \ No newline at end of file
+ "+third_party/crashpad",
+]
diff --git a/chromium/components/crash/android/crashpad_main.cc b/chromium/components/crash/android/crashpad_main.cc
new file mode 100644
index 00000000000..ce3d8888fb8
--- /dev/null
+++ b/chromium/components/crash/android/crashpad_main.cc
@@ -0,0 +1,25 @@
+// Copyright 2018 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 "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "jni/CrashpadMain_jni.h"
+#include "third_party/crashpad/crashpad/client/client_argv_handling.h"
+#include "third_party/crashpad/crashpad/handler/handler_main.h"
+
+namespace crashpad {
+
+static void JNI_CrashpadMain_CrashpadMain(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jobjectArray>& j_argv) {
+ std::vector<std::string> argv_strings;
+ base::android::AppendJavaStringArrayToStringVector(env, j_argv,
+ &argv_strings);
+
+ std::vector<const char*> argv;
+ StringVectorToCStringVector(argv_strings, &argv);
+ HandlerMain(argv.size() - 1, const_cast<char**>(argv.data()), nullptr);
+}
+
+} // namespace crashpad
diff --git a/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java b/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
deleted file mode 100644
index 495556181de..00000000000
--- a/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// 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.
-
-package org.chromium.components.crash.browser;
-
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-
-import java.io.File;
-
-/**
- * A Java-side bridge for continuing the upload processing for child process crash minidumps.
- */
-public class CrashDumpManager {
- private static final String TAG = "CrashDumpManager";
-
- /**
- * An interface for providing a callback that will try to upload a minidump. The callback should
- * be registered on, and will be run on, the UI thread.
- */
- public interface UploadMinidumpCallback { public void tryToUploadMinidump(File minidump); }
-
- /**
- * The globally registered callback for uploading minidumps, or null if no callback has been
- * registered yet.
- */
- private static UploadMinidumpCallback sCallback;
-
- /**
- * Registers a callback for uploading minidumps. May be called at most once, and only on the UI
- * thread.
- *
- * @param callback The callback to trigger when a new minidump is generated by a child process.
- */
- public static void registerUploadCallback(UploadMinidumpCallback callback) {
- ThreadUtils.assertOnUiThread();
- assert sCallback == null;
- sCallback = callback;
- }
-
- /**
- * Attempts to upload the specified child process minidump (or a no-op if no observer has been
- * registered).
- *
- * @param minidumpPath The file path for the generated minidump.
- */
- @CalledByNative
- public static void tryToUploadMinidump(String minidumpPath) {
- // The C++ code that calls into this method should be running on a background thread. It's
- // important to be off the UI thread for the file operations done below.
- ThreadUtils.assertOnBackgroundThread();
-
- if (minidumpPath == null) {
- Log.e(TAG, "Minidump path should be non-null! Bailing...");
- return;
- }
-
- final File minidump = new File(minidumpPath);
- if (!minidump.exists() || !minidump.isFile()) {
- Log.e(TAG,
- "Minidump path '" + minidumpPath
- + "' should describe a file that exists! Bailing...");
- return;
- }
-
- // The callback should only be accessed on the UI thread.
- ThreadUtils.postOnUiThread(new Runnable() {
- @Override
- public void run() {
- if (sCallback == null) {
- Log.w(TAG, "Ignoring crash observed before a callback was registered...");
- return;
- }
- sCallback.tryToUploadMinidump(minidump);
- }
- });
- }
-}
diff --git a/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashpadMain.java b/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashpadMain.java
new file mode 100644
index 00000000000..1add0b69c62
--- /dev/null
+++ b/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/CrashpadMain.java
@@ -0,0 +1,26 @@
+// Copyright 2018 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.components.crash.browser;
+
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.UsedByReflection;
+import org.chromium.base.library_loader.NativeLibraries;
+
+@JNINamespace("crashpad")
+final class CrashpadMain {
+ @UsedByReflection("crashpad_linux.cc")
+ public static void main(String[] argv) {
+ try {
+ for (String library : NativeLibraries.LIBRARIES) {
+ System.loadLibrary(library);
+ }
+ } catch (UnsatisfiedLinkError e) {
+ throw new RuntimeException(e);
+ }
+ nativeCrashpadMain(argv);
+ }
+
+ private static native void nativeCrashpadMain(String[] argv);
+}
diff --git a/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java b/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java
new file mode 100644
index 00000000000..9b621c4801b
--- /dev/null
+++ b/chromium/components/crash/android/java/src/org/chromium/components/crash/browser/PackagePaths.java
@@ -0,0 +1,75 @@
+// Copyright 2018 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.components.crash.browser;
+
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.text.TextUtils;
+
+import org.chromium.base.BuildInfo;
+import org.chromium.base.ContextUtils;
+import org.chromium.base.annotations.CalledByNative;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This class builds paths for the Chrome package.
+ */
+public abstract class PackagePaths {
+ private static final String TAG = "PackagePaths";
+
+ // Prevent instantiation.
+ private PackagePaths() {}
+
+ /**
+ * @ Build paths for the chrome/webview package for the purpose of loading CrashpadMain via
+ * /system/bin/app_process.
+ */
+ @CalledByNative
+ public static String[] makePackagePaths(String arch) {
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
+ return new String[] {"", ""};
+ }
+ try {
+ PackageManager pm = ContextUtils.getApplicationContext().getPackageManager();
+ PackageInfo pi = pm.getPackageInfo(
+ BuildInfo.getInstance().packageName, PackageManager.GET_SHARED_LIBRARY_FILES);
+
+ List<String> zipPaths = new ArrayList<>(10);
+ zipPaths.add(pi.applicationInfo.sourceDir);
+ if (pi.applicationInfo.splitSourceDirs != null) {
+ Collections.addAll(zipPaths, pi.applicationInfo.splitSourceDirs);
+ }
+
+ if (pi.applicationInfo.sharedLibraryFiles != null) {
+ Collections.addAll(zipPaths, pi.applicationInfo.sharedLibraryFiles);
+ }
+
+ List<String> libPaths = new ArrayList<>(10);
+ File parent = new File(pi.applicationInfo.nativeLibraryDir).getParentFile();
+ if (parent != null) {
+ libPaths.add(new File(parent, arch).getPath());
+ }
+ for (String zip : zipPaths) {
+ if (zip.endsWith(".apk")) {
+ libPaths.add(zip + "!/lib/" + arch);
+ }
+ }
+ libPaths.add(System.getProperty("java.library.path"));
+ libPaths.add(pi.applicationInfo.nativeLibraryDir);
+
+ return new String[] {TextUtils.join(File.pathSeparator, zipPaths),
+ TextUtils.join(File.pathSeparator, libPaths)};
+
+ } catch (NameNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/chromium/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java b/chromium/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
deleted file mode 100644
index cbcbaf17edf..00000000000
--- a/chromium/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// 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.
-
-package org.chromium.components.crash.browser;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.TestFileUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Unittests for {@link CrashDumpManager}.
- */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class CrashDumpManagerTest {
- File mTempDir;
-
- @Before
- public void setUp() throws Exception {
- ContextUtils.initApplicationContextForTests(InstrumentationRegistry.getInstrumentation()
- .getTargetContext()
- .getApplicationContext());
- mTempDir = ContextUtils.getApplicationContext().getCacheDir();
- assert mTempDir.exists();
- }
-
- @After
- public void tearDown() throws Exception {
- File[] files = mTempDir.listFiles();
- if (files == null) return;
-
- for (File file : files) {
- TestFileUtil.deleteFile(file);
- }
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_NoCallback() throws IOException {
- File minidump = new File(mTempDir, "mini.dmp");
- Assert.assertTrue(minidump.createNewFile());
-
- CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_NullMinidumpPath() {
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail("The callback should not be called when the minidump path is null.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(null);
- }
-
- // @SmallTest
- // @Feature({"Android-AppBase"})
- @Test
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_FileDoesntExist() {
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail(
- "The callback should not be called when the minidump file doesn't exist.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(
- mTempDir.getAbsolutePath() + "/some/file/that/doesnt/exist");
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_MinidumpPathIsDirectory() throws IOException {
- File directory = new File(mTempDir, "a_directory");
- Assert.assertTrue(directory.mkdir());
-
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File minidump) {
- Assert.fail(
- "The callback should not be called when the minidump path is not a file.");
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(directory.getAbsolutePath());
- }
-
- @Test
- @SmallTest
- @Feature({"Android-AppBase"})
- @DisabledTest // Flaky, crbug.com/725379.
- public void testUploadMinidump_MinidumpPathIsValid() throws IOException {
- final File minidump = new File(mTempDir, "mini.dmp");
- Assert.assertTrue(minidump.createNewFile());
-
- registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
- @Override
- public void tryToUploadMinidump(File actualMinidump) {
- Assert.assertEquals("Should call the callback with the correct filename.", minidump,
- actualMinidump);
- }
- });
-
- CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
- }
-
- /**
- * A convenience wrapper that registers the upload {@param callback}, running the registration
- * on the UI thread, as expected by the CrashDumpManager code.
- * @param callback The callback for uploading minidumps.
- */
- private static void registerUploadCallback(
- final CrashDumpManager.UploadMinidumpCallback callback) {
- ThreadUtils.runOnUiThreadBlocking(new Runnable() {
- @Override
- public void run() {
- CrashDumpManager.registerUploadCallback(callback);
- }
- });
- }
-}
diff --git a/chromium/components/crash/content/app/BUILD.gn b/chromium/components/crash/content/app/BUILD.gn
index 732ae72628f..5a13a51923a 100644
--- a/chromium/components/crash/content/app/BUILD.gn
+++ b/chromium/components/crash/content/app/BUILD.gn
@@ -36,17 +36,17 @@ static_library("app") {
sources += [ "crashpad.cc" ]
}
- if (is_android || is_linux) {
- # Want these files on both Linux and Android.
+ if (is_android || (is_linux && !is_chromeos)) {
set_sources_assignment_filter([])
+ sources += [ "crashpad_linux.cc" ]
+ }
+
+ if (is_linux) {
sources += [
"breakpad_linux.cc",
"breakpad_linux.h",
"breakpad_linux_impl.h",
]
- if (!is_chromeos) {
- sources += [ "crashpad_linux.cc" ]
- }
}
defines = [ "CRASH_IMPLEMENTATION" ]
@@ -61,11 +61,14 @@ static_library("app") {
if (is_mac || is_win || is_android || (is_linux && !is_chromeos)) {
deps += [
"//third_party/crashpad/crashpad/client",
- "//third_party/crashpad/crashpad/snapshot:snapshot_api",
"//third_party/crashpad/crashpad/util",
]
}
+ if (is_android) {
+ deps += [ "//components/crash/android:jni_headers" ]
+ }
+
if (is_android || is_linux) {
deps += [
"//base:base_static",
@@ -73,9 +76,12 @@ static_library("app") {
"//content/public/common:content_descriptors",
"//content/public/common:result_codes",
"//sandbox",
- "//third_party/breakpad:client",
"//third_party/crashpad/crashpad/snapshot",
]
+
+ if (is_linux) {
+ deps += [ "//third_party/breakpad:client" ]
+ }
}
if (is_win) {
diff --git a/chromium/components/crash/content/app/DEPS b/chromium/components/crash/content/app/DEPS
index 019cf70eee9..63e5b6fcabf 100644
--- a/chromium/components/crash/content/app/DEPS
+++ b/chromium/components/crash/content/app/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/gwp_asan/crash_handler/crash_handler.h",
"+content/public/common/content_descriptors.h",
"+content/public/common/result_codes.h",
+ "+jni",
"+third_party/crashpad",
"+third_party/lss/linux_syscall_support.h",
]
diff --git a/chromium/components/crash/content/app/breakpad_win.cc b/chromium/components/crash/content/app/breakpad_win.cc
index dfb140d253e..dec9daf1fdb 100644
--- a/chromium/components/crash/content/app/breakpad_win.cc
+++ b/chromium/components/crash/content/app/breakpad_win.cc
@@ -24,9 +24,9 @@
#include "base/debug/dump_without_crashing.h"
#include "base/environment.h"
#include "base/files/file_path.h"
-#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
+#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -210,7 +210,7 @@ std::wstring GetProfileType() {
{ PT_ROAMING, L"roaming" },
{ PT_TEMPORARY, L"temporary" },
};
- for (size_t i = 0; i < arraysize(kBitNames); ++i) {
+ for (size_t i = 0; i < base::size(kBitNames); ++i) {
const DWORD this_bit = kBitNames[i].bit;
if ((profile_bits & this_bit) != 0) {
profile_type.append(kBitNames[i].name);
diff --git a/chromium/components/crash/content/app/crash_reporter_client.cc b/chromium/components/crash/content/app/crash_reporter_client.cc
index f69c6c3ff26..b3b09cee8d6 100644
--- a/chromium/components/crash/content/app/crash_reporter_client.cc
+++ b/chromium/components/crash/content/app/crash_reporter_client.cc
@@ -36,7 +36,7 @@ CrashReporterClient* GetCrashReporterClient() {
CrashReporterClient::CrashReporterClient() {}
CrashReporterClient::~CrashReporterClient() {}
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
void CrashReporterClient::SetCrashReporterClientIdFromGUID(
const std::string& client_guid) {}
#endif
@@ -148,6 +148,14 @@ bool CrashReporterClient::ReportingIsEnforcedByPolicy(bool* breakpad_enabled) {
}
#if defined(OS_ANDROID)
+unsigned int CrashReporterClient::GetCrashDumpPercentageForWebView() {
+ return 100;
+}
+
+bool CrashReporterClient::GetBrowserProcessType(std::string* ptype) {
+ return false;
+}
+
int CrashReporterClient::GetAndroidMinidumpDescriptor() {
return 0;
}
diff --git a/chromium/components/crash/content/app/crash_reporter_client.h b/chromium/components/crash/content/app/crash_reporter_client.h
index 485c2c8bf63..caebf67a7e0 100644
--- a/chromium/components/crash/content/app/crash_reporter_client.h
+++ b/chromium/components/crash/content/app/crash_reporter_client.h
@@ -36,14 +36,14 @@ class CrashReporterClient {
CrashReporterClient();
virtual ~CrashReporterClient();
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
// Sets the crash reporting client ID, a unique identifier for the client
// that is sending crash reports. After it is set, it should not be changed.
// |client_guid| may either be a full GUID or a GUID that was already stripped
// from its dashes.
//
- // On Mac OS X and Windows, this is the responsibility of Crashpad, and can
- // not be set directly by the client.
+ // On macOS, Windows, and Android this is the responsibility of Crashpad, and
+ // can not be set directly by the client.
virtual void SetCrashReporterClientIdFromGUID(const std::string& client_guid);
#endif
@@ -153,6 +153,15 @@ class CrashReporterClient {
virtual bool ReportingIsEnforcedByPolicy(bool* breakpad_enabled);
#if defined(OS_ANDROID)
+ // Used by WebView to sample crashes without generating the unwanted dumps. If
+ // the returned value is less than 100, crash dumping will be sampled to that
+ // percentage.
+ virtual unsigned int GetCrashDumpPercentageForWebView();
+
+ // Returns true if |ptype| was set to a value to override the default `ptype`
+ // annotation used for the browser process.
+ virtual bool GetBrowserProcessType(std::string* ptype);
+
// Returns the descriptor key of the android minidump global descriptor.
virtual int GetAndroidMinidumpDescriptor();
diff --git a/chromium/components/crash/content/app/crashpad.cc b/chromium/components/crash/content/app/crashpad.cc
index 5cf5818c879..a04a4d84300 100644
--- a/chromium/components/crash/content/app/crashpad.cc
+++ b/chromium/components/crash/content/app/crashpad.cc
@@ -114,7 +114,8 @@ void InitializeCrashpadImpl(bool initial_client,
// "relauncher" is hard-coded because it's a Chrome --type, but this
// component can't see Chrome's switches. This is only used for argument
// sanitization.
- DCHECK(browser_process || process_type == "relauncher");
+ DCHECK(browser_process || process_type == "relauncher" ||
+ process_type == "app_shim");
#elif defined(OS_WIN)
// "Chrome Installer" is the name historically used for installer binaries
// as processed by the backend.
@@ -264,9 +265,17 @@ bool GetUploadsEnabled() {
return false;
}
+#if !defined(OS_ANDROID)
void DumpWithoutCrashing() {
CRASHPAD_SIMULATE_CRASH();
}
+#endif
+
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+void CrashWithoutDumping(const std::string& message) {
+ crashpad::CrashpadClient::CrashWithoutDump(message);
+}
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
void GetReports(std::vector<Report>* reports) {
#if defined(OS_WIN)
diff --git a/chromium/components/crash/content/app/crashpad.h b/chromium/components/crash/content/app/crashpad.h
index 3c92c1631dd..c16f6b87b38 100644
--- a/chromium/components/crash/content/app/crashpad.h
+++ b/chromium/components/crash/content/app/crashpad.h
@@ -130,6 +130,12 @@ void RequestSingleCrashUpload(const std::string& local_id);
void DumpWithoutCrashing();
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+// Logs message and immediately crashes the current process without triggering a
+// crash dump.
+void CrashWithoutDumping(const std::string& message);
+#endif // defined(OS_LINUX) || defined(OS_ANDROID)
+
// Returns the Crashpad database path, only valid in the browser.
base::FilePath GetCrashpadDatabasePath();
@@ -148,6 +154,14 @@ base::FilePath::StringType::const_pointer GetCrashpadDatabasePathImpl();
void DumpProcessWithoutCrashing(task_t task_port);
#endif
+#if defined(OS_ANDROID)
+// This is used by WebView to generate a dump on behalf of the embedding app.
+// This function can only be called from the browser process. Returns `true` on
+// success.
+class CrashReporterClient;
+bool DumpWithoutCrashingForClient(CrashReporterClient* client);
+#endif // OS_ANDROID
+
namespace internal {
#if defined(OS_WIN)
diff --git a/chromium/components/crash/content/app/crashpad_linux.cc b/chromium/components/crash/content/app/crashpad_linux.cc
index 69febb07a3b..6244bfef583 100644
--- a/chromium/components/crash/content/app/crashpad_linux.cc
+++ b/chromium/components/crash/content/app/crashpad_linux.cc
@@ -20,39 +20,70 @@
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/global_descriptors.h"
+#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "components/crash/content/app/crash_reporter_client.h"
#include "content/public/common/content_descriptors.h"
#include "sandbox/linux/services/syscall_wrappers.h"
#include "third_party/crashpad/crashpad/client/annotation.h"
+#include "third_party/crashpad/crashpad/client/client_argv_handling.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
+#include "third_party/crashpad/crashpad/client/simulate_crash_linux.h"
#include "third_party/crashpad/crashpad/snapshot/sanitized/sanitization_information.h"
#include "third_party/crashpad/crashpad/util/linux/exception_handler_client.h"
#include "third_party/crashpad/crashpad/util/linux/exception_information.h"
+#include "third_party/crashpad/crashpad/util/linux/scoped_pr_set_dumpable.h"
#include "third_party/crashpad/crashpad/util/misc/from_pointer_cast.h"
#include "third_party/crashpad/crashpad/util/posix/signals.h"
#if defined(OS_ANDROID)
#include "base/android/build_info.h"
#include "base/android/java_exception_reporter.h"
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/android/path_utils.h"
+#include "jni/PackagePaths_jni.h"
#endif // OS_ANDROID
namespace crashpad {
namespace {
-bool SetSanitizationInfo(SanitizationInformation* info) {
+bool SetSanitizationInfo(crash_reporter::CrashReporterClient* client,
+ SanitizationInformation* info) {
const char* const* whitelist = nullptr;
void* target_module = nullptr;
bool sanitize_stacks = false;
- crash_reporter::GetCrashReporterClient()->GetSanitizationInformation(
- &whitelist, &target_module, &sanitize_stacks);
+ client->GetSanitizationInformation(&whitelist, &target_module,
+ &sanitize_stacks);
info->annotations_whitelist_address = FromPointerCast<VMAddress>(whitelist);
info->target_module_address = FromPointerCast<VMAddress>(target_module);
info->sanitize_stacks = sanitize_stacks;
return whitelist != nullptr || target_module != nullptr || sanitize_stacks;
}
+void SetExceptionInformation(siginfo_t* siginfo,
+ ucontext_t* context,
+ ExceptionInformation* info) {
+ info->siginfo_address =
+ FromPointerCast<decltype(info->siginfo_address)>(siginfo);
+ info->context_address =
+ FromPointerCast<decltype(info->context_address)>(context);
+ info->thread_id = sandbox::sys_gettid();
+}
+
+void SetClientInformation(ExceptionInformation* exception,
+ SanitizationInformation* sanitization,
+ ClientInformation* info) {
+ info->exception_information_address =
+ FromPointerCast<decltype(info->exception_information_address)>(exception);
+
+ info->sanitization_information_address =
+ FromPointerCast<decltype(info->sanitization_information_address)>(
+ sanitization);
+}
+
// A signal handler for non-browser processes in the sandbox.
// Sends a message to a crashpad::CrashHandlerHost to handle the crash.
class SandboxedHandler {
@@ -62,12 +93,48 @@ class SandboxedHandler {
return instance;
}
- bool Initialize() {
- SetSanitizationInfo(&sanitization_);
+ bool Initialize(bool dump_at_crash) {
+ request_dump_ = dump_at_crash ? 1 : 0;
+
+ SetSanitizationInfo(crash_reporter::GetCrashReporterClient(),
+ &sanitization_);
server_fd_ = base::GlobalDescriptors::GetInstance()->Get(
service_manager::kCrashDumpSignal);
- return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
+#if defined(OS_ANDROID)
+ // Android's debuggerd handler on JB MR2 until OREO displays a dialog which
+ // is a bad user experience for child process crashes. Disable the debuggerd
+ // handler for user builds. crbug.com/273706
+ base::android::BuildInfo* build_info =
+ base::android::BuildInfo::GetInstance();
+ restore_previous_handler_ =
+ build_info->sdk_int() < base::android::SDK_VERSION_JELLY_BEAN_MR2 ||
+ build_info->sdk_int() >= base::android::SDK_VERSION_OREO ||
+ strcmp(build_info->build_type(), "eng") == 0 ||
+ strcmp(build_info->build_type(), "userdebug") == 0;
+#else
+ restore_previous_handler_ = false;
+#endif
+
+ return Signals::InstallCrashHandlers(HandleCrash, 0, &old_actions_);
+ }
+
+ void HandleCrashNonFatal(int signo, siginfo_t* siginfo, void* context) {
+ base::ScopedFD connection;
+ if (ConnectToHandler(signo, &connection) == 0) {
+ ExceptionInformation exception_information;
+ SetExceptionInformation(siginfo, static_cast<ucontext_t*>(context),
+ &exception_information);
+
+ ClientInformation info;
+ SetClientInformation(&exception_information, &sanitization_, &info);
+
+ ScopedPrSetDumpable set_dumpable(/* may_log= */ false);
+
+ ExceptionHandlerClient handler_client(connection.get());
+ handler_client.SetCanSetPtracer(false);
+ handler_client.RequestCrashDump(info);
+ }
}
private:
@@ -82,15 +149,23 @@ class SandboxedHandler {
base::ScopedFD local_connection(fds[0]);
base::ScopedFD handlers_socket(fds[1]);
- iovec iov;
- iov.iov_base = &signo;
- iov.iov_len = sizeof(signo);
+ // SELinux may block the handler from setting SO_PASSCRED on this socket.
+ // Attempt to set it here, but the handler can still try if this fails.
+ int optval = 1;
+ socklen_t optlen = sizeof(optval);
+ setsockopt(handlers_socket.get(), SOL_SOCKET, SO_PASSCRED, &optval, optlen);
+
+ iovec iov[2];
+ iov[0].iov_base = &signo;
+ iov[0].iov_len = sizeof(signo);
+ iov[1].iov_base = &request_dump_;
+ iov[1].iov_len = sizeof(request_dump_);
msghdr msg;
msg.msg_name = nullptr;
msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = base::size(iov);
char cmsg_buf[CMSG_SPACE(sizeof(int))];
msg.msg_control = cmsg_buf;
@@ -112,37 +187,21 @@ class SandboxedHandler {
static void HandleCrash(int signo, siginfo_t* siginfo, void* context) {
SandboxedHandler* state = Get();
-
- base::ScopedFD connection;
- if (state->ConnectToHandler(signo, &connection) == 0) {
- ExceptionInformation exception_information;
- exception_information.siginfo_address =
- FromPointerCast<decltype(exception_information.siginfo_address)>(
- siginfo);
- exception_information.context_address =
- FromPointerCast<decltype(exception_information.context_address)>(
- context);
- exception_information.thread_id = sandbox::sys_gettid();
-
- ClientInformation info = {};
- info.exception_information_address =
- FromPointerCast<decltype(info.exception_information_address)>(
- &exception_information);
-
- info.sanitization_information_address =
- FromPointerCast<decltype(info.sanitization_information_address)>(
- &state->sanitization_);
-
- ExceptionHandlerClient handler_client(connection.get());
- handler_client.SetCanSetPtracer(false);
- handler_client.RequestCrashDump(info);
- }
-
- Signals::RestoreHandlerAndReraiseSignalOnReturn(siginfo, nullptr);
+ state->HandleCrashNonFatal(signo, siginfo, context);
+ Signals::RestoreHandlerAndReraiseSignalOnReturn(
+ siginfo, state->restore_previous_handler_
+ ? state->old_actions_.ActionForSignal(signo)
+ : nullptr);
}
+ Signals::OldActions old_actions_ = {};
SanitizationInformation sanitization_;
int server_fd_;
+ unsigned char request_dump_;
+
+ // true if the previously installed signal handler is restored after
+ // handling a crash. Otherwise SIG_DFL is restored.
+ bool restore_previous_handler_;
DISALLOW_COPY_AND_ASSIGN(SandboxedHandler);
};
@@ -169,6 +228,7 @@ void SetBuildInfoAnnotations(std::map<std::string, std::string>* annotations) {
(*annotations)["android_build_id"] = info->android_build_id();
(*annotations)["android_build_fp"] = info->android_build_fp();
+ (*annotations)["sdk"] = base::StringPrintf("%d", info->sdk_int());
(*annotations)["device"] = info->device();
(*annotations)["model"] = info->model();
(*annotations)["brand"] = info->brand();
@@ -186,14 +246,85 @@ void SetBuildInfoAnnotations(std::map<std::string, std::string>* annotations) {
}
}
+#if defined(__arm__) && defined(__ARM_ARCH_7A__)
+#define CURRENT_ABI "armeabi-v7a"
+#elif defined(__arm__)
+#define CURRENT_ABI "armeabi"
+#elif defined(__i386__)
+#define CURRENT_ABI "x86"
+#elif defined(__mips__)
+#define CURRENT_ABI "mips"
+#elif defined(__x86_64__)
+#define CURRENT_ABI "x86_64"
+#elif defined(__aarch64__)
+#define CURRENT_ABI "arm64-v8a"
+#else
+#error "Unsupported target abi"
+#endif
+
+void MakePackagePaths(std::string* classpath, std::string* libpath) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ base::android::ScopedJavaLocalRef<jstring> arch =
+ base::android::ConvertUTF8ToJavaString(env,
+ base::StringPiece(CURRENT_ABI));
+ base::android::ScopedJavaLocalRef<jobjectArray> paths =
+ Java_PackagePaths_makePackagePaths(env, arch);
+
+ base::android::ConvertJavaStringToUTF8(
+ env, static_cast<jstring>(env->GetObjectArrayElement(paths.obj(), 0)),
+ classpath);
+ base::android::ConvertJavaStringToUTF8(
+ env, static_cast<jstring>(env->GetObjectArrayElement(paths.obj(), 1)),
+ libpath);
+}
+
+// Copies and extends the current environment with CLASSPATH and LD_LIBRARY_PATH
+// set to library paths in the APK.
+bool BuildEnvironmentWithApk(std::vector<std::string>* result) {
+ DCHECK(result->empty());
+
+ std::string classpath;
+ std::string library_path;
+ MakePackagePaths(&classpath, &library_path);
+
+ std::unique_ptr<base::Environment> env(base::Environment::Create());
+ static constexpr char kClasspathVar[] = "CLASSPATH";
+ std::string current_classpath;
+ env->GetVar(kClasspathVar, &current_classpath);
+ classpath += ":" + current_classpath;
+
+ static constexpr char kLdLibraryPathVar[] = "LD_LIBRARY_PATH";
+ std::string current_library_path;
+ env->GetVar(kLdLibraryPathVar, &current_library_path);
+ library_path += ":" + current_library_path;
+
+ result->push_back("CLASSPATH=" + classpath);
+ result->push_back("LD_LIBRARY_PATH=" + library_path);
+ for (char** envp = environ; *envp != nullptr; ++envp) {
+ if ((strncmp(*envp, kClasspathVar, strlen(kClasspathVar)) == 0 &&
+ (*envp)[strlen(kClasspathVar)] == '=') ||
+ (strncmp(*envp, kLdLibraryPathVar, strlen(kLdLibraryPathVar)) == 0 &&
+ (*envp)[strlen(kLdLibraryPathVar)] == '=')) {
+ continue;
+ }
+ result->push_back(*envp);
+ }
+
+ return true;
+}
+
+const char kCrashpadJavaMain[] =
+ "org.chromium.components.crash.browser.CrashpadMain";
+
#endif // OS_ANDROID
-bool BuildHandlerArgs(base::FilePath* database_path,
+void BuildHandlerArgs(CrashReporterClient* crash_reporter_client,
+ base::FilePath* database_path,
base::FilePath* metrics_path,
std::string* url,
std::map<std::string, std::string>* process_annotations,
std::vector<std::string>* arguments) {
- CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
crash_reporter_client->GetCrashDumpLocation(database_path);
crash_reporter_client->GetCrashMetricsLocation(metrics_path);
@@ -241,7 +372,6 @@ bool BuildHandlerArgs(base::FilePath* database_path,
// so that minidumps produced by Crashpad's generate_dump tool will
// contain these annotations.
arguments->push_back("--monitor-self-annotation=ptype=crashpad-handler");
- return true;
}
bool GetHandlerPath(base::FilePath* exe_dir, base::FilePath* handler_path) {
@@ -290,32 +420,57 @@ class HandlerStarter {
return instance;
}
- base::FilePath Initialize() {
- base::FilePath exe_dir;
- base::FilePath handler_path;
- if (!GetHandlerPath(&exe_dir, &handler_path)) {
- return base::FilePath();
- }
-
- if (!SetLdLibraryPath(exe_dir)) {
- return base::FilePath();
- }
-
+ base::FilePath Initialize(bool dump_at_crash) {
base::FilePath database_path;
base::FilePath metrics_path;
std::string url;
std::map<std::string, std::string> process_annotations;
std::vector<std::string> arguments;
- if (!BuildHandlerArgs(&database_path, &metrics_path, &url,
- &process_annotations, &arguments)) {
- return base::FilePath();
+ BuildHandlerArgs(GetCrashReporterClient(), &database_path, &metrics_path,
+ &url, &process_annotations, &arguments);
+
+ base::FilePath exe_dir;
+ base::FilePath handler_path;
+ if (!GetHandlerPath(&exe_dir, &handler_path)) {
+ return database_path;
}
- if (crashpad::SetSanitizationInfo(&browser_sanitization_info_)) {
+ if (crashpad::SetSanitizationInfo(GetCrashReporterClient(),
+ &browser_sanitization_info_)) {
arguments.push_back(base::StringPrintf("--sanitization-information=%p",
&browser_sanitization_info_));
}
+#if defined(OS_ANDROID)
+ if (!base::PathExists(handler_path)) {
+ use_java_handler_ = true;
+ }
+
+ if (!dump_at_crash) {
+ return database_path;
+ }
+
+ if (use_java_handler_) {
+ std::vector<std::string> env;
+ if (!BuildEnvironmentWithApk(&env)) {
+ return database_path;
+ }
+
+ // TODO(jperaza): The logic for constructing an appropriate
+ // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
+ // need to be launched by executing the dynamic linker instead.
+ bool result = GetCrashpadClient().StartJavaHandlerAtCrash(
+ kCrashpadJavaMain, &env, database_path, metrics_path, url,
+ process_annotations, arguments);
+ DCHECK(result);
+ return database_path;
+ }
+#endif
+
+ if (!SetLdLibraryPath(exe_dir)) {
+ return database_path;
+ }
+
bool result = GetCrashpadClient().StartHandlerAtCrash(
handler_path, database_path, metrics_path, url, process_annotations,
arguments);
@@ -323,24 +478,46 @@ class HandlerStarter {
return database_path;
}
- bool StartHandlerForClient(int fd) {
+ bool StartHandlerForClient(CrashReporterClient* client, int fd) {
+ base::FilePath database_path;
+ base::FilePath metrics_path;
+ std::string url;
+ std::map<std::string, std::string> process_annotations;
+ std::vector<std::string> arguments;
+ BuildHandlerArgs(client, &database_path, &metrics_path, &url,
+ &process_annotations, &arguments);
+
+#if defined(OS_ANDROID)
+ std::string browser_ptype;
+ if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
+ process_annotations["ptype"] = browser_ptype;
+ }
+#endif // defined(OS_ANDROID)
+
base::FilePath exe_dir;
base::FilePath handler_path;
if (!GetHandlerPath(&exe_dir, &handler_path)) {
return false;
}
- if (!SetLdLibraryPath(exe_dir)) {
- return false;
+#if defined(OS_ANDROID)
+ if (use_java_handler_) {
+ std::vector<std::string> env;
+ if (!BuildEnvironmentWithApk(&env)) {
+ return false;
+ }
+
+ // TODO(jperaza): The logic for constructing an appropriate
+ // CLASSPATH/LD_LIBRARY_PATH won't work for Android Q+. The handler will
+ // need to be launched by executing the dynamic linker instead.
+ bool result = GetCrashpadClient().StartJavaHandlerForClient(
+ kCrashpadJavaMain, &env, database_path, metrics_path, url,
+ process_annotations, arguments, fd);
+ return result;
}
+#endif
- base::FilePath database_path;
- base::FilePath metrics_path;
- std::string url;
- std::map<std::string, std::string> process_annotations;
- std::vector<std::string> arguments;
- if (!BuildHandlerArgs(&database_path, &metrics_path, &url,
- &process_annotations, &arguments)) {
+ if (!SetLdLibraryPath(exe_dir)) {
return false;
}
@@ -354,16 +531,91 @@ class HandlerStarter {
~HandlerStarter() = delete;
crashpad::SanitizationInformation browser_sanitization_info_;
+#if defined(OS_ANDROID)
+ bool use_java_handler_ = false;
+#endif
DISALLOW_COPY_AND_ASSIGN(HandlerStarter);
};
+bool ConnectToHandler(CrashReporterClient* client, base::ScopedFD* connection) {
+ int fds[2];
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) {
+ PLOG(ERROR) << "socketpair";
+ return false;
+ }
+ base::ScopedFD local_connection(fds[0]);
+ base::ScopedFD handlers_socket(fds[1]);
+
+ if (!HandlerStarter::Get()->StartHandlerForClient(client,
+ handlers_socket.get())) {
+ return false;
+ }
+
+ *connection = std::move(local_connection);
+ return true;
+}
+
+bool g_is_browser = false;
+
} // namespace
+#if defined(OS_ANDROID)
+// TODO(jperaza): This might be simplified to have both the browser and child
+// processes use CRASHPAD_SIMULATE_CRASH() if CrashpadClient allows injecting
+// the Chromium specific SandboxedHandler.
+void DumpWithoutCrashing() {
+ if (g_is_browser) {
+ CRASHPAD_SIMULATE_CRASH();
+ } else {
+ siginfo_t siginfo;
+ siginfo.si_signo = crashpad::Signals::kSimulatedSigno;
+ siginfo.si_errno = 0;
+ siginfo.si_code = 0;
+
+ ucontext_t context;
+ crashpad::CaptureContext(&context);
+
+ crashpad::SandboxedHandler::Get()->HandleCrashNonFatal(siginfo.si_signo,
+ &siginfo, &context);
+ }
+}
+#endif
+
+bool DumpWithoutCrashingForClient(CrashReporterClient* client) {
+ base::ScopedFD connection;
+ if (!ConnectToHandler(client, &connection)) {
+ return false;
+ }
+
+ siginfo_t siginfo;
+ siginfo.si_signo = crashpad::Signals::kSimulatedSigno;
+ siginfo.si_errno = 0;
+ siginfo.si_code = 0;
+
+ ucontext_t context;
+ crashpad::CaptureContext(&context);
+
+ crashpad::SanitizationInformation sanitization;
+ crashpad::SetSanitizationInfo(client, &sanitization);
+
+ crashpad::ExceptionInformation exception;
+ crashpad::SetExceptionInformation(&siginfo, &context, &exception);
+
+ crashpad::ClientInformation info;
+ crashpad::SetClientInformation(&exception, &sanitization, &info);
+
+ crashpad::ScopedPrSetDumpable set_dumpable(/* may_log= */ false);
+
+ crashpad::ExceptionHandlerClient handler_client(connection.get());
+ return handler_client.RequestCrashDump(info) == 0;
+}
+
namespace internal {
bool StartHandlerForClient(int fd) {
- return HandlerStarter::Get()->StartHandlerForClient(fd);
+ return HandlerStarter::Get()->StartHandlerForClient(GetCrashReporterClient(),
+ fd);
}
base::FilePath PlatformCrashpadInitialization(
@@ -380,17 +632,26 @@ base::FilePath PlatformCrashpadInitialization(
DCHECK(!embedded_handler);
DCHECK(exe_path.empty());
+ g_is_browser = browser_process;
+
+ bool dump_at_crash = true;
#if defined(OS_ANDROID)
base::android::SetJavaExceptionCallback(SetJavaExceptionInfo);
+
+ unsigned int dump_percentage =
+ GetCrashReporterClient()->GetCrashDumpPercentageForWebView();
+ if (dump_percentage < 100 && rand() % 100 >= dump_percentage) {
+ dump_at_crash = false;
+ }
#endif // OS_ANDROID
if (browser_process) {
HandlerStarter* starter = HandlerStarter::Get();
- return starter->Initialize();
+ return starter->Initialize(dump_at_crash);
}
crashpad::SandboxedHandler* handler = crashpad::SandboxedHandler::Get();
- bool result = handler->Initialize();
+ bool result = handler->Initialize(dump_at_crash);
DCHECK(result);
return base::FilePath();
diff --git a/chromium/components/crash/content/app/crashpad_win.cc b/chromium/components/crash/content/app/crashpad_win.cc
index 8b55f0a521f..cc16c40ea32 100644
--- a/chromium/components/crash/content/app/crashpad_win.cc
+++ b/chromium/components/crash/content/app/crashpad_win.cc
@@ -10,6 +10,7 @@
#include "base/environment.h"
#include "base/files/file_util.h"
#include "base/numerics/safe_conversions.h"
+#include "base/stl_util.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
@@ -30,7 +31,7 @@ void GetPlatformCrashpadAnnotations(
std::map<std::string, std::string>* annotations) {
CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
wchar_t exe_file[MAX_PATH] = {};
- CHECK(::GetModuleFileName(nullptr, exe_file, arraysize(exe_file)));
+ CHECK(::GetModuleFileName(nullptr, exe_file, base::size(exe_file)));
base::string16 product_name, version, special_build, channel_name;
crash_reporter_client->GetProductNameAndVersion(
exe_file, &product_name, &version, &special_build, &channel_name);
@@ -96,7 +97,7 @@ base::FilePath PlatformCrashpadInitialization(
if (exe_file.empty()) {
wchar_t exe_file_path[MAX_PATH] = {};
CHECK(::GetModuleFileName(nullptr, exe_file_path,
- arraysize(exe_file_path)));
+ base::size(exe_file_path)));
exe_file = base::FilePath(exe_file_path);
}
diff --git a/chromium/components/crash/content/browser/BUILD.gn b/chromium/components/crash/content/browser/BUILD.gn
index d3dbf58e714..0f38a77059b 100644
--- a/chromium/components/crash/content/browser/BUILD.gn
+++ b/chromium/components/crash/content/browser/BUILD.gn
@@ -15,8 +15,6 @@ source_set("browser") {
"child_exit_observer_android.h",
"child_process_crash_observer_android.cc",
"child_process_crash_observer_android.h",
- "crash_dump_manager_android.cc",
- "crash_dump_manager_android.h",
"crash_memory_metrics_collector_android.cc",
"crash_memory_metrics_collector_android.h",
"crash_metrics_reporter_android.cc",
@@ -28,7 +26,6 @@ source_set("browser") {
"//components/crash/content/app",
"//content/public/browser",
"//content/public/common",
- "//third_party/breakpad:client",
]
if (is_linux || is_android) {
@@ -39,10 +36,14 @@ source_set("browser") {
"crash_handler_host_linux.cc",
"crash_handler_host_linux.h",
]
+ }
+
+ if (!is_chromeos) {
+ deps += [ "//third_party/crashpad/crashpad/client" ]
+ }
+
+ if (!is_android) {
deps += [ "//third_party/breakpad:client" ]
- if (!is_chromeos) {
- deps += [ "//third_party/crashpad/crashpad/client" ]
- }
}
# This is not in the GYP build but this target includes breakpad client
@@ -63,7 +64,6 @@ source_set("browser") {
source_set("unit_tests") {
testonly = true
sources = [
- "crash_dump_manager_android_unittest.cc",
"crash_metrics_reporter_android_unittest.cc",
]
deps = [
diff --git a/chromium/components/crash/content/browser/child_exit_observer_android.cc b/chromium/components/crash/content/browser/child_exit_observer_android.cc
index 5d9aa4c68f1..cd62274d372 100644
--- a/chromium/components/crash/content/browser/child_exit_observer_android.cc
+++ b/chromium/components/crash/content/browser/child_exit_observer_android.cc
@@ -129,20 +129,6 @@ void ChildExitObserver::OnChildExit(TerminationInfo* info) {
}
}
-void ChildExitObserver::BrowserChildProcessStarted(
- int process_host_id,
- content::PosixFileDescriptorInfo* mappings) {
- std::vector<Client*> registered_clients_copy;
- {
- base::AutoLock auto_lock(registered_clients_lock_);
- for (auto& client : registered_clients_)
- registered_clients_copy.push_back(client.get());
- }
- for (auto* client : registered_clients_copy) {
- client->OnChildStart(process_host_id, mappings);
- }
-}
-
void ChildExitObserver::BrowserChildProcessHostDisconnected(
const content::ChildProcessData& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -230,12 +216,18 @@ void ChildExitObserver::Observe(int type,
return;
}
const auto& iter = process_host_id_to_pid_.find(rph->GetID());
- if (iter != process_host_id_to_pid_.end()) {
- if (info.pid == base::kNullProcessHandle) {
- info.pid = iter->second;
- }
- process_host_id_to_pid_.erase(iter);
+ // NOTIFICATION_RENDERER_PROCESS_CLOSED corresponds to death of an underlying
+ // RenderProcess. NOTIFICATION_RENDERER_PROCESS_TERMINATED corresponds to when
+ // the RenderProcessHost's lifetime is ending. Ideally, we'd only listen to
+ // the former, but if the RenderProcessHost is destroyed before the
+ // RenderProcess, then the former is never sent.
+ if (iter == process_host_id_to_pid_.end()) {
+ return;
+ }
+ if (info.pid == base::kNullProcessHandle) {
+ info.pid = iter->second;
}
+ process_host_id_to_pid_.erase(iter);
OnChildExit(&info);
}
diff --git a/chromium/components/crash/content/browser/child_exit_observer_android.h b/chromium/components/crash/content/browser/child_exit_observer_android.h
index adbccc4770d..161d2e88f04 100644
--- a/chromium/components/crash/content/browser/child_exit_observer_android.h
+++ b/chromium/components/crash/content/browser/child_exit_observer_android.h
@@ -12,7 +12,6 @@
#include "base/android/application_status_listener.h"
#include "base/android/child_process_binding_types.h"
#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "base/scoped_observer.h"
#include "base/synchronization/lock.h"
@@ -20,7 +19,6 @@
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/posix_file_descriptor_info.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/process_type.h"
#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
@@ -46,7 +44,6 @@ class ChildExitObserver : public content::BrowserChildProcessObserver,
TerminationInfo(const TerminationInfo& other);
TerminationInfo& operator=(const TerminationInfo& other);
- // TODO(jperaza): Not valid until Crashpad is enabled.
bool is_crashed() const { return crash_signo != kInvalidSigno; }
int process_host_id = content::ChildProcessHost::kInvalidUniqueID;
@@ -55,7 +52,6 @@ class ChildExitObserver : public content::BrowserChildProcessObserver,
base::android::ApplicationState app_state =
base::android::APPLICATION_STATE_UNKNOWN;
- // TODO(jperaza): Not valid until Crashpad is enabled.
// The crash signal the child process received before it exited.
int crash_signo = kInvalidSigno;
@@ -109,9 +105,6 @@ class ChildExitObserver : public content::BrowserChildProcessObserver,
// process type.
class Client {
public:
- // OnChildStart is called on the launcher thread.
- virtual void OnChildStart(int process_host_id,
- content::PosixFileDescriptorInfo* mappings) = 0;
// OnChildExit is called on the UI thread.
// OnChildExit may be called twice for the same process.
virtual void OnChildExit(const TerminationInfo& info) = 0;
@@ -134,14 +127,6 @@ class ChildExitObserver : public content::BrowserChildProcessObserver,
// crashpad::CrashHandlerHost::Observer
void ChildReceivedCrashSignal(base::ProcessId pid, int signo) override;
- // BrowserChildProcessStarted must be called from
- // ContentBrowserClient::GetAdditionalMappedFilesForChildProcess
- // overrides, to notify the ChildExitObserver of child process
- // creation, and to allow clients to register any fd mappings they
- // need.
- void BrowserChildProcessStarted(int process_host_id,
- content::PosixFileDescriptorInfo* mappings);
-
private:
friend struct base::LazyInstanceTraitsBase<ChildExitObserver>;
diff --git a/chromium/components/crash/content/browser/child_process_crash_observer_android.cc b/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
index e235ba3a06f..cd46b75b334 100644
--- a/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
+++ b/chromium/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -4,47 +4,45 @@
#include "components/crash/content/browser/child_process_crash_observer_android.h"
-#include <utility>
-
+#include "base/android/jni_android.h"
#include "base/bind.h"
-#include "base/files/file_util.h"
#include "base/task/post_task.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/task/task_traits.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "components/crash/content/browser/crash_metrics_reporter_android.h"
+#include "jni/ChildProcessCrashObserver_jni.h"
namespace crash_reporter {
-ChildProcessCrashObserver::ChildProcessCrashObserver(
- const base::FilePath crash_dump_dir,
- int descriptor_id)
- : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {}
-
-ChildProcessCrashObserver::~ChildProcessCrashObserver() {}
+ChildProcessCrashObserver::ChildProcessCrashObserver() {
+ task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
+}
-void ChildProcessCrashObserver::OnChildStart(
- int process_host_id,
- content::PosixFileDescriptorInfo* mappings) {
- if (!breakpad::IsCrashReporterEnabled())
- return;
+ChildProcessCrashObserver::~ChildProcessCrashObserver() = default;
- base::ScopedFD file(
- breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- process_host_id));
- if (file.is_valid())
- mappings->Transfer(descriptor_id_, std::move(file));
+void ChildProcessCrashObserver::OnChildExit(
+ const ChildExitObserver::TerminationInfo& info) {
+ task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChildProcessCrashObserver::OnChildExitImpl,
+ base::Unretained(this), info));
}
-void ChildProcessCrashObserver::OnChildExit(
+void ChildProcessCrashObserver::OnChildExitImpl(
const ChildExitObserver::TerminationInfo& info) {
- // This might be called twice for a given child process, with a
- // NOTIFICATION_RENDERER_PROCESS_TERMINATED and then with
- // NOTIFICATION_RENDERER_PROCESS_CLOSED.
-
- base::PostTaskWithTraits(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::Bind(&breakpad::CrashDumpManager::ProcessMinidumpFileFromChild,
- base::Unretained(breakpad::CrashDumpManager::GetInstance()),
- crash_dump_dir_, info));
+ crash_reporter::CrashMetricsReporter::GetInstance()->ChildProcessExited(info);
+
+ if (!info.is_crashed()) {
+ return;
+ }
+
+ base::ScopedBlockingCall sbc(base::BlockingType::WILL_BLOCK);
+
+ // Hop over to Java to attempt to attach the logcat to the crash. This may
+ // fail, which is ok -- if it does, the crash will still be uploaded on the
+ // next browser start.
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ChildProcessCrashObserver_childCrashed(env, info.pid);
}
} // namespace crash_reporter
diff --git a/chromium/components/crash/content/browser/child_process_crash_observer_android.h b/chromium/components/crash/content/browser/child_process_crash_observer_android.h
index 7710e6f9d9b..a4014592c5f 100644
--- a/chromium/components/crash/content/browser/child_process_crash_observer_android.h
+++ b/chromium/components/crash/content/browser/child_process_crash_observer_android.h
@@ -5,28 +5,28 @@
#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
#define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
-#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
namespace crash_reporter {
+// Records metrics and initiates minidump upload in response to child process
+// crashes.
class ChildProcessCrashObserver
: public crash_reporter::ChildExitObserver::Client {
public:
- ChildProcessCrashObserver(const base::FilePath crash_dump_dir,
- int descriptor_id);
+ ChildProcessCrashObserver();
~ChildProcessCrashObserver() override;
// crash_reporter::ChildExitObserver::Client implementation:
- void OnChildStart(int process_host_id,
- content::PosixFileDescriptorInfo* mappings) override;
void OnChildExit(const ChildExitObserver::TerminationInfo& info) override;
private:
- base::FilePath crash_dump_dir_;
- // The id used to identify the file descriptor in the set of file
- // descriptor mappings passed to the child process.
- int descriptor_id_;
+ void OnChildExitImpl(const ChildExitObserver::TerminationInfo& info);
+
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
DISALLOW_COPY_AND_ASSIGN(ChildProcessCrashObserver);
};
diff --git a/chromium/components/crash/content/browser/crash_dump_manager_android.cc b/chromium/components/crash/content/browser/crash_dump_manager_android.cc
deleted file mode 100644
index 07132888c86..00000000000
--- a/chromium/components/crash/content/browser/crash_dump_manager_android.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2013 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/browser/crash_dump_manager_android.h"
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/files/file_util.h"
-#include "base/format_macros.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/process/process.h"
-#include "base/rand_util.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "jni/CrashDumpManager_jni.h"
-
-namespace breakpad {
-
-namespace {
-
-base::LazyInstance<CrashDumpManager>::Leaky g_instance =
- LAZY_INSTANCE_INITIALIZER;
-
-class DefaultUploader : public CrashDumpManager::Uploader {
- public:
- DefaultUploader() = default;
- ~DefaultUploader() override = default;
-
- // CrashDumpManager::Uploader:
- void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override {
- // Hop over to Java to attempt to attach the logcat to the crash. This may
- // fail, which is ok -- if it does, the crash will still be uploaded on the
- // next browser start.
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jstring> j_dump_path =
- base::android::ConvertUTF8ToJavaString(env, crash_dump_path.value());
- Java_CrashDumpManager_tryToUploadMinidump(env, j_dump_path);
- }
-};
-
-} // namespace
-
-// static
-CrashDumpManager* CrashDumpManager::GetInstance() {
- return g_instance.Pointer();
-}
-
-CrashDumpManager::CrashDumpManager()
- : uploader_(std::make_unique<DefaultUploader>()) {}
-
-CrashDumpManager::~CrashDumpManager() {}
-
-base::ScopedFD CrashDumpManager::CreateMinidumpFileForChild(
- int process_host_id) {
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- base::FilePath minidump_path;
- if (!base::CreateTemporaryFile(&minidump_path)) {
- LOG(ERROR) << "Failed to create temporary file, crash won't be reported.";
- return base::ScopedFD();
- }
-
- // We need read permission as the minidump is generated in several phases
- // and needs to be read at some point.
- int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
- base::File::FLAG_WRITE;
- base::File minidump_file(minidump_path, flags);
- if (!minidump_file.IsValid()) {
- LOG(ERROR) << "Failed to open temporary file, crash won't be reported.";
- return base::ScopedFD();
- }
-
- SetMinidumpPath(process_host_id, minidump_path);
- return base::ScopedFD(minidump_file.TakePlatformFile());
-}
-
-void CrashDumpManager::ProcessMinidumpFileFromChild(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info) {
- CrashDumpManager::CrashDumpStatus status =
- ProcessMinidumpFileFromChildInternal(crash_dump_dir, info);
- crash_reporter::CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- info, status);
-}
-
-CrashDumpManager::CrashDumpStatus
-CrashDumpManager::ProcessMinidumpFileFromChildInternal(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info) {
- base::FilePath minidump_path;
- // If the minidump for a given child process has already been
- // processed, then there is no more work to do.
- if (!GetMinidumpPath(info.process_host_id, &minidump_path)) {
- return CrashDumpStatus::kMissingDump;
- }
-
- int64_t file_size = 0;
-
- base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
- if (!base::PathExists(minidump_path)) {
- LOG(ERROR) << "minidump does not exist " << minidump_path.value();
- return CrashDumpStatus::kMissingDump;
- }
-
- int r = base::GetFileSize(minidump_path, &file_size);
- DCHECK(r) << "Failed to retrieve size for minidump " << minidump_path.value();
-
- if (file_size == 0) {
- // Empty minidump, this process did not crash. Just remove the file.
- r = base::DeleteFile(minidump_path, false);
- DCHECK(r) << "Failed to delete temporary minidump file "
- << minidump_path.value();
- return CrashDumpStatus::kEmptyDump;
- }
-
- // We are dealing with a valid minidump. Copy it to the crash report
- // directory from where Java code will upload it later on.
- if (crash_dump_dir.empty()) {
- NOTREACHED() << "Failed to retrieve the crash dump directory.";
- return CrashDumpStatus::kDumpProcessingFailed;
- }
- const uint64_t rand = base::RandUint64();
- const std::string filename =
- base::StringPrintf("chromium-renderer-minidump-%016" PRIx64 ".dmp%d",
- rand, info.process_host_id);
- base::FilePath dest_path = crash_dump_dir.Append(filename);
- r = base::Move(minidump_path, dest_path);
- if (!r) {
- LOG(ERROR) << "Failed to move crash dump from " << minidump_path.value()
- << " to " << dest_path.value();
- base::DeleteFile(minidump_path, false);
- return CrashDumpStatus::kDumpProcessingFailed;
- }
- VLOG(1) << "Crash minidump successfully generated: " << dest_path.value();
-
- uploader_->TryToUploadCrashDump(dest_path);
- return CrashDumpStatus::kValidDump;
-}
-
-void CrashDumpManager::SetMinidumpPath(int process_host_id,
- const base::FilePath& minidump_path) {
- base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
- DCHECK(
- !base::ContainsKey(process_host_id_to_minidump_path_, process_host_id));
- process_host_id_to_minidump_path_[process_host_id] = minidump_path;
-}
-
-bool CrashDumpManager::GetMinidumpPath(int process_host_id,
- base::FilePath* minidump_path) {
- base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
- ChildProcessIDToMinidumpPath::iterator iter =
- process_host_id_to_minidump_path_.find(process_host_id);
- if (iter == process_host_id_to_minidump_path_.end()) {
- return false;
- }
- *minidump_path = iter->second;
- process_host_id_to_minidump_path_.erase(iter);
- return true;
-}
-
-} // namespace breakpad
diff --git a/chromium/components/crash/content/browser/crash_dump_manager_android.h b/chromium/components/crash/content/browser/crash_dump_manager_android.h
deleted file mode 100644
index bc10af0c95e..00000000000
--- a/chromium/components/crash/content/browser/crash_dump_manager_android.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 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 COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-#define COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "base/android/application_status_listener.h"
-#include "base/files/file_path.h"
-#include "base/files/platform_file.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "content/public/common/child_process_host.h"
-#include "content/public/common/process_type.h"
-
-namespace breakpad {
-
-// This class manages the crash minidumps.
-// On Android, because of process isolation, each renderer process runs with a
-// different UID. As a result, we cannot generate the minidumps in the browser
-// (as the browser process does not have access to some system files for the
-// crashed process). So the minidump is generated in the renderer process.
-// Since the isolated process cannot open files, we provide it on creation with
-// a file descriptor into which to write the minidump in the event of a crash.
-// This class creates these file descriptors and associates them with render
-// processes and takes the appropriate action when the render process
-// terminates.
-class CrashDumpManager {
- public:
- enum class CrashDumpStatus {
- // The dump for this process did not have a path set. This can happen if the
- // dump was already processed or if crash dump generation is not turned on.
- kMissingDump,
-
- // The crash dump was empty.
- kEmptyDump,
-
- // Minidump file was found, but could not be copied to crash dir.
- kDumpProcessingFailed,
-
- // The crash dump is valid.
- kValidDump,
- };
-
- // Class which aids in uploading a crash dump.
- class Uploader {
- public:
- virtual ~Uploader() = default;
-
- // Attempts to upload the specified child process minidump.
- virtual void TryToUploadCrashDump(
- const base::FilePath& crash_dump_path) = 0;
- };
-
- static CrashDumpManager* GetInstance();
-
- void ProcessMinidumpFileFromChild(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
- base::ScopedFD CreateMinidumpFileForChild(int process_host_id);
-
- // Careful, |uploader_| is accessed on one of the task scheduler threads.
- // Tests should set this before any other threads are spawned.
- void set_uploader_for_testing(std::unique_ptr<Uploader> uploader) {
- DCHECK(uploader);
- uploader_ = std::move(uploader);
- }
-
- private:
- friend struct base::LazyInstanceTraitsBase<CrashDumpManager>;
-
- CrashDumpManager();
- ~CrashDumpManager();
-
- CrashDumpStatus ProcessMinidumpFileFromChildInternal(
- base::FilePath crash_dump_dir,
- const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
- typedef std::map<int, base::FilePath> ChildProcessIDToMinidumpPath;
-
- void SetMinidumpPath(int process_host_id,
- const base::FilePath& minidump_path);
- bool GetMinidumpPath(int process_host_id, base::FilePath* minidump_path);
-
- // Should never be nullptr.
- std::unique_ptr<Uploader> uploader_;
-
- // This map should only be accessed with its lock aquired as it is accessed
- // from the PROCESS_LAUNCHER and UI threads.
- base::Lock process_host_id_to_minidump_path_lock_;
- ChildProcessIDToMinidumpPath process_host_id_to_minidump_path_;
-
- DISALLOW_COPY_AND_ASSIGN(CrashDumpManager);
-};
-
-} // namespace breakpad
-
-#endif // COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
diff --git a/chromium/components/crash/content/browser/crash_dump_manager_android_unittest.cc b/chromium/components/crash/content/browser/crash_dump_manager_android_unittest.cc
deleted file mode 100644
index 0b284e14a39..00000000000
--- a/chromium/components/crash/content/browser/crash_dump_manager_android_unittest.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// 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/browser/crash_dump_manager_android.h"
-
-#include <string>
-#include <utility>
-
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
-#include "base/run_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task/post_task.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/threading/thread_restrictions.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace breakpad {
-
-class CrashDumpManagerTest;
-
-class CrashMetricsReporterObserver
- : public crash_reporter::CrashMetricsReporter::Observer {
- public:
- CrashMetricsReporterObserver() {}
- ~CrashMetricsReporterObserver() {}
-
- // crash_reporter::CrashMetricsReporter::Observer:
- void OnCrashDumpProcessed(
- int rph_id,
- const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet&
- reported_counts) override {
- wait_run_loop_.QuitClosure().Run();
- }
-
- void WaitForProcessed() { wait_run_loop_.Run(); }
-
- private:
- base::RunLoop wait_run_loop_;
- DISALLOW_COPY_AND_ASSIGN(CrashMetricsReporterObserver);
-};
-
-class NoOpUploader : public CrashDumpManager::Uploader {
- public:
- NoOpUploader(scoped_refptr<base::SequencedTaskRunner> test_runner,
- CrashDumpManagerTest* test_harness)
- : test_runner_(std::move(test_runner)), test_harness_(test_harness) {}
- ~NoOpUploader() override = default;
-
- // CrashDumpManager::Uploader:
- void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override;
-
- private:
- scoped_refptr<base::SequencedTaskRunner> test_runner_;
- CrashDumpManagerTest* test_harness_;
- DISALLOW_COPY_AND_ASSIGN(NoOpUploader);
-};
-
-class CrashDumpManagerTest : public testing::Test {
- public:
- CrashDumpManagerTest()
- : scoped_environment_(
- base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
- ~CrashDumpManagerTest() override {}
-
- void SetUp() override {
- // Initialize the manager.
- ASSERT_TRUE(CrashDumpManager::GetInstance());
- CrashDumpManager::GetInstance()->set_uploader_for_testing(
- std::make_unique<NoOpUploader>(base::SequencedTaskRunnerHandle::Get(),
- this));
- }
-
- void OnUploadedCrashDump() {
- dumps_uploaded_++;
- if (!upload_waiter_.is_null())
- std::move(upload_waiter_).Run();
- }
-
- void WaitForCrashDumpsUploaded(int num_dumps) {
- EXPECT_LE(num_dumps, dumps_uploaded_);
- while (num_dumps < dumps_uploaded_) {
- base::RunLoop run_loop;
- upload_waiter_ = run_loop.QuitClosure();
- run_loop.Run();
- }
- }
-
- static void CreateAndProcessCrashDump(
- const crash_reporter::ChildExitObserver::TerminationInfo& info,
- const std::string& data) {
- base::ScopedFD fd =
- CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- info.process_host_id);
- EXPECT_TRUE(fd.is_valid());
- base::WriteFileDescriptor(fd.get(), data.data(), data.size());
- base::ScopedTempDir dump_dir;
- EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
- CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
- dump_dir.GetPath(), info);
- }
-
- protected:
- int dumps_uploaded_ = 0;
-
- private:
- base::ShadowingAtExitManager at_exit_;
- base::test::ScopedTaskEnvironment scoped_environment_;
- base::OnceClosure upload_waiter_;
- DISALLOW_COPY_AND_ASSIGN(CrashDumpManagerTest);
-};
-
-void NoOpUploader::TryToUploadCrashDump(const base::FilePath& crash_dump_path) {
- test_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CrashDumpManagerTest::OnUploadedCrashDump,
- base::Unretained(test_harness_)));
-}
-
-TEST_F(CrashDumpManagerTest, NonOomCrash) {
- base::HistogramTester histogram_tester;
-
- CrashMetricsReporterObserver observer;
- crash_reporter::CrashMetricsReporter::GetInstance()->AddObserver(&observer);
-
- crash_reporter::ChildExitObserver::TerminationInfo termination_info;
- termination_info.process_host_id = 1;
- termination_info.pid = base::kNullProcessHandle;
- termination_info.process_type = content::PROCESS_TYPE_RENDERER;
- termination_info.app_state =
- base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
- termination_info.normal_termination = false;
- termination_info.binding_state = base::android::ChildBindingState::STRONG;
- termination_info.was_killed_intentionally_by_browser = false;
- termination_info.was_oom_protected_status = true;
- base::PostTaskWithTraits(
- FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
- base::BindOnce(&CrashDumpManagerTest::CreateAndProcessCrashDump,
- termination_info, "Some non-empty crash data"));
- observer.WaitForProcessed();
-
- histogram_tester.ExpectUniqueSample(
- "Tab.RendererDetailedExitStatus",
- crash_reporter::CrashMetricsReporter::VALID_MINIDUMP_WHILE_RUNNING, 1);
- WaitForCrashDumpsUploaded(1);
-}
-
-} // namespace breakpad
diff --git a/chromium/components/crash/content/browser/crash_handler_host_linux.cc b/chromium/components/crash/content/browser/crash_handler_host_linux.cc
index 815bf788f28..13cf0e84db6 100644
--- a/chromium/components/crash/content/browser/crash_handler_host_linux.cc
+++ b/chromium/components/crash/content/browser/crash_handler_host_linux.cc
@@ -28,6 +28,7 @@
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
+#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/post_task.h"
@@ -53,6 +54,7 @@
#if !defined(OS_CHROMEOS)
#include "components/crash/content/app/crashpad.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h" // nogncheck
+#include "third_party/crashpad/crashpad/util/posix/signals.h" // nogncheck
#endif
using content::BrowserThread;
@@ -116,7 +118,6 @@ CrashHandlerHostLinux::CrashHandlerHostLinux(const std::string& process_type,
upload_(upload),
#endif
fd_watch_controller_(FROM_HERE),
- shutting_down_(false),
blocking_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::USER_VISIBLE})) {
int fds[2];
@@ -228,10 +229,9 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
const ssize_t msg_size = HANDLE_EINTR(recvmsg(browser_socket_, &msg, 0));
if (msg_size < 0) {
- LOG(ERROR) << "Error reading from death signal socket. Crash dumping"
- << " is disabled."
- << " msg_size:" << msg_size
- << " errno:" << errno;
+ PLOG(ERROR) << "Error reading from death signal socket. Crash dumping"
+ << " is disabled."
+ << " msg_size:" << msg_size;
fd_watch_controller_.StopWatchingFileDescriptor();
return;
}
@@ -491,12 +491,12 @@ void CrashHandlerHostLinux::WillDestroyCurrentMessageLoop() {
// If we are quitting and there are crash dumps in the queue, turn them into
// no-ops.
- shutting_down_ = true;
+ shutting_down_.Set();
uploader_thread_->Stop();
}
bool CrashHandlerHostLinux::IsShuttingDown() const {
- return shutting_down_;
+ return shutting_down_.IsSet();
}
} // namespace breakpad
@@ -569,15 +569,18 @@ void CrashHandlerHost::Init() {
bool CrashHandlerHost::ReceiveClientMessage(int client_fd,
base::ScopedFD* handler_fd) {
int signo;
- iovec iov;
- iov.iov_base = &signo;
- iov.iov_len = sizeof(signo);
+ unsigned char request_dump;
+ iovec iov[2];
+ iov[0].iov_base = &signo;
+ iov[0].iov_len = sizeof(signo);
+ iov[1].iov_base = &request_dump;
+ iov[1].iov_len = sizeof(request_dump);
msghdr msg;
msg.msg_name = nullptr;
msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = base::size(iov);
char cmsg_buf[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(ucred))];
msg.msg_control = cmsg_buf;
@@ -615,7 +618,17 @@ bool CrashHandlerHost::ReceiveClientMessage(int client_fd,
return false;
}
- NotifyCrashSignalObservers(child_pid, signo);
+ if (signo != crashpad::Signals::kSimulatedSigno) {
+ NotifyCrashSignalObservers(child_pid, signo);
+ }
+
+#if defined(OS_ANDROID)
+ if (!request_dump) {
+ return false;
+ }
+#else
+ DCHECK(request_dump);
+#endif
handler_fd->reset(child_fd.release());
return true;
diff --git a/chromium/components/crash/content/browser/crash_handler_host_linux.h b/chromium/components/crash/content/browser/crash_handler_host_linux.h
index 916005283a6..18f156cb860 100644
--- a/chromium/components/crash/content/browser/crash_handler_host_linux.h
+++ b/chromium/components/crash/content/browser/crash_handler_host_linux.h
@@ -17,6 +17,7 @@
#include "base/message_loop/message_loop_current.h"
#include "base/message_loop/message_pump_for_io.h"
#include "base/process/process_handle.h"
+#include "base/synchronization/atomic_flag.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
@@ -108,7 +109,7 @@ class CrashHandlerHostLinux
base::MessagePumpForIO::FdWatchController fd_watch_controller_;
std::unique_ptr<base::Thread> uploader_thread_;
- bool shutting_down_;
+ base::AtomicFlag shutting_down_;
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_;
diff --git a/chromium/components/crash/content/browser/crash_metrics_reporter_android.cc b/chromium/components/crash/content/browser/crash_metrics_reporter_android.cc
index bf6d85a219b..9ddeee9f2f0 100644
--- a/chromium/components/crash/content/browser/crash_metrics_reporter_android.cc
+++ b/chromium/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -8,7 +8,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/optional.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/rand_util.h"
namespace crash_reporter {
namespace {
@@ -108,35 +108,17 @@ void CrashMetricsReporter::RemoveObserver(
async_observers_->RemoveObserver(observer);
}
-void CrashMetricsReporter::CrashDumpProcessed(
- const ChildExitObserver::TerminationInfo& info,
- breakpad::CrashDumpManager::CrashDumpStatus status) {
+void CrashMetricsReporter::ChildProcessExited(
+ const ChildExitObserver::TerminationInfo& info) {
ReportedCrashTypeSet reported_counts;
-
- // Avoid duplicating processing for the same process.
- if (status == breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump)
- return;
-
- bool has_valid_dump = false;
- switch (status) {
- case breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump:
- NOTREACHED();
- break;
- case breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump:
- has_valid_dump = false;
- break;
- case breakpad::CrashDumpManager::CrashDumpStatus::kValidDump:
- case breakpad::CrashDumpManager::CrashDumpStatus::kDumpProcessingFailed:
- has_valid_dump = true;
- break;
- }
+ const bool crashed = info.is_crashed();
const bool app_foreground =
info.app_state ==
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
info.app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
const bool intentional_kill = info.was_killed_intentionally_by_browser;
const bool android_oom_kill = !info.was_killed_intentionally_by_browser &&
- !has_valid_dump && !info.normal_termination;
+ !crashed && !info.normal_termination;
const bool renderer_visible = info.renderer_has_visible_clients;
const bool renderer_subframe = info.renderer_was_subframe;
const bool renderer_allocation_failed =
@@ -170,7 +152,7 @@ void CrashMetricsReporter::CrashDumpProcessed(
if (info.process_type == content::PROCESS_TYPE_RENDERER && app_foreground) {
if (renderer_visible) {
- if (has_valid_dump) {
+ if (crashed) {
ReportCrashCount(
renderer_subframe
? ProcessedCrashCounts::kRendererForegroundVisibleSubframeCrash
@@ -219,7 +201,7 @@ void CrashMetricsReporter::CrashDumpProcessed(
vm_size_kb / 1024);
}
}
- } else if (!has_valid_dump) {
+ } else if (!crashed) {
// Record stats when renderer is not visible, but the process has oom
// protected bindings. This case occurs when a tab is switched or closed,
// the bindings are updated later than visibility on web contents.
@@ -267,7 +249,7 @@ void CrashMetricsReporter::CrashDumpProcessed(
&reported_counts);
}
- if (has_valid_dump) {
+ if (crashed) {
if (info.process_type == content::PROCESS_TYPE_RENDERER) {
ReportCrashCount(ProcessedCrashCounts::kRendererCrashAll,
&reported_counts);
@@ -305,7 +287,7 @@ void CrashMetricsReporter::CrashDumpProcessed(
info.remaining_process_with_strong_binding, 20);
}
- ReportLegacyCrashUma(info, has_valid_dump);
+ ReportLegacyCrashUma(info, crashed);
NotifyObservers(info.process_host_id, reported_counts);
}
diff --git a/chromium/components/crash/content/browser/crash_metrics_reporter_android.h b/chromium/components/crash/content/browser/crash_metrics_reporter_android.h
index f098ac21f2b..c2ededf3f4c 100644
--- a/chromium/components/crash/content/browser/crash_metrics_reporter_android.h
+++ b/chromium/components/crash/content/browser/crash_metrics_reporter_android.h
@@ -8,7 +8,6 @@
#include "base/containers/flat_set.h"
#include "base/observer_list_threadsafe.h"
#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
namespace crash_reporter {
@@ -75,8 +74,8 @@ class CrashMetricsReporter {
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
- void CrashDumpProcessed(const ChildExitObserver::TerminationInfo& info,
- breakpad::CrashDumpManager::CrashDumpStatus status);
+ void ChildProcessExited(
+ const crash_reporter::ChildExitObserver::TerminationInfo& info);
private:
CrashMetricsReporter();
diff --git a/chromium/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc b/chromium/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
index 380b9abbec6..a01347fb043 100644
--- a/chromium/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
+++ b/chromium/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
@@ -4,6 +4,8 @@
#include "components/crash/content/browser/crash_metrics_reporter_android.h"
+#include <signal.h>
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
@@ -47,20 +49,6 @@ class CrashMetricsReporterTest : public testing::Test {
base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
~CrashMetricsReporterTest() override {}
- static void CreateAndProcessCrashDump(
- const ChildExitObserver::TerminationInfo& info,
- const std::string& data) {
- base::ScopedFD fd =
- breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
- info.process_host_id);
- EXPECT_TRUE(fd.is_valid());
- base::WriteFileDescriptor(fd.get(), data.data(), data.size());
- base::ScopedTempDir dump_dir;
- EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
- breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
- dump_dir.GetPath(), info);
- }
-
protected:
blink::OomInterventionMetrics InterventionMetrics(bool allocation_failed) {
blink::OomInterventionMetrics metrics;
@@ -81,9 +69,7 @@ class CrashMetricsReporterTest : public testing::Test {
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(expected_crash_types, crash_dump_observer.recorded_crash_types());
@@ -180,6 +166,7 @@ TEST_F(CrashMetricsReporterTest, UtilityProcessAll) {
termination_info.process_type = content::PROCESS_TYPE_UTILITY;
termination_info.app_state =
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+ termination_info.crash_signo = SIGSEGV;
termination_info.normal_termination = false;
termination_info.binding_state = base::android::ChildBindingState::STRONG;
termination_info.was_killed_intentionally_by_browser = false;
@@ -189,9 +176,7 @@ TEST_F(CrashMetricsReporterTest, UtilityProcessAll) {
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(CrashMetricsReporter::ReportedCrashTypeSet(
@@ -329,6 +314,7 @@ TEST_F(CrashMetricsReporterTest, RendererForegroundCrash) {
termination_info.process_type = content::PROCESS_TYPE_RENDERER;
termination_info.app_state =
base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+ termination_info.crash_signo = SIGSEGV;
termination_info.normal_termination = true;
termination_info.binding_state = base::android::ChildBindingState::STRONG;
termination_info.was_killed_intentionally_by_browser = true;
@@ -338,9 +324,7 @@ TEST_F(CrashMetricsReporterTest, RendererForegroundCrash) {
CrashMetricsReporterObserver crash_dump_observer;
CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
- CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
- termination_info,
- breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+ CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
crash_dump_observer.WaitForProcessed();
EXPECT_EQ(
diff --git a/chromium/components/crash/content/tools/generate_breakpad_symbols.py b/chromium/components/crash/content/tools/generate_breakpad_symbols.py
index 2032f1991ad..c926de336a8 100755
--- a/chromium/components/crash/content/tools/generate_breakpad_symbols.py
+++ b/chromium/components/crash/content/tools/generate_breakpad_symbols.py
@@ -12,6 +12,7 @@ platforms is planned.
import collections
import errno
import glob
+import multiprocessing
import optparse
import os
import Queue
@@ -22,7 +23,7 @@ import sys
import threading
-CONCURRENT_TASKS=4
+CONCURRENT_TASKS=multiprocessing.cpu_count()
# The BINARY_INFO tuple describes a binary as dump_syms identifies it.
BINARY_INFO = collections.namedtuple('BINARY_INFO',
@@ -60,7 +61,7 @@ def Resolve(path, exe_path, loader_path, rpaths):
def GetSharedLibraryDependenciesLinux(binary):
- """Return absolute paths to all shared library dependecies of the binary.
+ """Return absolute paths to all shared library dependencies of the binary.
This implementation assumes that we're running on a Linux system."""
# TODO(thakis): Figure out how to make this work for android
@@ -72,7 +73,7 @@ def GetSharedLibraryDependenciesLinux(binary):
for line in ldd.splitlines():
m = lib_re.match(line)
if m:
- result.append(m.group(1))
+ result.append(os.path.abspath(m.group(1)))
return result
@@ -106,7 +107,7 @@ def GetDeveloperDirMac():
def GetSharedLibraryDependenciesMac(binary, exe_path):
- """Return absolute paths to all shared library dependecies of the binary.
+ """Return absolute paths to all shared library dependencies of the binary.
This implementation assumes that we're running on a Mac system."""
# realpath() serves two purposes:
@@ -164,7 +165,7 @@ def GetSharedLibraryDependenciesMac(binary, exe_path):
def GetSharedLibraryDependencies(options, binary, exe_path):
- """Return absolute paths to all shared library dependecies of the binary."""
+ """Return absolute paths to all shared library dependencies of the binary."""
deps = []
if sys.platform.startswith('linux'):
deps = GetSharedLibraryDependenciesLinux(binary)
@@ -183,6 +184,29 @@ def GetSharedLibraryDependencies(options, binary, exe_path):
return result
+def GetTransitiveDependencies(options):
+ """Return absolute paths to the transitive closure of all shared library
+ dependencies of the binary, along with the binary itself."""
+ binary = os.path.abspath(options.binary)
+ exe_path = os.path.dirname(binary)
+ if sys.platform.startswith('linux'):
+ # 'ldd' returns all transitive dependencies for us.
+ deps = set(GetSharedLibraryDependencies(options, binary, exe_path))
+ deps.add(binary)
+ return list(deps)
+ if sys.platform == 'darwin':
+ binaries = set([binary])
+ queue = [binary]
+ while queue:
+ deps = GetSharedLibraryDependencies(options, queue.pop(0), exe_path)
+ new_deps = set(deps) - binaries
+ binaries |= new_deps
+ queue.extend(list(new_deps))
+ return binaries
+ print "Platform not supported."
+ sys.exit(1)
+
+
def mkdir_p(path):
"""Simulates mkdir -p."""
try:
@@ -328,14 +352,7 @@ def main():
return 1
# Build the transitive closure of all dependencies.
- binaries = set([options.binary])
- queue = [options.binary]
- exe_path = os.path.dirname(options.binary)
- while queue:
- deps = GetSharedLibraryDependencies(options, queue.pop(0), exe_path)
- new_deps = set(deps) - binaries
- binaries |= new_deps
- queue.extend(list(new_deps))
+ binaries = GetTransitiveDependencies(options)
GenerateSymbols(options, binaries)
diff --git a/chromium/components/crash/core/browser/crashes_ui_util.cc b/chromium/components/crash/core/browser/crashes_ui_util.cc
index 78fa705f2e3..b714115c572 100644
--- a/chromium/components/crash/core/browser/crashes_ui_util.cc
+++ b/chromium/components/crash/core/browser/crashes_ui_util.cc
@@ -9,7 +9,7 @@
#include <vector>
#include "base/i18n/time_formatting.h"
-#include "base/macros.h"
+#include "base/stl_util.h"
#include "base/values.h"
#include "components/strings/grit/components_chromium_strings.h"
#include "components/strings/grit/components_strings.h"
@@ -38,7 +38,7 @@ const CrashesUILocalizedString kCrashesUILocalizedStrings[] = {
};
const size_t kCrashesUILocalizedStringsCount =
- arraysize(kCrashesUILocalizedStrings);
+ base::size(kCrashesUILocalizedStrings);
const char kCrashesUICrashesJS[] = "crashes.js";
const char kCrashesUIRequestCrashList[] = "requestCrashList";
diff --git a/chromium/components/crash/core/common/BUILD.gn b/chromium/components/crash/core/common/BUILD.gn
index c8e02ebf852..81912a5691c 100644
--- a/chromium/components/crash/core/common/BUILD.gn
+++ b/chromium/components/crash/core/common/BUILD.gn
@@ -20,7 +20,8 @@ group("common") {
}
}
-use_crashpad_annotation = (is_mac || is_win) && !use_crash_key_stubs
+use_crashpad_annotation =
+ (is_mac || is_win || is_android) && !use_crash_key_stubs
buildflag_header("crash_buildflags") {
header = "crash_buildflags.h"
@@ -143,7 +144,7 @@ source_set("unit_tests") {
sources += [ "objc_zombie_unittest.mm" ]
}
- if (!is_mac && !is_win && !is_fuchsia) {
+ if (!is_mac && !is_win && !is_fuchsia && !is_android) {
include_dirs = [ "//third_party/breakpad/breakpad/src/" ]
sources += [ "crash_key_breakpad_unittest.cc" ]
}
diff --git a/chromium/components/crash/core/common/crash_key.h b/chromium/components/crash/core/common/crash_key.h
index c96108a18b3..f27b6eb67f9 100644
--- a/chromium/components/crash/core/common/crash_key.h
+++ b/chromium/components/crash/core/common/crash_key.h
@@ -217,6 +217,8 @@ CRASH_KEY_EXPORT void InitializeCrashKeys();
#if defined(UNIT_TEST) || defined(CRASH_CORE_COMMON_IMPLEMENTATION)
// Returns a value for the crash key named |key_name|. For Crashpad-based
// clients, this returns the first instance found of the name.
+// Note: In a component build, this will only retrieve crash keys for the
+// current component.
CRASH_KEY_EXPORT std::string GetCrashKeyValue(const std::string& key_name);
// Resets crash key state and, depending on the platform, de-initializes
diff --git a/chromium/components/crash/core/common/crash_key_crashpad.cc b/chromium/components/crash/core/common/crash_key_crashpad.cc
index 929392e56ec..c6b074897c5 100644
--- a/chromium/components/crash/core/common/crash_key_crashpad.cc
+++ b/chromium/components/crash/core/common/crash_key_crashpad.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
// NOTE: This file is only compiled when Crashpad is used as the crash
-// reproter.
+// reporter.
#include "components/crash/core/common/crash_key.h"
diff --git a/chromium/components/crash/core/common/crash_key_unittest.cc b/chromium/components/crash/core/common/crash_key_unittest.cc
index 466eb25513e..cb9ad9660d6 100644
--- a/chromium/components/crash/core/common/crash_key_unittest.cc
+++ b/chromium/components/crash/core/common/crash_key_unittest.cc
@@ -6,6 +6,7 @@
#include "base/debug/crash_logging.h"
#include "base/debug/stack_trace.h"
+#include "base/stl_util.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -35,7 +36,7 @@ TEST_F(CrashKeyStringTest, FormatStackTrace) {
0x0badbeef, 0x77778888, 0xabc, 0x000ddeeff, 0x12345678,
};
base::debug::StackTrace trace(reinterpret_cast<const void* const*>(addresses),
- arraysize(addresses));
+ base::size(addresses));
std::string too_small = internal::FormatStackTrace(trace, 3);
EXPECT_EQ(0u, too_small.size());
@@ -56,7 +57,7 @@ TEST_F(CrashKeyStringTest, FormatStackTrace64) {
0xbaaaabaaaaba, 0x1000000000000000,
};
base::debug::StackTrace trace(reinterpret_cast<const void* const*>(addresses),
- arraysize(addresses));
+ base::size(addresses));
std::string too_small = internal::FormatStackTrace(trace, 8);
EXPECT_EQ(0u, too_small.size());
diff --git a/chromium/components/crash/core/common/crash_keys.cc b/chromium/components/crash/core/common/crash_keys.cc
index bbb0af7cb05..6a3c9599b3d 100644
--- a/chromium/components/crash/core/common/crash_keys.cc
+++ b/chromium/components/crash/core/common/crash_keys.cc
@@ -10,6 +10,7 @@
#include "base/command_line.h"
#include "base/format_macros.h"
#include "base/no_destructor.h"
+#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
@@ -23,7 +24,7 @@ namespace crash_keys {
namespace {
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
// When using Crashpad, the crash reporting client ID is the responsibility of
// Crashpad. It is not set directly by Chrome. To make the metrics client ID
// available on the server, it's stored in a distinct key.
@@ -50,7 +51,7 @@ void SetMetricsClientIdFromGUID(const std::string& metrics_client_guid) {
}
void ClearMetricsClientId() {
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
// Crashpad always monitors for crashes, but doesn't upload them when
// crash reporting is disabled. The preference to upload crash reports is
// linked to the preference for metrics reporting. When metrics reporting is
@@ -130,7 +131,7 @@ static PrinterInfoKey printer_info_keys[] = {
ScopedPrinterInfo::ScopedPrinterInfo(base::StringPiece data) {
std::vector<base::StringPiece> info = base::SplitStringPiece(
data, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- for (size_t i = 0; i < arraysize(printer_info_keys); ++i) {
+ for (size_t i = 0; i < base::size(printer_info_keys); ++i) {
if (i < info.size())
printer_info_keys[i].Set(info[i]);
else