blob: 1e9b59147b54fe33b54c728aba3f778f8cd7db28 [file] [log] [blame]
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001/*
Mark Salyzyne9c41962014-01-02 13:52:29 -08002 * Copyright (C) 2007-2014 The Android Open Source Project
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Mark Salyzyn154f4602014-02-20 14:59:07 -080016#include <errno.h>
17#include <fcntl.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080018#ifdef HAVE_PTHREADS
19#include <pthread.h>
20#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080021#include <stdarg.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080022#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
Nick Kralevicha1703222013-03-15 09:45:12 -070025#include <sys/stat.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080026#include <sys/types.h>
27#if (FAKE_LOG_DEVICE == 0)
28#include <sys/socket.h>
29#include <sys/un.h>
30#endif
31#include <time.h>
32#include <unistd.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080033
Dan Albertc68fedc2014-08-18 17:29:34 -070034#ifdef __BIONIC__
35#include <android/set_abort_message.h>
36#endif
37
Colin Cross9227bd32013-07-23 16:59:20 -070038#include <log/logd.h>
Mark Salyzyn154f4602014-02-20 14:59:07 -080039#include <log/logger.h>
40#include <log/log_read.h>
41#include <private/android_filesystem_config.h>
Mark Salyzyn7a809402015-01-16 13:38:07 -080042#include <private/android_logger.h>
Mark Salyzyne9c41962014-01-02 13:52:29 -080043
Mark Salyzyncf4aa032013-11-22 07:54:30 -080044#define LOG_BUF_SIZE 1024
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080045
46#if FAKE_LOG_DEVICE
Mark Salyzyn154f4602014-02-20 14:59:07 -080047/* This will be defined when building for the host. */
Kristian Monsenb5a98902014-01-28 11:26:56 -080048#include "fake_log_device.h"
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080049#endif
50
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080051static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr);
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -080052static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = __write_to_log_init;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080053#ifdef HAVE_PTHREADS
54static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER;
55#endif
56
Mark Salyzyna04464a2014-04-30 08:50:53 -070057#ifndef __unused
58#define __unused __attribute__((__unused__))
59#endif
Kristian Monsenb5a98902014-01-28 11:26:56 -080060
Mark Salyzyn154f4602014-02-20 14:59:07 -080061#if FAKE_LOG_DEVICE
Mark Salyzyn99f47a92014-04-07 14:58:08 -070062static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1, -1, -1 };
Mark Salyzyna04464a2014-04-30 08:50:53 -070063#else
64static int logd_fd = -1;
Mark Salyzynd91ab582014-12-15 10:52:12 -080065static int pstore_fd = -1;
Mark Salyzyn154f4602014-02-20 14:59:07 -080066#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080067
68/*
69 * This is used by the C++ code to decide if it should write logs through
Mark Salyzyn154f4602014-02-20 14:59:07 -080070 * the C code. Basically, if /dev/socket/logd is available, we're running in
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080071 * the simulator rather than a desktop tool and want to use the device.
72 */
73static enum {
Chris Pearson19299902010-06-02 16:25:35 -070074 kLogUninitialized, kLogNotAvailable, kLogAvailable
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080075} g_log_status = kLogUninitialized;
76int __android_log_dev_available(void)
77{
78 if (g_log_status == kLogUninitialized) {
Mark Salyzyn154f4602014-02-20 14:59:07 -080079 if (access("/dev/socket/logdw", W_OK) == 0)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080080 g_log_status = kLogAvailable;
81 else
82 g_log_status = kLogNotAvailable;
83 }
84
85 return (g_log_status == kLogAvailable);
86}
87
Mark Salyzyna04464a2014-04-30 08:50:53 -070088#if !FAKE_LOG_DEVICE
Mark Salyzyn8245af12014-03-25 13:45:33 -070089/* give up, resources too limited */
Mark Salyzyna04464a2014-04-30 08:50:53 -070090static int __write_to_log_null(log_id_t log_fd __unused, struct iovec *vec __unused,
91 size_t nr __unused)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080092{
93 return -1;
94}
Mark Salyzyna04464a2014-04-30 08:50:53 -070095#endif
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080096
Mark Salyzyn8245af12014-03-25 13:45:33 -070097/* log_init_lock assumed */
98static int __write_to_log_initialize()
99{
100 int i, ret = 0;
101
102#if FAKE_LOG_DEVICE
103 for (i = 0; i < LOG_ID_MAX; i++) {
104 char buf[sizeof("/dev/log_system")];
105 snprintf(buf, sizeof(buf), "/dev/log_%s", android_log_id_to_name(i));
106 log_fds[i] = fakeLogOpen(buf, O_WRONLY);
107 }
108#else
109 if (logd_fd >= 0) {
110 i = logd_fd;
111 logd_fd = -1;
112 close(i);
113 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800114 if (pstore_fd >= 0) {
115 i = pstore_fd;
116 pstore_fd = -1;
117 close(i);
118 }
119 pstore_fd = open("/dev/pmsg0", O_WRONLY);
Mark Salyzyn8245af12014-03-25 13:45:33 -0700120
Nick Kralevich118d1b32014-07-02 22:30:39 -0700121 i = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
Mark Salyzyn8245af12014-03-25 13:45:33 -0700122 if (i < 0) {
123 ret = -errno;
124 write_to_log = __write_to_log_null;
125 } else if (fcntl(i, F_SETFL, O_NONBLOCK) < 0) {
126 ret = -errno;
127 close(i);
128 i = -1;
129 write_to_log = __write_to_log_null;
130 } else {
131 struct sockaddr_un un;
132 memset(&un, 0, sizeof(struct sockaddr_un));
133 un.sun_family = AF_UNIX;
134 strcpy(un.sun_path, "/dev/socket/logdw");
135
136 if (connect(i, (struct sockaddr *)&un, sizeof(struct sockaddr_un)) < 0) {
137 ret = -errno;
138 close(i);
139 i = -1;
140 }
141 }
142 logd_fd = i;
143#endif
144
145 return ret;
146}
147
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800148static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
149{
150 ssize_t ret;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700151#if FAKE_LOG_DEVICE
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800152 int log_fd;
153
154 if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {
155 log_fd = log_fds[(int)log_id];
156 } else {
Mark Salyzyn8245af12014-03-25 13:45:33 -0700157 return -EBADF;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800158 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800159 do {
Mark Salyzyn154f4602014-02-20 14:59:07 -0800160 ret = fakeLogWritev(log_fd, vec, nr);
Mark Salyzyn8245af12014-03-25 13:45:33 -0700161 if (ret < 0) {
162 ret = -errno;
163 }
164 } while (ret == -EINTR);
Mark Salyzyn154f4602014-02-20 14:59:07 -0800165#else
Mark Salyzynd91ab582014-12-15 10:52:12 -0800166 static const unsigned header_length = 2;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700167 struct iovec newVec[nr + header_length];
Mark Salyzynd91ab582014-12-15 10:52:12 -0800168 android_log_header_t header;
169 android_pmsg_log_header_t pmsg_header;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700170 struct timespec ts;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700171 size_t i, payload_size;
Mark Salyzyn076ba812014-05-29 17:53:41 -0700172 static uid_t last_uid = AID_ROOT; /* logd *always* starts up as AID_ROOT */
Mark Salyzynd91ab582014-12-15 10:52:12 -0800173 static pid_t last_pid = (pid_t) -1;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700174
Mark Salyzyn076ba812014-05-29 17:53:41 -0700175 if (last_uid == AID_ROOT) { /* have we called to get the UID yet? */
176 last_uid = getuid();
177 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800178 if (last_pid == (pid_t) -1) {
179 last_pid = getpid();
Mark Salyzyn154f4602014-02-20 14:59:07 -0800180 }
Mark Salyzynb992d0d2014-03-20 16:09:38 -0700181 /*
182 * struct {
Mark Salyzynd91ab582014-12-15 10:52:12 -0800183 * // whate we provire to pstore
184 * android_pmsg_log_header_t pmsg_header;
185 * // what we provide to socket
Mark Salyzyn7a809402015-01-16 13:38:07 -0800186 * android_log_header_t header;
Mark Salyzynb992d0d2014-03-20 16:09:38 -0700187 * // caller provides
188 * union {
189 * struct {
190 * char prio;
191 * char payload[];
192 * } string;
193 * struct {
194 * uint32_t tag
195 * char payload[];
196 * } binary;
197 * };
198 * };
199 */
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700200
Mark Salyzyn076ba812014-05-29 17:53:41 -0700201 clock_gettime(CLOCK_REALTIME, &ts);
Mark Salyzyn076ba812014-05-29 17:53:41 -0700202
Mark Salyzynd91ab582014-12-15 10:52:12 -0800203 pmsg_header.magic = LOGGER_MAGIC;
204 pmsg_header.len = sizeof(pmsg_header) + sizeof(header);
205 pmsg_header.uid = last_uid;
206 pmsg_header.pid = last_pid;
207
Mark Salyzyn7a809402015-01-16 13:38:07 -0800208 header.id = log_id;
209 header.tid = gettid();
210 header.realtime.tv_sec = ts.tv_sec;
211 header.realtime.tv_nsec = ts.tv_nsec;
Mark Salyzyn154f4602014-02-20 14:59:07 -0800212
Mark Salyzynd91ab582014-12-15 10:52:12 -0800213 newVec[0].iov_base = (unsigned char *) &pmsg_header;
214 newVec[0].iov_len = sizeof(pmsg_header);
215 newVec[1].iov_base = (unsigned char *) &header;
216 newVec[1].iov_len = sizeof(header);
Mark Salyzyn154f4602014-02-20 14:59:07 -0800217
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700218 for (payload_size = 0, i = header_length; i < nr + header_length; i++) {
219 newVec[i].iov_base = vec[i - header_length].iov_base;
220 payload_size += newVec[i].iov_len = vec[i - header_length].iov_len;
221
222 if (payload_size > LOGGER_ENTRY_MAX_PAYLOAD) {
223 newVec[i].iov_len -= payload_size - LOGGER_ENTRY_MAX_PAYLOAD;
224 if (newVec[i].iov_len) {
225 ++i;
226 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800227 payload_size = LOGGER_ENTRY_MAX_PAYLOAD;
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700228 break;
229 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800230 }
Mark Salyzynd91ab582014-12-15 10:52:12 -0800231 pmsg_header.len += payload_size;
232
233 if (pstore_fd >= 0) {
234 TEMP_FAILURE_RETRY(writev(pstore_fd, newVec, i));
235 }
236
237 if (last_uid == AID_LOGD) { /* logd, after initialization and priv drop */
238 /*
239 * ignore log messages we send to ourself (logd).
240 * Such log messages are often generated by libraries we depend on
241 * which use standard Android logging.
242 */
243 return 0;
244 }
245
246 if (logd_fd < 0) {
247 return -EBADF;
248 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800249
Mark Salyzyn8245af12014-03-25 13:45:33 -0700250 /*
251 * The write below could be lost, but will never block.
252 *
Mark Salyzynd91ab582014-12-15 10:52:12 -0800253 * To logd, we drop the pmsg_header
254 *
Mark Salyzyn8245af12014-03-25 13:45:33 -0700255 * ENOTCONN occurs if logd dies.
256 * EAGAIN occurs if logd is overloaded.
257 */
Mark Salyzynd91ab582014-12-15 10:52:12 -0800258 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
Mark Salyzyn8245af12014-03-25 13:45:33 -0700259 if (ret < 0) {
260 ret = -errno;
261 if (ret == -ENOTCONN) {
262#ifdef HAVE_PTHREADS
263 pthread_mutex_lock(&log_init_lock);
264#endif
265 ret = __write_to_log_initialize();
266#ifdef HAVE_PTHREADS
267 pthread_mutex_unlock(&log_init_lock);
268#endif
269
270 if (ret < 0) {
271 return ret;
272 }
273
Mark Salyzynd91ab582014-12-15 10:52:12 -0800274 ret = TEMP_FAILURE_RETRY(writev(logd_fd, newVec + 1, i - 1));
Mark Salyzyn8245af12014-03-25 13:45:33 -0700275 if (ret < 0) {
276 ret = -errno;
277 }
278 }
279 }
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700280
Mark Salyzyn7a809402015-01-16 13:38:07 -0800281 if (ret > (ssize_t)sizeof(header)) {
282 ret -= sizeof(header);
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700283 }
Mark Salyzyn154f4602014-02-20 14:59:07 -0800284#endif
Mark Salyzyn8444eb82014-04-24 09:43:23 -0700285
286 return ret;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800287}
288
Mark Salyzyn154f4602014-02-20 14:59:07 -0800289#if FAKE_LOG_DEVICE
290static const char *LOG_NAME[LOG_ID_MAX] = {
291 [LOG_ID_MAIN] = "main",
292 [LOG_ID_RADIO] = "radio",
293 [LOG_ID_EVENTS] = "events",
Mark Salyzyn99f47a92014-04-07 14:58:08 -0700294 [LOG_ID_SYSTEM] = "system",
295 [LOG_ID_CRASH] = "crash"
Mark Salyzyn154f4602014-02-20 14:59:07 -0800296};
297
Adam Lesinskia1ac84c2014-10-20 12:31:30 -0700298const char *android_log_id_to_name(log_id_t log_id)
Mark Salyzyn154f4602014-02-20 14:59:07 -0800299{
300 if (log_id >= LOG_ID_MAX) {
301 log_id = LOG_ID_MAIN;
302 }
303 return LOG_NAME[log_id];
304}
305#endif
306
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800307static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
308{
309#ifdef HAVE_PTHREADS
310 pthread_mutex_lock(&log_init_lock);
311#endif
312
313 if (write_to_log == __write_to_log_init) {
Mark Salyzyn8245af12014-03-25 13:45:33 -0700314 int ret;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800315
Mark Salyzyn8245af12014-03-25 13:45:33 -0700316 ret = __write_to_log_initialize();
317 if (ret < 0) {
318#ifdef HAVE_PTHREADS
319 pthread_mutex_unlock(&log_init_lock);
Mark Salyzyn154f4602014-02-20 14:59:07 -0800320#endif
Mark Salyzyn8245af12014-03-25 13:45:33 -0700321 return ret;
322 }
323
324 write_to_log = __write_to_log_kernel;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800325 }
326
327#ifdef HAVE_PTHREADS
328 pthread_mutex_unlock(&log_init_lock);
329#endif
330
331 return write_to_log(log_id, vec, nr);
332}
333
334int __android_log_write(int prio, const char *tag, const char *msg)
335{
336 struct iovec vec[3];
337 log_id_t log_id = LOG_ID_MAIN;
Wink Saville3761e962012-11-28 12:20:19 -0800338 char tmp_tag[32];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800339
340 if (!tag)
341 tag = "";
342
343 /* XXX: This needs to go! */
344 if (!strcmp(tag, "HTC_RIL") ||
John Michelaued7ccae2009-08-19 10:01:55 -0500345 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
Jeff Sharkey84dcf092012-08-13 11:27:30 -0700346 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800347 !strcmp(tag, "AT") ||
348 !strcmp(tag, "GSM") ||
Wink Saville89efdc92009-04-02 11:00:57 -0700349 !strcmp(tag, "STK") ||
350 !strcmp(tag, "CDMA") ||
351 !strcmp(tag, "PHONE") ||
Wink Saville3761e962012-11-28 12:20:19 -0800352 !strcmp(tag, "SMS")) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800353 log_id = LOG_ID_RADIO;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700354 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
Wink Saville3761e962012-11-28 12:20:19 -0800355 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
356 tag = tmp_tag;
357 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800358
Elliott Hughes26864bf2014-05-06 20:40:15 -0700359#if __BIONIC__
360 if (prio == ANDROID_LOG_FATAL) {
Dan Albertc68fedc2014-08-18 17:29:34 -0700361 android_set_abort_message(msg);
Elliott Hughes26864bf2014-05-06 20:40:15 -0700362 }
363#endif
364
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800365 vec[0].iov_base = (unsigned char *) &prio;
366 vec[0].iov_len = 1;
367 vec[1].iov_base = (void *) tag;
368 vec[1].iov_len = strlen(tag) + 1;
369 vec[2].iov_base = (void *) msg;
370 vec[2].iov_len = strlen(msg) + 1;
371
372 return write_to_log(log_id, vec, 3);
373}
374
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800375int __android_log_buf_write(int bufID, int prio, const char *tag, const char *msg)
376{
377 struct iovec vec[3];
Wink Saville3761e962012-11-28 12:20:19 -0800378 char tmp_tag[32];
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800379
380 if (!tag)
381 tag = "";
382
383 /* XXX: This needs to go! */
Wink Saville3761e962012-11-28 12:20:19 -0800384 if ((bufID != LOG_ID_RADIO) &&
385 (!strcmp(tag, "HTC_RIL") ||
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800386 !strncmp(tag, "RIL", 3) || /* Any log tag with "RIL" as the prefix */
Jeff Sharkey84dcf092012-08-13 11:27:30 -0700387 !strncmp(tag, "IMS", 3) || /* Any log tag with "IMS" as the prefix */
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800388 !strcmp(tag, "AT") ||
389 !strcmp(tag, "GSM") ||
390 !strcmp(tag, "STK") ||
391 !strcmp(tag, "CDMA") ||
392 !strcmp(tag, "PHONE") ||
Wink Saville3761e962012-11-28 12:20:19 -0800393 !strcmp(tag, "SMS"))) {
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800394 bufID = LOG_ID_RADIO;
Mark Salyzyn8245af12014-03-25 13:45:33 -0700395 /* Inform third party apps/ril/radio.. to use Rlog or RLOG */
Wink Saville3761e962012-11-28 12:20:19 -0800396 snprintf(tmp_tag, sizeof(tmp_tag), "use-Rlog/RLOG-%s", tag);
397 tag = tmp_tag;
398 }
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800399
400 vec[0].iov_base = (unsigned char *) &prio;
401 vec[0].iov_len = 1;
402 vec[1].iov_base = (void *) tag;
403 vec[1].iov_len = strlen(tag) + 1;
404 vec[2].iov_base = (void *) msg;
405 vec[2].iov_len = strlen(msg) + 1;
406
407 return write_to_log(bufID, vec, 3);
408}
409
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800410int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap)
411{
Chris Pearson19299902010-06-02 16:25:35 -0700412 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800413
414 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
415
416 return __android_log_write(prio, tag, buf);
417}
418
419int __android_log_print(int prio, const char *tag, const char *fmt, ...)
420{
421 va_list ap;
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800422 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800423
424 va_start(ap, fmt);
425 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
426 va_end(ap);
427
428 return __android_log_write(prio, tag, buf);
429}
430
Joe Onoratoe2bf2ea2010-03-01 09:11:54 -0800431int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...)
432{
433 va_list ap;
434 char buf[LOG_BUF_SIZE];
435
436 va_start(ap, fmt);
437 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
438 va_end(ap);
439
440 return __android_log_buf_write(bufID, prio, tag, buf);
441}
442
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800443void __android_log_assert(const char *cond, const char *tag,
Mark Salyzyncf4aa032013-11-22 07:54:30 -0800444 const char *fmt, ...)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800445{
Chris Pearson19299902010-06-02 16:25:35 -0700446 char buf[LOG_BUF_SIZE];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800447
Chris Pearson19299902010-06-02 16:25:35 -0700448 if (fmt) {
449 va_list ap;
450 va_start(ap, fmt);
451 vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
452 va_end(ap);
453 } else {
454 /* Msg not provided, log condition. N.B. Do not use cond directly as
455 * format string as it could contain spurious '%' syntax (e.g.
456 * "%d" in "blocks%devs == 0").
457 */
458 if (cond)
459 snprintf(buf, LOG_BUF_SIZE, "Assertion failed: %s", cond);
460 else
461 strcpy(buf, "Unspecified assertion failed");
462 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800463
464 __android_log_write(ANDROID_LOG_FATAL, tag, buf);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800465 __builtin_trap(); /* trap so we have a chance to debug the situation */
Elliott Hughesda6b2e22014-04-23 14:57:32 -0700466 /* NOTREACHED */
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800467}
468
469int __android_log_bwrite(int32_t tag, const void *payload, size_t len)
470{
471 struct iovec vec[2];
472
473 vec[0].iov_base = &tag;
474 vec[0].iov_len = sizeof(tag);
475 vec[1].iov_base = (void*)payload;
476 vec[1].iov_len = len;
477
478 return write_to_log(LOG_ID_EVENTS, vec, 2);
479}
480
481/*
482 * Like __android_log_bwrite, but takes the type as well. Doesn't work
483 * for the general case where we're generating lists of stuff, but very
484 * handy if we just want to dump an integer into the log.
485 */
486int __android_log_btwrite(int32_t tag, char type, const void *payload,
Mark Salyzyn154f4602014-02-20 14:59:07 -0800487 size_t len)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800488{
489 struct iovec vec[3];
490
491 vec[0].iov_base = &tag;
492 vec[0].iov_len = sizeof(tag);
493 vec[1].iov_base = &type;
494 vec[1].iov_len = sizeof(type);
495 vec[2].iov_base = (void*)payload;
496 vec[2].iov_len = len;
497
498 return write_to_log(LOG_ID_EVENTS, vec, 3);
499}
Nick Kralevich2a4d05a2014-07-01 10:57:16 -0700500
501/*
502 * Like __android_log_bwrite, but used for writing strings to the
503 * event log.
504 */
505int __android_log_bswrite(int32_t tag, const char *payload)
506{
507 struct iovec vec[4];
508 char type = EVENT_TYPE_STRING;
509 uint32_t len = strlen(payload);
510
511 vec[0].iov_base = &tag;
512 vec[0].iov_len = sizeof(tag);
513 vec[1].iov_base = &type;
514 vec[1].iov_len = sizeof(type);
515 vec[2].iov_base = &len;
516 vec[2].iov_len = sizeof(len);
517 vec[3].iov_base = (void*)payload;
518 vec[3].iov_len = len;
519
520 return write_to_log(LOG_ID_EVENTS, vec, 4);
521}