Index: chrome/app/breakpad_linux.cc |
diff --git a/chrome/app/breakpad_linux.cc b/chrome/app/breakpad_linux.cc |
index 705b9365cd10fea0fc16e545b8f5f3e127276f33..43841ece94af1b4f1d5c2b3257507b0555ebed8c 100644 |
--- a/chrome/app/breakpad_linux.cc |
+++ b/chrome/app/breakpad_linux.cc |
@@ -376,6 +376,38 @@ size_t WriteLog(const char* buf, size_t nbytes) { |
#endif |
} |
+#if defined(OS_ANDROID) |
+// Android's native crash handler outputs a diagnostic tombstone to the device |
+// log. By returning false from the HandlerCallbacks, breakpad will reinstall |
+// the previous (i.e. native) signal handlers before returning from its own |
+// handler. A Chrome build fingerprint is written to the log, so that the |
+// specific build of Chrome and the location of the archived Chrome symbols can |
+// be determined directly from it. |
+bool FinalizeCrashDoneAndroid() { |
+ base::android::BuildInfo* android_build_info = |
+ base::android::BuildInfo::GetInstance(); |
+ |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ "### ### ### ### ### ### ### ### ### ### ### ### ###"); |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ "Chrome build fingerprint:"); |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ android_build_info->package_version_name()); |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ android_build_info->package_version_code()); |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ CHROME_SYMBOLS_ID); |
+ __android_log_write(ANDROID_LOG_WARN, kGoogleBreakpad, |
+ "### ### ### ### ### ### ### ### ### ### ### ### ###"); |
+ return false; |
+} |
+ |
+bool CrashDoneNonBrowserAndroid(const MinidumpDescriptor& minidump, |
+ void* context, |
+ bool succeeded) { |
+ return FinalizeCrashDoneAndroid(); |
+} |
+#endif |
bool CrashDone(const MinidumpDescriptor& minidump, |
const bool upload, |
@@ -411,7 +443,11 @@ bool CrashDone(const MinidumpDescriptor& minidump, |
info.oom_size = base::g_oom_size; |
info.pid = 0; |
HandleCrashDump(info); |
+#if defined(OS_ANDROID) |
+ return FinalizeCrashDoneAndroid(); |
+#else |
return true; |
+#endif |
} |
// Wrapper function, do not add more code here. |
@@ -578,7 +614,14 @@ bool NonBrowserCrashHandler(const void* crash_context, |
WriteLog(errmsg, sizeof(errmsg)-1); |
} |
+#if defined(OS_ANDROID) |
+ // When false is returned, breakpad will continue to its minidump generator |
+ // and then to the HandlerCallback, which, in this case, is |
+ // CrashDoneNonBrowserAndroid(). |
+ return false; |
+#else |
return true; |
+#endif |
} |
void EnableNonBrowserCrashDumping() { |
@@ -586,10 +629,16 @@ void EnableNonBrowserCrashDumping() { |
g_is_crash_reporter_enabled = true; |
// We deliberately leak this object. |
DCHECK(!g_breakpad); |
+ |
+ ExceptionHandler::MinidumpCallback crash_done_callback = NULL; |
+#if defined(OS_ANDROID) |
+ crash_done_callback = CrashDoneNonBrowserAndroid; |
+#endif |
+ |
g_breakpad = new ExceptionHandler( |
MinidumpDescriptor("/tmp"), // Unused but needed or Breakpad will assert. |
NULL, |
- NULL, |
+ crash_done_callback, |
reinterpret_cast<void*>(fd), // Param passed to the crash handler. |
true, |
-1); |