Index: src/client/linux/log/log.cc |
diff --git a/src/client/linux/log/log.cc b/src/client/linux/log/log.cc |
index 186359139054177f85239d4a1e94304042c5fcbf..fc23aa6d528a57f067a4748d44ae881224f04ad5 100644 |
--- a/src/client/linux/log/log.cc |
+++ b/src/client/linux/log/log.cc |
@@ -31,15 +31,51 @@ |
#if defined(__ANDROID__) |
#include <android/log.h> |
+#include <dlfcn.h> |
#else |
#include "third_party/lss/linux_syscall_support.h" |
#endif |
namespace logger { |
+#if defined(__ANDROID__) |
+namespace { |
+ |
+// __android_log_buf_write() is not exported in the NDK and is being used by |
+// dynamic runtime linking. Its declaration is taken from Android's |
+// system/core/include/log/log.h. |
+using AndroidLogBufferWriteFunc = int (*)(int bufID, int prio, const char *tag, |
+ const char *text); |
+const int kAndroidCrashLogId = 4; // From LOG_ID_CRASH in log.h. |
+const char kAndroidLogTag[] = "google-breakpad"; |
+ |
+bool g_crash_log_initialized = false; |
+AndroidLogBufferWriteFunc g_android_log_buf_write = nullptr; |
+ |
+} // namespace |
+ |
+void initializeCrashLogWriter() { |
+ if (g_crash_log_initialized) |
+ return; |
+ g_android_log_buf_write = reinterpret_cast<AndroidLogBufferWriteFunc>( |
+ dlsym(RTLD_DEFAULT, "__android_log_buf_write")); |
+ g_crash_log_initialized = true; |
+} |
+ |
+int writeToCrashLog(const char* buf) { |
+ // Try writing to the crash log ring buffer. If not available, fall back to |
+ // the standard log buffer. |
+ if (g_android_log_buf_write) { |
+ return g_android_log_buf_write(kAndroidCrashLogId, ANDROID_LOG_FATAL, |
+ kAndroidLogTag, buf); |
+ } |
+ return __android_log_write(ANDROID_LOG_FATAL, kAndroidLogTag, buf); |
+} |
+#endif |
+ |
int write(const char* buf, size_t nbytes) { |
#if defined(__ANDROID__) |
- return __android_log_write(ANDROID_LOG_WARN, "google-breakpad", buf); |
+ return __android_log_write(ANDROID_LOG_WARN, kAndroidLogTag, buf); |
#else |
return sys_write(2, buf, nbytes); |
#endif |