summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcarlosvaldivia@google.com <carlosvaldivia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-10 18:34:44 +0000
committercarlosvaldivia@google.com <carlosvaldivia@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-10 18:34:44 +0000
commit01e77f96bbd03a13876ae6fb2cf684198d858094 (patch)
tree216b6a1f92975d90917ec51eef855733300001c4
parentea1be09912afaa22f7a31a0c08a3e99d8ad70147 (diff)
downloadchromium_src-01e77f96bbd03a13876ae6fb2cf684198d858094.zip
chromium_src-01e77f96bbd03a13876ae6fb2cf684198d858094.tar.gz
chromium_src-01e77f96bbd03a13876ae6fb2cf684198d858094.tar.bz2
Upstream Android native crash handling changes.
This is actulaly the second time. Revert "Revert 131404 - Upstream native crash handling changes for Android." This reverts commit 421df96aab6267e963ddff16c9f738aa903a2cba. Conflicts: chrome/browser/chrome_browser_main.cc BUG= TEST= Review URL: http://codereview.chromium.org/9967017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131593 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/android/build_info.cc66
-rw-r--r--base/android/build_info.h88
-rw-r--r--base/android/java/org/chromium/base/BuildInfo.java88
-rw-r--r--base/base.gyp2
-rw-r--r--base/base.gypi2
-rw-r--r--breakpad/breakpad.gyp151
-rw-r--r--build/filename_rules.gypi6
-rw-r--r--chrome/app/DEPS1
-rw-r--r--chrome/app/breakpad_linuxish.cc (renamed from chrome/app/breakpad_linux.cc)165
-rw-r--r--chrome/app/breakpad_linuxish.h (renamed from chrome/app/breakpad_linux.h)7
-rw-r--r--chrome/app/chrome_main_delegate.cc2
-rw-r--r--chrome/browser/chrome_browser_main_linux.cc2
-rw-r--r--chrome/browser/chrome_browser_main_x11.cc4
-rw-r--r--chrome/browser/chrome_content_browser_client.cc10
-rw-r--r--chrome/browser/chromeos/login/wizard_controller.cc2
-rw-r--r--chrome/browser/crash_handler_host_linuxish.cc (renamed from chrome/browser/crash_handler_host_linux.cc)17
-rw-r--r--chrome/browser/crash_handler_host_linuxish.h (renamed from chrome/browser/crash_handler_host_linux.h)16
-rw-r--r--chrome/browser/crash_handler_host_linuxish_stub.cc (renamed from chrome/browser/crash_handler_host_linux_stub.cc)4
-rw-r--r--chrome/browser/ui/gtk/first_run_dialog.cc2
-rw-r--r--chrome/chrome_browser.gypi14
-rw-r--r--chrome/common/logging_chrome_uitest.cc5
21 files changed, 598 insertions, 56 deletions
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
new file mode 100644
index 0000000..157ce42
--- /dev/null
+++ b/base/android/build_info.cc
@@ -0,0 +1,66 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/android/build_info.h"
+
+#include <string>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/logging.h"
+#include "base/memory/singleton.h"
+#include "jni/build_info_jni.h"
+
+namespace base {
+namespace android {
+
+BuildInfo::BuildInfo() {
+ JNIEnv* env = AttachCurrentThread();
+
+ // The const char* pointers initialized below will be owned by the
+ // resultant BuildInfo.
+ std::string device_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getDevice(env));
+ device_ = strdup(device_str.c_str());
+
+ std::string model_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getDeviceModel(env));
+ model_ = strdup(model_str.c_str());
+
+ std::string brand_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getBrand(env));
+ brand_ = strdup(brand_str.c_str());
+
+ std::string android_build_id_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getAndroidBuildId(env));
+ android_build_id_ = strdup(android_build_id_str.c_str());
+
+ std::string android_build_fp_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getAndroidBuildFingerprint(env));
+ android_build_fp_ = strdup(android_build_fp_str.c_str());
+
+ jobject app_context = GetApplicationContext();
+ std::string package_version_code_str =
+ ConvertJavaStringToUTF8(Java_BuildInfo_getPackageVersionCode(
+ env, app_context));
+ package_version_code_ = strdup(package_version_code_str.c_str());
+
+ std::string package_version_name_str =
+ ConvertJavaStringToUTF8(
+ Java_BuildInfo_getPackageVersionName(env, app_context));
+ package_version_name_ = strdup(package_version_name_str.c_str());
+}
+
+// static
+BuildInfo* BuildInfo::GetInstance() {
+ return Singleton<BuildInfo, LeakySingletonTraits<BuildInfo> >::get();
+}
+
+bool RegisterBuildInfo(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android
+} // namespace base
diff --git a/base/android/build_info.h b/base/android/build_info.h
new file mode 100644
index 0000000..95a0cf5
--- /dev/null
+++ b/base/android/build_info.h
@@ -0,0 +1,88 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BASE_ANDROID_BUILD_INFO_H_
+#define BASE_ANDROID_BUILD_INFO_H_
+
+#include <jni.h>
+
+#include <string>
+
+#include "base/memory/singleton.h"
+
+namespace base {
+namespace android {
+
+// BuildInfo is a singleton class that stores android build and device
+// information. It will be called from Android specific java code and gets used
+// primarily in crash reporting.
+class BuildInfo {
+ public:
+
+ ~BuildInfo() {}
+
+ // Static factory method for getting the singleton BuildInfo instance.
+ // Note that ownership is not conferred on the caller and the BuildInfo in
+ // question isn't actually freed until shutdown. This is ok because there
+ // should only be one instance of BuildInfo ever created.
+ static BuildInfo* GetInstance();
+
+ // Const char* is used instead of std::strings because these values must be
+ // available even if the process is in a crash state. Sadly
+ // std::string.c_str() doesn't guarantee that memory won't be allocated when
+ // it is called.
+ const char* device() const {
+ return device_;
+ }
+
+ const char* model() const {
+ return model_;
+ }
+
+ const char* brand() const {
+ return brand_;
+ }
+
+ const char* android_build_id() const {
+ return android_build_id_;
+ }
+
+ const char* android_build_fp() const {
+ return android_build_fp_;
+ }
+
+ const char* package_version_code() const {
+ return package_version_code_;
+ }
+
+ const char* package_version_name() const {
+ return package_version_name_;
+ }
+
+ private:
+ BuildInfo();
+
+ friend struct DefaultSingletonTraits<BuildInfo>;
+
+ // Const char* is used instead of std::strings because these values must be
+ // available even if the process is in a crash state. Sadly
+ // std::string.c_str() doesn't guarantee that memory won't be allocated when
+ // it is called.
+ char* device_;
+ char* model_;
+ char* brand_;
+ char* android_build_id_;
+ char* android_build_fp_;
+ char* package_version_code_;
+ char* package_version_name_;
+
+ DISALLOW_COPY_AND_ASSIGN(BuildInfo);
+};
+
+bool RegisterBuildInfo(JNIEnv* env);
+
+} // namespace android
+} // namespace base
+
+#endif // BASE_ANDROID_BUILD_INFO_H_
diff --git a/base/android/java/org/chromium/base/BuildInfo.java b/base/android/java/org/chromium/base/BuildInfo.java
new file mode 100644
index 0000000..75748ac
--- /dev/null
+++ b/base/android/java/org/chromium/base/BuildInfo.java
@@ -0,0 +1,88 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.base;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Build;
+import android.util.Log;
+
+/**
+ * BuildInfo is a utility class providing easy access to {@link PackageInfo}
+ * information. This is primarly of use for accessesing package information
+ * from native code.
+ */
+public class BuildInfo {
+ private static final String TAG = "BuildInfo";
+ private static final int MAX_FINGERPRINT_LENGTH = 128;
+
+ /**
+ * BuildInfo is a static utility class and therefore should'nt be
+ * instantiated.
+ */
+ private BuildInfo() {
+ }
+
+ @CalledByNative
+ public static String getDevice() {
+ return Build.DEVICE;
+ }
+
+ @CalledByNative
+ public static String getBrand() {
+ return Build.BRAND;
+ }
+
+ @CalledByNative
+ public static String getAndroidBuildId() {
+ return Build.ID;
+ }
+
+ /**
+ * @return The build fingerprint for the current Android install. The value is truncated to a
+ * 128 characters as this is used for crash and UMA reporting, which should avoid huge
+ * strings.
+ */
+ @CalledByNative
+ public static String getAndroidBuildFingerprint() {
+ return Build.FINGERPRINT.substring(
+ 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH));
+ }
+
+ @CalledByNative
+ public static String getDeviceModel() {
+ return Build.MODEL;
+ }
+
+ @CalledByNative
+ public static String getPackageVersionCode(Context context) {
+ String msg = "versionCode not available.";
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo pi = pm.getPackageInfo("com.android.chrome", 0);
+ msg = "" + pi.versionCode;
+ } catch (NameNotFoundException e) {
+ Log.d(TAG, msg);
+ }
+ return msg;
+
+ }
+
+ @CalledByNative
+ public static String getPackageVersionName(Context context) {
+ String msg = "versionName not available";
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo pi = pm.getPackageInfo("com.android.chrome", 0);
+ msg = pi.versionName;
+ } catch (NameNotFoundException e) {
+ Log.d(TAG, msg);
+ }
+ return msg;
+ }
+
+}
diff --git a/base/base.gyp b/base/base.gyp
index 4225f7e..c6058873 100644
--- a/base/base.gyp
+++ b/base/base.gyp
@@ -122,10 +122,12 @@
'action_name': 'generate_jni_headers',
'inputs': [
'android/jni_generator/jni_generator.py',
+ 'android/java/org/chromium/base/BuildInfo.java',
'android/java/org/chromium/base/PathUtils.java',
'android/java/org/chromium/base/SystemMessageHandler.java',
],
'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/base/jni/build_info_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/base/jni/path_utils_jni.h',
'<(SHARED_INTERMEDIATE_DIR)/base/jni/system_message_handler_jni.h',
],
diff --git a/base/base.gypi b/base/base.gypi
index facb472..48812a0 100644
--- a/base/base.gypi
+++ b/base/base.gypi
@@ -21,6 +21,8 @@
'third_party/nspr/prtime.h',
'third_party/nspr/prcpucfg_linux.h',
'third_party/xdg_mime/xdgmime.h',
+ 'android/build_info.cc',
+ 'android/build_info.h',
'android/scoped_java_ref.cc',
'android/scoped_java_ref.h',
'android/jni_android.cc',
diff --git a/breakpad/breakpad.gyp b/breakpad/breakpad.gyp
index ca561d8..6a666d8 100644
--- a/breakpad/breakpad.gyp
+++ b/breakpad/breakpad.gyp
@@ -217,12 +217,154 @@
},
],
}],
- [ 'OS=="linux"', {
+ [ 'OS=="linux" or OS=="android"', {
'conditions': [
+ ['OS=="android"', {
+ 'defines': [
+ '__ANDROID__',
+ ],
+ }],
# Tools needed for archiving build symbols.
['linux_breakpad==1', {
'targets': [
{
+ 'target_name': 'minidump_stackwalk',
+ 'type': 'executable',
+ 'toolsets': [ 'host', ],
+ # This uses the system libcurl, so don't use the default 32-bit
+ # compile flags when building on a 64-bit machine.
+ 'variables': {
+ 'host_arch': '<!(uname -m)',
+ },
+ 'conditions': [
+ ['host_arch=="x86_64"', {
+ 'cflags!': ['-m32', '-march=pentium4', '-msse2',
+ '-mfpmath=sse'],
+ 'ldflags!': ['-m32'],
+ 'cflags': ['-O2'],
+ 'include_dirs!': ['/usr/include32'],
+ }],
+ ],
+ 'include_dirs': [
+ 'src',
+ 'src/third_party',
+ '..',
+ ],
+ 'sources': [
+ 'src/google_breakpad/procesor/call_stack.h',
+ 'src/processor/minidump_stackwalk.cc',
+ 'src/processor/stackwalker.cc',
+ 'src/processor/stackwalker.h',
+ 'src/processor/basic_code_module.h',
+ 'src/processor/basic_code_modules.cc',
+ 'src/processor/basic_code_modules.h',
+ 'src/processor/basic_source_line_resolver.cc',
+ 'src/processor/basic_source_line_resolver.h',
+ 'src/processor/binarystream.cc',
+ 'src/processor/binarystream.h',
+ 'src/processor/call_stack.cc',
+ 'src/processor/cfi_frame_info.cc',
+ 'src/processor/cfi_frame_info.h',
+ 'src/processor/disassembler_x86.cc',
+ 'src/processor/disassembler_x86.h',
+ 'src/processor/exploitability.cc',
+ 'src/processor/exploitability.h',
+ 'src/processor/exploitability_win.cc',
+ 'src/processor/exploitability_win.h',
+ 'src/processor/logging.cc',
+ 'src/processor/logging.h',
+ 'src/processor/minidump.cc',
+ 'src/processor/minidump.h',
+ 'src/processor/minidump_processor.cc',
+ 'src/processor/minidump_processor.h',
+ 'src/processor/pathname_stripper.cc',
+ 'src/processor/pathname_stripper.h',
+ 'src/processor/process_state.cc',
+ 'src/processor/process_state.h',
+ 'src/processor/simple_symbol_supplier.cc',
+ 'src/processor/simple_symbol_supplier.h',
+ 'src/processor/source_line_resolver_base.cc',
+ 'src/processor/source_line_resolver_base.h',
+ 'src/processor/stackwalker.cc',
+ 'src/processor/stackwalker.h',
+ 'src/processor/stackwalker_amd64.cc',
+ 'src/processor/stackwalker_amd64.h',
+ 'src/processor/stackwalker_arm.cc',
+ 'src/processor/stackwalker_arm.h',
+ 'src/processor/stackwalker_ppc.cc',
+ 'src/processor/stackwalker_ppc.h',
+ 'src/processor/stackwalker_sparc.cc',
+ 'src/processor/stackwalker_sparc.h',
+ 'src/processor/stackwalker_x86.cc',
+ 'src/processor/stackwalker_x86.h',
+ 'src/processor/tokenize.cc',
+ 'src/processor/tokenize.h',
+ # libdisasm
+ 'src/third_party/libdisasm/ia32_implicit.c',
+ 'src/third_party/libdisasm/ia32_implicit.h',
+ 'src/third_party/libdisasm/ia32_insn.c',
+ 'src/third_party/libdisasm/ia32_insn.h',
+ 'src/third_party/libdisasm/ia32_invariant.c',
+ 'src/third_party/libdisasm/ia32_invariant.h',
+ 'src/third_party/libdisasm/ia32_modrm.c',
+ 'src/third_party/libdisasm/ia32_modrm.h',
+ 'src/third_party/libdisasm/ia32_opcode_tables.c',
+ 'src/third_party/libdisasm/ia32_opcode_tables.h',
+ 'src/third_party/libdisasm/ia32_operand.c',
+ 'src/third_party/libdisasm/ia32_operand.h',
+ 'src/third_party/libdisasm/ia32_reg.c',
+ 'src/third_party/libdisasm/ia32_reg.h',
+ 'src/third_party/libdisasm/ia32_settings.c',
+ 'src/third_party/libdisasm/ia32_settings.h',
+ 'src/third_party/libdisasm/libdis.h',
+ 'src/third_party/libdisasm/qword.h',
+ 'src/third_party/libdisasm/x86_disasm.c',
+ 'src/third_party/libdisasm/x86_format.c',
+ 'src/third_party/libdisasm/x86_imm.c',
+ 'src/third_party/libdisasm/x86_imm.h',
+ 'src/third_party/libdisasm/x86_insn.c',
+ 'src/third_party/libdisasm/x86_misc.c',
+ 'src/third_party/libdisasm/x86_operand_list.c',
+ 'src/third_party/libdisasm/x86_operand_list.h',
+ ],
+ },
+ {
+ 'target_name': 'minidump_dump',
+ 'type': 'executable',
+ 'toolsets': [ 'host', ],
+ # This uses the system libcurl, so don't use the default 32-bit
+ # compile flags when building on a 64-bit machine.
+ 'variables': {
+ 'host_arch': '<!(uname -m)',
+ },
+ 'conditions': [
+ ['host_arch=="x86_64"', {
+ 'cflags!': ['-m32', '-march=pentium4', '-msse2',
+ '-mfpmath=sse'],
+ 'ldflags!': ['-m32'],
+ 'cflags': ['-O2'],
+ 'include_dirs!': ['/usr/include32'],
+ }],
+ ],
+ 'sources': [
+ 'src/processor/minidump_dump.cc',
+ 'src/processor/basic_code_module.h',
+ 'src/processor/basic_code_modules.h',
+ 'src/processor/basic_code_modules.cc',
+ 'src/processor/logging.h',
+ 'src/processor/logging.cc',
+ 'src/processor/minidump.h',
+ 'src/processor/minidump.cc',
+ 'src/processor/pathname_stripper.h',
+ 'src/processor/pathname_stripper.cc',
+ ],
+ 'include_dirs': [
+ 'src',
+ 'src/third_party',
+ '..',
+ ],
+ },
+ {
'target_name': 'symupload',
'type': 'executable',
@@ -258,6 +400,7 @@
{
'target_name': 'dump_syms',
'type': 'executable',
+ 'toolsets': [ 'host' ],
# dwarf2reader.cc uses dynamic_cast. Because we don't typically
# don't support RTTI, we enable it for this single target. Since
@@ -358,6 +501,12 @@
['target_arch=="arm"', {
'cflags': ['-Wa,-mimplicit-it=always'],
}],
+ ['OS=="android"', {
+ 'sources!':[
+ 'src/common/linux/elf_core_dump.cc',
+ 'src/common/linux/elf_core_dump.h',
+ ],
+ }],
],
'link_settings': {
diff --git a/build/filename_rules.gypi b/build/filename_rules.gypi
index d5a5a65..162e9b2 100644
--- a/build/filename_rules.gypi
+++ b/build/filename_rules.gypi
@@ -29,6 +29,12 @@
['exclude', '(^|/)linux/'],
],
}],
+ ['OS!="android" and OS!="linux" and OS!="openbsd" and OS!="freebsd"', {
+ 'sources/': [
+ ['exclude', '_linuxish(_unittest)?\\.(h|cc)$'],
+ ['exclude', '(^|/)linuxish/'],
+ ],
+ }],
['OS!="android"', {
'sources/': [
['exclude', '_android(_unittest)?\\.cc$'],
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index 414df54..680eaa9 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -13,4 +13,5 @@ include_rules = [
"+policy", # For generated headers and source
"+sandbox",
"+tools/memory_watcher",
+ "+third_party/lss/linux_syscall_support.h",
]
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linuxish.cc
index 17b4e8ae..8d6556e 100644
--- a/chrome/app/breakpad_linux.cc
+++ b/chrome/app/breakpad_linuxish.cc
@@ -6,7 +6,7 @@
// calls when in seccomp mode.
#define SYS_SYSCALL_ENTRYPOINT "playground$syscallEntryPoint"
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#include <fcntl.h>
#include <poll.h>
@@ -42,7 +42,16 @@
#include "chrome/common/env_vars.h"
#include "chrome/common/logging_chrome.h"
#include "content/common/chrome_descriptors.h"
+
+#if defined(OS_ANDROID)
+#include <android/log.h>
+#include <sys/stat.h>
+#include "base/android/path_utils.h"
+#include "base/android/build_info.h"
+#include "third_party/lss/linux_syscall_support.h"
+#else
#include "seccompsandbox/linux_syscall_support.h"
+#endif
#ifndef PR_SET_PTRACER
#define PR_SET_PTRACER 0x59616d61
@@ -118,6 +127,35 @@ static void my_uint64tos(char* output, uint64_t i, unsigned i_len) {
output[index - 1] = '0' + (i % 10);
}
+#if defined(OS_ANDROID)
+static char* my_strncpy(char* dst, const char* src, size_t len) {
+ int i = len;
+ char* p = dst;
+ if (!dst || !src)
+ return dst;
+ while (i != 0 && *src != '\0') {
+ *p++ = *src++;
+ i--;
+ }
+ while (i != 0) {
+ *p++ = '\0';
+ i--;
+ }
+ return dst;
+}
+
+static char* my_strncat(char *dest, const char *src, size_t len) {
+ char *ret = dest;
+ while (*dest)
+ dest++;
+ while (len--)
+ if (!(*dest++ = *src++))
+ return ret;
+ *dest = 0;
+ return ret;
+}
+#endif
+
namespace {
// MIME substrings.
@@ -305,6 +343,14 @@ void DumpProcess() {
g_breakpad->WriteMinidump();
}
+size_t WriteLog(const char* buf, size_t nbytes) {
+#if defined(OS_ANDROID)
+ return __android_log_write(ANDROID_LOG_WARN, "google-breakpad", buf);
+#else
+ return sys_write(2, buf, nbytes)
+#endif
+}
+
} // namespace
void HandleCrashDump(const BreakpadInfo& info) {
@@ -314,13 +360,18 @@ void HandleCrashDump(const BreakpadInfo& info) {
const int dumpfd = sys_open(info.filename, O_RDONLY, 0);
if (dumpfd < 0) {
static const char msg[] = "Cannot upload crash dump: failed to open\n";
- sys_write(2, msg, sizeof(msg));
+ WriteLog(msg, sizeof(msg));
return;
}
+#if defined(OS_ANDROID)
+ struct stat st;
+ if (fstat(dumpfd, &st) != 0) {
+#else
struct kernel_stat st;
if (sys_fstat(dumpfd, &st) != 0) {
+#endif
static const char msg[] = "Cannot upload crash dump: stat failed\n";
- sys_write(2, msg, sizeof(msg));
+ WriteLog(msg, sizeof(msg));
IGNORE_RET(sys_close(dumpfd));
return;
}
@@ -330,7 +381,7 @@ void HandleCrashDump(const BreakpadInfo& info) {
uint8_t* dump_data = reinterpret_cast<uint8_t*>(allocator.Alloc(st.st_size));
if (!dump_data) {
static const char msg[] = "Cannot upload crash dump: cannot alloc\n";
- sys_write(2, msg, sizeof(msg));
+ WriteLog(msg, sizeof(msg));
IGNORE_RET(sys_close(dumpfd));
return;
}
@@ -345,7 +396,7 @@ void HandleCrashDump(const BreakpadInfo& info) {
if (ufd < 0) {
static const char msg[] = "Cannot upload crash dump because /dev/urandom"
" is missing\n";
- sys_write(2, msg, sizeof(msg) - 1);
+ WriteLog(msg, sizeof(msg) - 1);
return;
}
@@ -369,7 +420,7 @@ void HandleCrashDump(const BreakpadInfo& info) {
if (temp_file_fd < 0) {
static const char msg[] = "Failed to create temporary file in /tmp: "
"cannot upload crash dump\n";
- sys_write(2, msg, sizeof(msg) - 1);
+ WriteLog(msg, sizeof(msg) - 1);
IGNORE_RET(sys_close(ufd));
return;
}
@@ -377,7 +428,7 @@ void HandleCrashDump(const BreakpadInfo& info) {
temp_file_fd = sys_open(info.filename, O_WRONLY, 0600);
if (temp_file_fd < 0) {
static const char msg[] = "Failed to save crash dump: failed to open\n";
- sys_write(2, msg, sizeof(msg) - 1);
+ WriteLog(msg, sizeof(msg) - 1);
IGNORE_RET(sys_close(ufd));
return;
}
@@ -476,12 +527,27 @@ void HandleCrashDump(const BreakpadInfo& info) {
MimeWriter writer(temp_file_fd, mime_boundary);
{
-#if defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+ static const char chrome_product_msg[] = "Chrome_Android";
+#elif defined(OS_CHROMEOS)
static const char chrome_product_msg[] = "Chrome_ChromeOS";
#else // OS_LINUX
static const char chrome_product_msg[] = "Chrome_Linux";
#endif
+
+#if defined (OS_ANDROID)
+ base::android::BuildInfo* android_build_info =
+ base::android::BuildInfo::GetInstance();
+ static const char* version_msg =
+ android_build_info->package_version_code();
+ static const char android_build_id[] = "android_build_id";
+ static const char android_build_fp[] = "android_build_fp";
+ static const char device[] = "device";
+ static const char model[] = "model";
+ static const char brand[] = "brand";
+#else
static const char version_msg[] = PRODUCT_VERSION;
+#endif
writer.AddBoundary();
writer.AddPairString("prod", chrome_product_msg);
@@ -490,6 +556,28 @@ void HandleCrashDump(const BreakpadInfo& info) {
writer.AddBoundary();
writer.AddPairString("guid", info.guid);
writer.AddBoundary();
+ if (info.pid > 0) {
+ uint64_t pid_str_len = my_uint64_len(info.pid);
+ char* pid_buf = reinterpret_cast<char*>(allocator.Alloc(pid_str_len));
+ my_uint64tos(pid_buf, info.pid, pid_str_len);
+ writer.AddPairString("pid", pid_buf);
+ writer.AddBoundary();
+ }
+#if defined(OS_ANDROID)
+ // Addtional MIME blocks are added for logging on Android devices.
+ writer.AddPairString(
+ android_build_id, android_build_info->android_build_id());
+ writer.AddBoundary();
+ writer.AddPairString(
+ android_build_fp, android_build_info->android_build_fp());
+ writer.AddBoundary();
+ writer.AddPairString(device, android_build_info->device());
+ writer.AddBoundary();
+ writer.AddPairString(model, android_build_info->model());
+ writer.AddBoundary();
+ writer.AddPairString(brand, android_build_info->brand());
+ writer.AddBoundary();
+#endif
writer.Flush();
}
@@ -637,6 +725,36 @@ void HandleCrashDump(const BreakpadInfo& info) {
writer.Flush();
IGNORE_RET(sys_close(temp_file_fd));
+#if defined(OS_ANDROID)
+ uint64_t pid_str_len = my_uint64_len(info.pid);
+ char* pid_buf = reinterpret_cast<char*>(allocator.Alloc(pid_str_len));
+ my_uint64tos(pid_buf, info.pid, pid_str_len);
+
+ static const char* output_msg = "Output crash dump file:";
+ WriteLog(output_msg, my_strlen(output_msg));
+ unsigned filename_len = my_strlen(info.filename);
+ WriteLog(info.filename, filename_len);
+ // -1 because we won't need the null terminator on the original filename.
+ size_t done_filename_len = filename_len - 1 + pid_str_len;
+ char* done_filename = reinterpret_cast<char*>(
+ allocator.Alloc(done_filename_len));
+ // Rename the file such that the pid is the suffix in order to signal other
+ // processes that the minidump is complete. The advantage of using the pid as
+ // the suffix is that it is trivial to associate the minidump with the
+ // crashed process.
+ // Finally, note strncpy prevents null terminators from
+ // being copied. Pad the rest with 0's.
+ my_strncpy(done_filename, info.filename, done_filename_len);
+ // Append the suffix a null terminator should be added.
+ my_strncat(done_filename, pid_buf, pid_str_len);
+ // Rename the minidump file to signal that it is complete.
+ if (rename(info.filename, done_filename)) {
+ __android_log_write(ANDROID_LOG_WARN, "chromium", "Failed to rename:");
+ __android_log_write(ANDROID_LOG_WARN, "chromium", info.filename);
+ __android_log_write(ANDROID_LOG_WARN, "chromium", "to");
+ __android_log_write(ANDROID_LOG_WARN, "chromium", done_filename);
+ }
+#endif
if (!info.upload)
return;
@@ -718,7 +836,7 @@ void HandleCrashDump(const BreakpadInfo& info) {
execve(kWgetBinary, const_cast<char**>(args), environ);
static const char msg[] = "Cannot upload crash dump: cannot exec "
"/usr/bin/wget\n";
- sys_write(2, msg, sizeof(msg) - 1);
+ WriteLog(msg, sizeof(msg) - 1);
sys__exit(1);
}
@@ -748,9 +866,9 @@ void HandleCrashDump(const BreakpadInfo& info) {
// Write crash dump id to stderr.
id_buf[len] = 0;
static const char msg[] = "\nCrash dump id: ";
- sys_write(2, msg, sizeof(msg) - 1);
- sys_write(2, id_buf, my_strlen(id_buf));
- sys_write(2, "\n", 1);
+ WriteLog(msg, sizeof(msg) - 1);
+ WriteLog(id_buf, my_strlen(id_buf));
+ WriteLog("\n", 1);
// Write crash dump id to crash log as: seconds_since_epoch,crash_id
struct kernel_timeval tv;
@@ -825,6 +943,7 @@ static bool CrashDone(const char* dump_path,
info.upload = upload;
info.process_start_time = g_process_start_time;
info.oom_size = base::g_oom_size;
+ info.pid = 0;
HandleCrashDump(info);
return true;
}
@@ -837,6 +956,7 @@ static bool CrashDoneNoUpload(const char* dump_path,
return CrashDone(dump_path, minidump_id, false, succeeded);
}
+#if !defined(OS_ANDROID)
// Wrapper function, do not add more code here.
static bool CrashDoneUpload(const char* dump_path,
const char* minidump_id,
@@ -844,8 +964,9 @@ static bool CrashDoneUpload(const char* dump_path,
bool succeeded) {
return CrashDone(dump_path, minidump_id, true, succeeded);
}
+#endif
-void EnableCrashDumping(const bool unattended) {
+void EnableCrashDumping(bool unattended) {
g_is_crash_reporter_enabled = true;
FilePath tmp_path("/tmp");
@@ -860,8 +981,10 @@ void EnableCrashDumping(const bool unattended) {
g_crash_log_path = new char[crash_log_path_len];
strncpy(g_crash_log_path, logfile_str.c_str(), crash_log_path_len);
}
-
DCHECK(!g_breakpad);
+#if defined(OS_ANDROID)
+ unattended = true;
+#endif
if (unattended) {
g_breakpad = new google_breakpad::ExceptionHandler(
dumps_path.value().c_str(),
@@ -887,7 +1010,7 @@ static bool NonBrowserCrashHandler(const void* crash_context,
int fds[2] = { -1, -1 };
if (sys_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
static const char msg[] = "Failed to create socket for crash dumping.\n";
- sys_write(2, msg, sizeof(msg)-1);
+ WriteLog(msg, sizeof(msg)-1);
return false;
}
@@ -964,7 +1087,7 @@ static bool NonBrowserCrashHandler(const void* crash_context,
if (HANDLE_EINTR(sys_sendmsg(fd, &msg, 0)) < 0) {
static const char errmsg[] = "Failed to tell parent about crash.\n";
- sys_write(2, errmsg, sizeof(errmsg)-1);
+ WriteLog(errmsg, sizeof(errmsg)-1);
IGNORE_RET(sys_close(fds[1]));
return false;
}
@@ -972,7 +1095,7 @@ static bool NonBrowserCrashHandler(const void* crash_context,
if (HANDLE_EINTR(sys_read(fds[0], &b, 1)) != 1) {
static const char errmsg[] = "Parent failed to complete crash dump.\n";
- sys_write(2, errmsg, sizeof(errmsg)-1);
+ WriteLog(errmsg, sizeof(errmsg)-1);
}
return true;
@@ -989,6 +1112,11 @@ void EnableNonBrowserCrashDumping() {
}
void InitCrashReporter() {
+#if defined(OS_ANDROID)
+ // This will guarantee that the BuildInfo has been initialized and subsequent
+ // calls will not require memory allocation.
+ base::android::BuildInfo::GetInstance();
+#endif
// Determine the process type and take appropriate action.
const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
if (parsed_command_line.HasSwitch(switches::kDisableBreakpad))
@@ -1003,6 +1131,9 @@ void InitCrashReporter() {
process_type == switches::kPpapiPluginProcess ||
process_type == switches::kZygoteProcess ||
process_type == switches::kGpuProcess) {
+#if defined(OS_ANDROID)
+ child_process_logging::SetClientId("Android");
+#endif
// We might be chrooted in a zygote or renderer process so we cannot call
// GetCollectStatsConsent because that needs access the the user's home
// dir. Instead, we set a command line flag for these processes.
diff --git a/chrome/app/breakpad_linux.h b/chrome/app/breakpad_linuxish.h
index 7c20514..9a7e2fd 100644
--- a/chrome/app/breakpad_linux.h
+++ b/chrome/app/breakpad_linuxish.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_APP_BREAKPAD_LINUX_H_
-#define CHROME_APP_BREAKPAD_LINUX_H_
+#ifndef CHROME_APP_BREAKPAD_LINUXISH_H_
+#define CHROME_APP_BREAKPAD_LINUXISH_H_
#pragma once
#include "base/basictypes.h"
@@ -28,8 +28,9 @@ struct BreakpadInfo {
bool upload; // Whether to upload or save crash dump.
uint64_t process_start_time; // Uptime of the crashing process.
size_t oom_size; // Amount of memory requested if OOM.
+ uint64_t pid; // PID where applicable.
};
extern void HandleCrashDump(const BreakpadInfo& info);
-#endif // CHROME_APP_BREAKPAD_LINUX_H_
+#endif // CHROME_APP_BREAKPAD_LINUXISH_H_
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 5a492d9..c03b310 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -89,7 +89,7 @@
#endif
#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#endif
base::LazyInstance<chrome::ChromeContentBrowserClient>
diff --git a/chrome/browser/chrome_browser_main_linux.cc b/chrome/browser/chrome_browser_main_linux.cc
index 2ba1b41..1354ffb 100644
--- a/chrome/browser/chrome_browser_main_linux.cc
+++ b/chrome/browser/chrome_browser_main_linux.cc
@@ -8,7 +8,7 @@
#include <stdlib.h>
#include "base/linux_util.h"
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/chrome_browser_main_x11.cc b/chrome/browser/chrome_browser_main_x11.cc
index 55968ca..fbd832f 100644
--- a/chrome/browser/chrome_browser_main_x11.cc
+++ b/chrome/browser/chrome_browser_main_x11.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,7 +15,7 @@
#include "ui/base/x/x11_util_internal.h"
#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#endif
using content::BrowserThread;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index d6c8557..b11823e 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -135,9 +135,9 @@
#include "chrome/browser/chrome_browser_main_extra_parts_ash.h"
#endif
-#if defined(OS_LINUX) || defined(OS_OPENBSD)
+#if defined(OS_LINUX) || defined(OS_OPENBSD) || defined(OS_ANDROID)
#include "base/linux_util.h"
-#include "chrome/browser/crash_handler_host_linux.h"
+#include "chrome/browser/crash_handler_host_linuxish.h"
#endif
#if defined(TOOLKIT_GTK)
@@ -1611,11 +1611,6 @@ bool ChromeContentBrowserClient::AllowSocketAPI(
#if defined(OS_POSIX) && !defined(OS_MACOSX)
int ChromeContentBrowserClient::GetCrashSignalFD(
const CommandLine& command_line) {
-#if defined(OS_ANDROID)
- // TODO(carlosvaldivia): Upstream breakpad code for Android and remove this
- // fork. http://crbug.com/113560
- NOTIMPLEMENTED();
-#else
if (command_line.HasSwitch(switches::kExtensionProcess)) {
ExtensionCrashHandlerHostLinux* crash_handler =
ExtensionCrashHandlerHostLinux::GetInstance();
@@ -1636,7 +1631,6 @@ int ChromeContentBrowserClient::GetCrashSignalFD(
if (process_type == switches::kGpuProcess)
return GpuCrashHandlerHostLinux::GetInstance()->GetDeathSignalSocket();
-#endif // defined(OS_ANDROID)
return -1;
}
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index d308b30..075e016 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -50,7 +50,7 @@
#include "ui/base/l10n/l10n_util.h"
#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#endif
using content::BrowserThread;
diff --git a/chrome/browser/crash_handler_host_linux.cc b/chrome/browser/crash_handler_host_linuxish.cc
index c385406..8b393fe 100644
--- a/chrome/browser/crash_handler_host_linux.cc
+++ b/chrome/browser/crash_handler_host_linuxish.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/crash_handler_host_linux.h"
+#include "chrome/browser/crash_handler_host_linuxish.h"
#include <stdint.h>
#include <stdlib.h>
@@ -27,11 +27,17 @@
#include "breakpad/src/client/linux/handler/exception_handler.h"
#include "breakpad/src/client/linux/minidump_writer/linux_dumper.h"
#include "breakpad/src/client/linux/minidump_writer/minidump_writer.h"
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/env_vars.h"
#include "content/public/browser/browser_thread.h"
+#if defined(OS_ANDROID)
+#include <sys/linux-syscalls.h>
+
+#define SYS_read __NR_read
+#endif
+
using content::BrowserThread;
using google_breakpad::ExceptionHandler;
@@ -318,8 +324,12 @@ void CrashHandlerHostLinux::OnFileCanReadWithoutBlocking(int fd) {
info->distro_length = strlen(distro);
info->distro = distro;
-
+#if defined(OS_ANDROID)
+ // Nothing gets uploaded in android.
+ info->upload = false;
+#else
info->upload = (getenv(env_vars::kHeadless) == NULL);
+#endif
info->process_start_time = uptime;
info->oom_size = oom_size;
@@ -361,6 +371,7 @@ void CrashHandlerHostLinux::WriteDumpFile(BreakpadInfo* info,
minidump_filename.copy(minidump_filename_str, minidump_filename.length());
minidump_filename_str[minidump_filename.length()] = '\0';
info->filename = minidump_filename_str;
+ info->pid = crashing_pid;
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
diff --git a/chrome/browser/crash_handler_host_linux.h b/chrome/browser/crash_handler_host_linuxish.h
index 55ef624..80c06d9 100644
--- a/chrome/browser/crash_handler_host_linux.h
+++ b/chrome/browser/crash_handler_host_linuxish.h
@@ -1,9 +1,9 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
-#define CHROME_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
+#ifndef CHROME_BROWSER_CRASH_HANDLER_HOST_LINUXISH_H_
+#define CHROME_BROWSER_CRASH_HANDLER_HOST_LINUXISH_H_
#pragma once
#include "base/compiler_specific.h"
@@ -26,11 +26,11 @@ class Thread;
template <typename T> struct DefaultSingletonTraits;
// This is the base class for singleton objects which crash dump renderers and
-// plugins on Linux. We perform the crash dump from the browser because it
-// allows us to be outside the sandbox.
+// plugins on Linux or Android. We perform the crash dump from the browser
+// because it allows us to be outside the sandbox.
//
-// PluginCrashHandlerHostLinux and RendererCrashHandlerHostLinux are singletons
-// that handle plugin and renderer crashes, respectively.
+// PluginCrashHandlerHostLinux and RendererCrashHandlerHostLinux are
+// singletons that handle plugin and renderer crashes, respectively.
//
// Processes signal that they need to be dumped by sending a datagram over a
// UNIX domain socket. All processes of the same type share the client end of
@@ -181,4 +181,4 @@ class RendererCrashHandlerHostLinux : public CrashHandlerHostLinux {
DISALLOW_COPY_AND_ASSIGN(RendererCrashHandlerHostLinux);
};
-#endif // CHROME_BROWSER_CRASH_HANDLER_HOST_LINUX_H_
+#endif // CHROME_BROWSER_CRASH_HANDLER_HOST_LINUXISH_H_
diff --git a/chrome/browser/crash_handler_host_linux_stub.cc b/chrome/browser/crash_handler_host_linuxish_stub.cc
index 8685846..8101c8f 100644
--- a/chrome/browser/crash_handler_host_linux_stub.cc
+++ b/chrome/browser/crash_handler_host_linuxish_stub.cc
@@ -1,11 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This is a stub file which is compiled in when we are building without
// breakpad support.
-#include "chrome/browser/crash_handler_host_linux.h"
+#include "chrome/browser/crash_handler_host_linuxish.h"
#include "base/memory/singleton.h"
diff --git a/chrome/browser/ui/gtk/first_run_dialog.cc b/chrome/browser/ui/gtk/first_run_dialog.cc
index f91b3d9..ddbbeff 100644
--- a/chrome/browser/ui/gtk/first_run_dialog.cc
+++ b/chrome/browser/ui/gtk/first_run_dialog.cc
@@ -29,7 +29,7 @@
#include "ui/base/resource/resource_bundle.h"
#if defined(USE_LINUX_BREAKPAD)
-#include "chrome/app/breakpad_linux.h"
+#include "chrome/app/breakpad_linuxish.h"
#endif
#if defined(GOOGLE_CHROME_BUILD)
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index e1a0cfa..9f155fe 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -931,7 +931,6 @@
'browser/content_settings/tab_specific_content_settings.h',
'browser/cookies_tree_model.cc',
'browser/cookies_tree_model.h',
- 'browser/crash_handler_host_linux.h',
'browser/crash_upload_list.cc',
'browser/crash_upload_list.h',
'browser/crash_upload_list_win.cc',
@@ -4340,12 +4339,15 @@
'-lXss',
],
},
+ }],
+ ['os_posix == 1 and OS != "mac"', {
+ 'sources': [ 'browser/crash_handler_host_linuxish.h', ],
'conditions': [
['linux_breakpad==1', {
'sources': [
- 'app/breakpad_linux.cc',
- 'app/breakpad_linux.h',
- 'browser/crash_handler_host_linux.cc',
+ 'app/breakpad_linuxish.cc',
+ 'app/breakpad_linuxish.h',
+ 'browser/crash_handler_host_linuxish.cc',
],
'dependencies': [
'../breakpad/breakpad.gyp:breakpad_client',
@@ -4353,13 +4355,13 @@
'common',
],
'include_dirs': [
- # breakpad_linux.cc uses generated file_version_info_linux.h.
+ # breakpad_linuxish.cc uses generated file_version_info_linux.h.
'<(SHARED_INTERMEDIATE_DIR)',
'../breakpad/src',
],
}, { # linux_breakpad==0
'sources': [
- 'browser/crash_handler_host_linux_stub.cc',
+ 'browser/crash_handler_host_linuxish_stub.cc',
],
}],
],
diff --git a/chrome/common/logging_chrome_uitest.cc b/chrome/common/logging_chrome_uitest.cc
index 8c87ff4..551fbd9 100644
--- a/chrome/common/logging_chrome_uitest.cc
+++ b/chrome/common/logging_chrome_uitest.cc
@@ -66,7 +66,8 @@ TEST_F(ChromeLoggingTest, EnvironmentLogFileName) {
RestoreEnvironmentVariable();
}
-#if defined(OS_LINUX) && (!defined(NDEBUG) || !defined(USE_LINUX_BREAKPAD))
+#if (defined(OS_LINUX) || defined(OS_ANDROID)) \
+ && (!defined(NDEBUG) || !defined(USE_LINUX_BREAKPAD))
// On Linux in Debug mode, Chrome generates a SIGTRAP.
// we do not catch SIGTRAPs, thus no crash dump.
// This also does not work if Breakpad is disabled.
@@ -149,7 +150,7 @@ class RendererCrashTest : public UITest {
}
};
-#if defined(OS_LINUX) && !defined(USE_LINUX_BREAKPAD)
+#if (defined(OS_LINUX) || defined(OS_ANDROID)) && !defined(USE_LINUX_BREAKPAD)
// On Linux, do not expect a crash dump if Breakpad is disabled.
#define EXPECTED_CRASH_CRASHES 0
#else