1// Copyright (c) 2012 Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include "client/linux/log/log.h"
31
32#if defined(__ANDROID__)
33#include <android/log.h>
34#include <dlfcn.h>
35#else
36#include "third_party/lss/linux_syscall_support.h"
37#endif
38
39namespace logger {
40
41#if defined(__ANDROID__)
42namespace {
43
44// __android_log_buf_write() is not exported in the NDK and is being used by
45// dynamic runtime linking. Its declaration is taken from Android's
46// system/core/include/log/log.h.
47using AndroidLogBufferWriteFunc = int (*)(int bufID, int prio, const char* tag,
48 const char* text);
49const int kAndroidCrashLogId = 4; // From LOG_ID_CRASH in log.h.
50const char kAndroidLogTag[] = "google-breakpad";
51
52bool g_crash_log_initialized = false;
53AndroidLogBufferWriteFunc g_android_log_buf_write = nullptr;
54
55} // namespace
56
57void initializeCrashLogWriter() {
58 if (g_crash_log_initialized)
59 return;
60 g_android_log_buf_write = reinterpret_cast<AndroidLogBufferWriteFunc>(
61 dlsym(RTLD_DEFAULT, "__android_log_buf_write"));
62 g_crash_log_initialized = true;
63}
64
65int writeToCrashLog(const char* buf) {
66 // Try writing to the crash log ring buffer. If not available, fall back to
67 // the standard log buffer.
68 if (g_android_log_buf_write) {
69 return g_android_log_buf_write(kAndroidCrashLogId, ANDROID_LOG_FATAL,
70 kAndroidLogTag, buf);
71 }
72 return __android_log_write(ANDROID_LOG_FATAL, kAndroidLogTag, buf);
73}
74#endif
75
76int write(const char* buf, size_t nbytes) {
77#if defined(__ANDROID__)
78 return __android_log_write(ANDROID_LOG_WARN, kAndroidLogTag, buf);
79#else
80 return sys_write(2, buf, nbytes);
81#endif
82}
83
84} // namespace logger
85