Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3564)

Unified Diff: chrome/app/breakpad_linuxish.cc

Issue 9960072: Upstream crash changes for android. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixes to gyp and a typo in breakpad_linuxish.cc Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/app/breakpad_linuxish.h ('k') | chrome/app/chrome_main_delegate.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/app/breakpad_linuxish.cc
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linuxish.cc
similarity index 87%
rename from chrome/app/breakpad_linux.cc
rename to chrome/app/breakpad_linuxish.cc
index 17b4e8ae989ac8900d55838a67be2717d5f18d23..f058ee1b5d6aa14f6037b5c4af9f2474aa4483b3 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.
« no previous file with comments | « chrome/app/breakpad_linuxish.h ('k') | chrome/app/chrome_main_delegate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698