1 /*
2 * Copyright (C) 2013-2016 The Android Open Source Project
3 *
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 */
16
17 #include <fcntl.h>
18 #include <inttypes.h>
19 #include <semaphore.h>
20 #include <signal.h>
21 #include <string.h>
22 #include <sys/types.h>
23 #include <unistd.h>
24
25 #include <cutils/properties.h>
26 #include <gtest/gtest.h>
27 #include <log/log.h>
28 #include <log/logger.h>
29 #include <log/log_read.h>
30 #include <log/logprint.h>
31 #include <private/android_filesystem_config.h>
32 #include <private/android_logger.h>
33
34 // enhanced version of LOG_FAILURE_RETRY to add support for EAGAIN and
35 // non-syscall libs. Since we are only using this in the emergency of
36 // a signal to stuff a terminating code into the logs, we will spin rather
37 // than try a usleep.
38 #define LOG_FAILURE_RETRY(exp) ({ \
39 typeof (exp) _rc; \
40 do { \
41 _rc = (exp); \
42 } while (((_rc == -1) \
43 && ((errno == EINTR) \
44 || (errno == EAGAIN))) \
45 || (_rc == -EINTR) \
46 || (_rc == -EAGAIN)); \
47 _rc; })
48
TEST(liblog,__android_log_buf_print)49 TEST(liblog, __android_log_buf_print) {
50 EXPECT_LT(0, __android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_INFO,
51 "TEST__android_log_buf_print",
52 "radio"));
53 usleep(1000);
54 EXPECT_LT(0, __android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
55 "TEST__android_log_buf_print",
56 "system"));
57 usleep(1000);
58 EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
59 "TEST__android_log_buf_print",
60 "main"));
61 usleep(1000);
62 }
63
TEST(liblog,__android_log_buf_write)64 TEST(liblog, __android_log_buf_write) {
65 EXPECT_LT(0, __android_log_buf_write(LOG_ID_RADIO, ANDROID_LOG_INFO,
66 "TEST__android_log_buf_write",
67 "radio"));
68 usleep(1000);
69 EXPECT_LT(0, __android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
70 "TEST__android_log_buf_write",
71 "system"));
72 usleep(1000);
73 EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
74 "TEST__android_log_buf_write",
75 "main"));
76 usleep(1000);
77 }
78
TEST(liblog,__android_log_btwrite)79 TEST(liblog, __android_log_btwrite) {
80 int intBuf = 0xDEADBEEF;
81 EXPECT_LT(0, __android_log_btwrite(0,
82 EVENT_TYPE_INT,
83 &intBuf, sizeof(intBuf)));
84 long long longBuf = 0xDEADBEEFA55A5AA5;
85 EXPECT_LT(0, __android_log_btwrite(0,
86 EVENT_TYPE_LONG,
87 &longBuf, sizeof(longBuf)));
88 usleep(1000);
89 char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
90 EXPECT_LT(0, __android_log_btwrite(0,
91 EVENT_TYPE_STRING,
92 Buf, sizeof(Buf) - 1));
93 usleep(1000);
94 }
95
ConcurrentPrintFn(void * arg)96 static void* ConcurrentPrintFn(void *arg) {
97 int ret = __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
98 "TEST__android_log_print", "Concurrent %" PRIuPTR,
99 reinterpret_cast<uintptr_t>(arg));
100 return reinterpret_cast<void*>(ret);
101 }
102
103 #define NUM_CONCURRENT 64
104 #define _concurrent_name(a,n) a##__concurrent##n
105 #define concurrent_name(a,n) _concurrent_name(a,n)
106
TEST(liblog,concurrent_name (__android_log_buf_print,NUM_CONCURRENT))107 TEST(liblog, concurrent_name(__android_log_buf_print, NUM_CONCURRENT)) {
108 pthread_t t[NUM_CONCURRENT];
109 int i;
110 for (i=0; i < NUM_CONCURRENT; i++) {
111 ASSERT_EQ(0, pthread_create(&t[i], NULL,
112 ConcurrentPrintFn,
113 reinterpret_cast<void *>(i)));
114 }
115 int ret = 0;
116 for (i=0; i < NUM_CONCURRENT; i++) {
117 void* result;
118 ASSERT_EQ(0, pthread_join(t[i], &result));
119 int this_result = reinterpret_cast<uintptr_t>(result);
120 if ((0 == ret) && (0 != this_result)) {
121 ret = this_result;
122 }
123 }
124 ASSERT_LT(0, ret);
125 }
126
TEST(liblog,__android_log_btwrite__android_logger_list_read)127 TEST(liblog, __android_log_btwrite__android_logger_list_read) {
128 struct logger_list *logger_list;
129
130 pid_t pid = getpid();
131
132 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
133 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
134
135 // Check that we can close and reopen the logger
136 log_time ts(CLOCK_MONOTONIC);
137 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
138 __android_log_close();
139
140 log_time ts1(CLOCK_MONOTONIC);
141 ASSERT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
142 usleep(1000000);
143
144 int count = 0;
145 int second_count = 0;
146
147 for (;;) {
148 log_msg log_msg;
149 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
150 break;
151 }
152
153 ASSERT_EQ(log_msg.entry.pid, pid);
154
155 if ((log_msg.entry.len != (4 + 1 + 8))
156 || (log_msg.id() != LOG_ID_EVENTS)) {
157 continue;
158 }
159
160 char *eventData = log_msg.msg();
161
162 if (eventData[4] != EVENT_TYPE_LONG) {
163 continue;
164 }
165
166 log_time tx(eventData + 4 + 1);
167 if (ts == tx) {
168 ++count;
169 } else if (ts1 == tx) {
170 ++second_count;
171 }
172 }
173
174 EXPECT_EQ(1, count);
175 EXPECT_EQ(1, second_count);
176
177 android_logger_list_close(logger_list);
178 }
179
get4LE(const char * src)180 static inline int32_t get4LE(const char* src)
181 {
182 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
183 }
184
TEST(liblog,__android_log_bswrite)185 TEST(liblog, __android_log_bswrite) {
186 struct logger_list *logger_list;
187
188 pid_t pid = getpid();
189
190 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
191 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
192
193 static const char buffer[] = "Hello World";
194 log_time ts(android_log_clockid());
195
196 ASSERT_LT(0, __android_log_bswrite(0, buffer));
197 usleep(1000000);
198
199 int count = 0;
200
201 for (;;) {
202 log_msg log_msg;
203 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
204 break;
205 }
206
207 ASSERT_EQ(log_msg.entry.pid, pid);
208
209 if ((log_msg.entry.sec < (ts.tv_sec - 1))
210 || ((ts.tv_sec + 1) < log_msg.entry.sec)
211 || (log_msg.entry.len != (4 + 1 + 4 + sizeof(buffer) - 1))
212 || (log_msg.id() != LOG_ID_EVENTS)) {
213 continue;
214 }
215
216 char *eventData = log_msg.msg();
217
218 if (eventData[4] != EVENT_TYPE_STRING) {
219 continue;
220 }
221
222 int len = get4LE(eventData + 4 + 1);
223 if (len == (sizeof(buffer) - 1)) {
224 ++count;
225
226 AndroidLogFormat *logformat = android_log_format_new();
227 EXPECT_TRUE(NULL != logformat);
228 AndroidLogEntry entry;
229 char msgBuf[1024];
230 EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
231 &entry,
232 NULL,
233 msgBuf,
234 sizeof(msgBuf)));
235 fflush(stderr);
236 EXPECT_EQ(31, android_log_printLogLine(logformat, fileno(stderr), &entry));
237 android_log_format_free(logformat);
238 }
239 }
240
241 EXPECT_EQ(1, count);
242
243 android_logger_list_close(logger_list);
244 }
245
TEST(liblog,__android_log_bswrite__empty_string)246 TEST(liblog, __android_log_bswrite__empty_string) {
247 struct logger_list *logger_list;
248
249 pid_t pid = getpid();
250
251 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
252 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
253
254 static const char buffer[] = "";
255 log_time ts(android_log_clockid());
256
257 ASSERT_LT(0, __android_log_bswrite(0, buffer));
258 usleep(1000000);
259
260 int count = 0;
261
262 for (;;) {
263 log_msg log_msg;
264 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
265 break;
266 }
267
268 ASSERT_EQ(log_msg.entry.pid, pid);
269
270 if ((log_msg.entry.sec < (ts.tv_sec - 1))
271 || ((ts.tv_sec + 1) < log_msg.entry.sec)
272 || (log_msg.entry.len != (4 + 1 + 4))
273 || (log_msg.id() != LOG_ID_EVENTS)) {
274 continue;
275 }
276
277 char *eventData = log_msg.msg();
278
279 if (eventData[4] != EVENT_TYPE_STRING) {
280 continue;
281 }
282
283 int len = get4LE(eventData + 4 + 1);
284 if (len == 0) {
285 ++count;
286
287 AndroidLogFormat *logformat = android_log_format_new();
288 EXPECT_TRUE(NULL != logformat);
289 AndroidLogEntry entry;
290 char msgBuf[1024];
291 EXPECT_EQ(0, android_log_processBinaryLogBuffer(&log_msg.entry_v1,
292 &entry,
293 NULL,
294 msgBuf,
295 sizeof(msgBuf)));
296 fflush(stderr);
297 EXPECT_EQ(20, android_log_printLogLine(logformat, fileno(stderr), &entry));
298 android_log_format_free(logformat);
299 }
300 }
301
302 EXPECT_EQ(1, count);
303
304 android_logger_list_close(logger_list);
305 }
306
TEST(liblog,__security)307 TEST(liblog, __security) {
308 static const char persist_key[] = "persist.logd.security";
309 static const char readonly_key[] = "ro.device_owner";
310 static const char nothing_val[] = "_NOTHING_TO_SEE_HERE_";
311 char persist[PROP_VALUE_MAX];
312 char readonly[PROP_VALUE_MAX];
313
314 property_get(persist_key, persist, "");
315 property_get(readonly_key, readonly, nothing_val);
316
317 if (!strcmp(readonly, nothing_val)) {
318 EXPECT_FALSE(__android_log_security());
319 fprintf(stderr, "Warning, setting ro.device_owner to a domain\n");
320 property_set(readonly_key, "com.google.android.SecOps.DeviceOwner");
321 } else if (!strcasecmp(readonly, "false") || !readonly[0]) {
322 EXPECT_FALSE(__android_log_security());
323 return;
324 }
325
326 if (!strcasecmp(persist, "true")) {
327 EXPECT_TRUE(__android_log_security());
328 } else {
329 EXPECT_FALSE(__android_log_security());
330 }
331 property_set(persist_key, "TRUE");
332 EXPECT_TRUE(__android_log_security());
333 property_set(persist_key, "FALSE");
334 EXPECT_FALSE(__android_log_security());
335 property_set(persist_key, "true");
336 EXPECT_TRUE(__android_log_security());
337 property_set(persist_key, "false");
338 EXPECT_FALSE(__android_log_security());
339 property_set(persist_key, "");
340 EXPECT_FALSE(__android_log_security());
341 property_set(persist_key, persist);
342 }
343
TEST(liblog,__security_buffer)344 TEST(liblog, __security_buffer) {
345 struct logger_list *logger_list;
346 android_event_long_t buffer;
347
348 static const char persist_key[] = "persist.logd.security";
349 char persist[PROP_VALUE_MAX];
350 bool set_persist = false;
351 bool allow_security = false;
352
353 if (__android_log_security()) {
354 allow_security = true;
355 } else {
356 property_get(persist_key, persist, "");
357 if (strcasecmp(persist, "true")) {
358 property_set(persist_key, "TRUE");
359 if (__android_log_security()) {
360 allow_security = true;
361 set_persist = true;
362 } else {
363 property_set(persist_key, persist);
364 }
365 }
366 }
367
368 if (!allow_security) {
369 fprintf(stderr, "WARNING: "
370 "security buffer disabled, bypassing end-to-end test\n");
371
372 log_time ts(CLOCK_MONOTONIC);
373
374 buffer.type = EVENT_TYPE_LONG;
375 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
376
377 // expect failure!
378 ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
379
380 return;
381 }
382
383 /* Matches clientHasLogCredentials() in logd */
384 uid_t uid = getuid();
385 gid_t gid = getgid();
386 bool clientHasLogCredentials = true;
387 if ((uid != AID_SYSTEM) && (uid != AID_ROOT) && (uid != AID_LOG)
388 && (gid != AID_SYSTEM) && (gid != AID_ROOT) && (gid != AID_LOG)) {
389 uid_t euid = geteuid();
390 if ((euid != AID_SYSTEM) && (euid != AID_ROOT) && (euid != AID_LOG)) {
391 gid_t egid = getegid();
392 if ((egid != AID_SYSTEM) && (egid != AID_ROOT) && (egid != AID_LOG)) {
393 int num_groups = getgroups(0, NULL);
394 if (num_groups > 0) {
395 gid_t groups[num_groups];
396 num_groups = getgroups(num_groups, groups);
397 while (num_groups > 0) {
398 if (groups[num_groups - 1] == AID_LOG) {
399 break;
400 }
401 --num_groups;
402 }
403 }
404 if (num_groups <= 0) {
405 clientHasLogCredentials = false;
406 }
407 }
408 }
409 }
410 if (!clientHasLogCredentials) {
411 fprintf(stderr, "WARNING: "
412 "not in system context, bypassing end-to-end test\n");
413
414 log_time ts(CLOCK_MONOTONIC);
415
416 buffer.type = EVENT_TYPE_LONG;
417 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
418
419 // expect failure!
420 ASSERT_GE(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
421
422 return;
423 }
424
425 pid_t pid = getpid();
426
427 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
428 LOG_ID_SECURITY, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
429 1000, pid)));
430
431 log_time ts(CLOCK_MONOTONIC);
432
433 buffer.type = EVENT_TYPE_LONG;
434 buffer.data = *(static_cast<uint64_t *>((void *)&ts));
435
436 ASSERT_LT(0, __android_log_security_bwrite(0, &buffer, sizeof(buffer)));
437 usleep(1000000);
438
439 int count = 0;
440
441 for (;;) {
442 log_msg log_msg;
443 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
444 break;
445 }
446
447 ASSERT_EQ(log_msg.entry.pid, pid);
448
449 if ((log_msg.entry.len != (4 + 1 + 8))
450 || (log_msg.id() != LOG_ID_SECURITY)) {
451 continue;
452 }
453
454 char *eventData = log_msg.msg();
455
456 if (eventData[4] != EVENT_TYPE_LONG) {
457 continue;
458 }
459
460 log_time tx(eventData + 4 + 1);
461 if (ts == tx) {
462 ++count;
463 }
464 }
465
466 if (set_persist) {
467 property_set(persist_key, persist);
468 }
469
470 android_logger_list_close(logger_list);
471
472 bool clientHasSecurityCredentials = (uid == AID_SYSTEM) || (gid == AID_SYSTEM);
473 if (!clientHasSecurityCredentials) {
474 fprintf(stderr, "WARNING: "
475 "not system, content submitted but can not check end-to-end\n");
476 }
477 EXPECT_EQ(clientHasSecurityCredentials ? 1 : 0, count);
478
479 }
480
481 static unsigned signaled;
482 static log_time signal_time;
483
484 /*
485 * Strictly, we are not allowed to log messages in a signal context, but we
486 * do make an effort to keep the failure surface minimized, and this in-effect
487 * should catch any regressions in that effort. The odds of a logged message
488 * in a signal handler causing a lockup problem should be _very_ small.
489 */
caught_blocking_signal(int)490 static void caught_blocking_signal(int /*signum*/)
491 {
492 unsigned long long v = 0xDEADBEEFA55A0000ULL;
493
494 v += getpid() & 0xFFFF;
495
496 ++signaled;
497 if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
498 signal_time = log_time(CLOCK_MONOTONIC);
499 signal_time.tv_sec += 2;
500 }
501
502 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
503 }
504
505 // Fill in current process user and system time in 10ms increments
get_ticks(unsigned long long * uticks,unsigned long long * sticks)506 static void get_ticks(unsigned long long *uticks, unsigned long long *sticks)
507 {
508 *uticks = *sticks = 0;
509
510 pid_t pid = getpid();
511
512 char buffer[512];
513 snprintf(buffer, sizeof(buffer), "/proc/%u/stat", pid);
514
515 FILE *fp = fopen(buffer, "r");
516 if (!fp) {
517 return;
518 }
519
520 char *cp = fgets(buffer, sizeof(buffer), fp);
521 fclose(fp);
522 if (!cp) {
523 return;
524 }
525
526 pid_t d;
527 char s[sizeof(buffer)];
528 char c;
529 long long ll;
530 unsigned long long ull;
531
532 if (15 != sscanf(buffer,
533 "%d %s %c %lld %lld %lld %lld %lld %llu %llu %llu %llu %llu %llu %llu ",
534 &d, s, &c, &ll, &ll, &ll, &ll, &ll, &ull, &ull, &ull, &ull, &ull,
535 uticks, sticks)) {
536 *uticks = *sticks = 0;
537 }
538 }
539
TEST(liblog,android_logger_list_read__cpu_signal)540 TEST(liblog, android_logger_list_read__cpu_signal) {
541 struct logger_list *logger_list;
542 unsigned long long v = 0xDEADBEEFA55A0000ULL;
543
544 pid_t pid = getpid();
545
546 v += pid & 0xFFFF;
547
548 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
549 LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
550
551 int count = 0;
552
553 int signals = 0;
554
555 unsigned long long uticks_start;
556 unsigned long long sticks_start;
557 get_ticks(&uticks_start, &sticks_start);
558
559 const unsigned alarm_time = 10;
560
561 memset(&signal_time, 0, sizeof(signal_time));
562
563 signal(SIGALRM, caught_blocking_signal);
564 alarm(alarm_time);
565
566 signaled = 0;
567
568 do {
569 log_msg log_msg;
570 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
571 break;
572 }
573
574 alarm(alarm_time);
575
576 ++count;
577
578 ASSERT_EQ(log_msg.entry.pid, pid);
579
580 if ((log_msg.entry.len != (4 + 1 + 8))
581 || (log_msg.id() != LOG_ID_EVENTS)) {
582 continue;
583 }
584
585 char *eventData = log_msg.msg();
586
587 if (eventData[4] != EVENT_TYPE_LONG) {
588 continue;
589 }
590
591 unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
592 l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
593 l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
594 l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
595 l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
596 l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
597 l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
598 l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
599
600 if (l == v) {
601 ++signals;
602 break;
603 }
604 } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
605 alarm(0);
606 signal(SIGALRM, SIG_DFL);
607
608 EXPECT_LE(1, count);
609
610 EXPECT_EQ(1, signals);
611
612 android_logger_list_close(logger_list);
613
614 unsigned long long uticks_end;
615 unsigned long long sticks_end;
616 get_ticks(&uticks_end, &sticks_end);
617
618 // Less than 1% in either user or system time, or both
619 const unsigned long long one_percent_ticks = alarm_time;
620 unsigned long long user_ticks = uticks_end - uticks_start;
621 unsigned long long system_ticks = sticks_end - sticks_start;
622 EXPECT_GT(one_percent_ticks, user_ticks);
623 EXPECT_GT(one_percent_ticks, system_ticks);
624 EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
625 }
626
627 /*
628 * Strictly, we are not allowed to log messages in a signal context, the
629 * correct way to handle this is to ensure the messages are constructed in
630 * a thread; the signal handler should only unblock the thread.
631 */
632 static sem_t thread_trigger;
633
caught_blocking_thread(int)634 static void caught_blocking_thread(int /*signum*/)
635 {
636 sem_post(&thread_trigger);
637 }
638
running_thread(void *)639 static void *running_thread(void *) {
640 unsigned long long v = 0xDEADBEAFA55A0000ULL;
641
642 v += getpid() & 0xFFFF;
643
644 struct timespec timeout;
645 clock_gettime(CLOCK_REALTIME, &timeout);
646 timeout.tv_sec += 55;
647 sem_timedwait(&thread_trigger, &timeout);
648
649 ++signaled;
650 if ((signal_time.tv_sec == 0) && (signal_time.tv_nsec == 0)) {
651 signal_time = log_time(CLOCK_MONOTONIC);
652 signal_time.tv_sec += 2;
653 }
654
655 LOG_FAILURE_RETRY(__android_log_btwrite(0, EVENT_TYPE_LONG, &v, sizeof(v)));
656
657 return NULL;
658 }
659
start_thread()660 int start_thread()
661 {
662 sem_init(&thread_trigger, 0, 0);
663
664 pthread_attr_t attr;
665 if (pthread_attr_init(&attr)) {
666 return -1;
667 }
668
669 struct sched_param param;
670
671 memset(¶m, 0, sizeof(param));
672 pthread_attr_setschedparam(&attr, ¶m);
673 pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
674
675 if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) {
676 pthread_attr_destroy(&attr);
677 return -1;
678 }
679
680 pthread_t thread;
681 if (pthread_create(&thread, &attr, running_thread, NULL)) {
682 pthread_attr_destroy(&attr);
683 return -1;
684 }
685
686 pthread_attr_destroy(&attr);
687 return 0;
688 }
689
TEST(liblog,android_logger_list_read__cpu_thread)690 TEST(liblog, android_logger_list_read__cpu_thread) {
691 struct logger_list *logger_list;
692 unsigned long long v = 0xDEADBEAFA55A0000ULL;
693
694 pid_t pid = getpid();
695
696 v += pid & 0xFFFF;
697
698 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
699 LOG_ID_EVENTS, ANDROID_LOG_RDONLY, 1000, pid)));
700
701 int count = 0;
702
703 int signals = 0;
704
705 unsigned long long uticks_start;
706 unsigned long long sticks_start;
707 get_ticks(&uticks_start, &sticks_start);
708
709 const unsigned alarm_time = 10;
710
711 memset(&signal_time, 0, sizeof(signal_time));
712
713 signaled = 0;
714 EXPECT_EQ(0, start_thread());
715
716 signal(SIGALRM, caught_blocking_thread);
717 alarm(alarm_time);
718
719 do {
720 log_msg log_msg;
721 if (LOG_FAILURE_RETRY(android_logger_list_read(logger_list, &log_msg)) <= 0) {
722 break;
723 }
724
725 alarm(alarm_time);
726
727 ++count;
728
729 ASSERT_EQ(log_msg.entry.pid, pid);
730
731 if ((log_msg.entry.len != (4 + 1 + 8))
732 || (log_msg.id() != LOG_ID_EVENTS)) {
733 continue;
734 }
735
736 char *eventData = log_msg.msg();
737
738 if (eventData[4] != EVENT_TYPE_LONG) {
739 continue;
740 }
741
742 unsigned long long l = eventData[4 + 1 + 0] & 0xFF;
743 l |= (unsigned long long) (eventData[4 + 1 + 1] & 0xFF) << 8;
744 l |= (unsigned long long) (eventData[4 + 1 + 2] & 0xFF) << 16;
745 l |= (unsigned long long) (eventData[4 + 1 + 3] & 0xFF) << 24;
746 l |= (unsigned long long) (eventData[4 + 1 + 4] & 0xFF) << 32;
747 l |= (unsigned long long) (eventData[4 + 1 + 5] & 0xFF) << 40;
748 l |= (unsigned long long) (eventData[4 + 1 + 6] & 0xFF) << 48;
749 l |= (unsigned long long) (eventData[4 + 1 + 7] & 0xFF) << 56;
750
751 if (l == v) {
752 ++signals;
753 break;
754 }
755 } while (!signaled || (log_time(CLOCK_MONOTONIC) < signal_time));
756 alarm(0);
757 signal(SIGALRM, SIG_DFL);
758
759 EXPECT_LE(1, count);
760
761 EXPECT_EQ(1, signals);
762
763 android_logger_list_close(logger_list);
764
765 unsigned long long uticks_end;
766 unsigned long long sticks_end;
767 get_ticks(&uticks_end, &sticks_end);
768
769 // Less than 1% in either user or system time, or both
770 const unsigned long long one_percent_ticks = alarm_time;
771 unsigned long long user_ticks = uticks_end - uticks_start;
772 unsigned long long system_ticks = sticks_end - sticks_start;
773 EXPECT_GT(one_percent_ticks, user_ticks);
774 EXPECT_GT(one_percent_ticks, system_ticks);
775 EXPECT_GT(one_percent_ticks, user_ticks + system_ticks);
776 }
777
778 static const char max_payload_tag[] = "TEST_max_payload_XXXX";
779 #define SIZEOF_MAX_PAYLOAD_BUF (LOGGER_ENTRY_MAX_PAYLOAD - \
780 sizeof(max_payload_tag) - 1)
781 static const char max_payload_buf[] = "LEONATO\n\
782 I learn in this letter that Don Peter of Arragon\n\
783 comes this night to Messina\n\
784 MESSENGER\n\
785 He is very near by this: he was not three leagues off\n\
786 when I left him\n\
787 LEONATO\n\
788 How many gentlemen have you lost in this action?\n\
789 MESSENGER\n\
790 But few of any sort, and none of name\n\
791 LEONATO\n\
792 A victory is twice itself when the achiever brings\n\
793 home full numbers. I find here that Don Peter hath\n\
794 bestowed much honour on a young Florentine called Claudio\n\
795 MESSENGER\n\
796 Much deserved on his part and equally remembered by\n\
797 Don Pedro: he hath borne himself beyond the\n\
798 promise of his age, doing, in the figure of a lamb,\n\
799 the feats of a lion: he hath indeed better\n\
800 bettered expectation than you must expect of me to\n\
801 tell you how\n\
802 LEONATO\n\
803 He hath an uncle here in Messina will be very much\n\
804 glad of it.\n\
805 MESSENGER\n\
806 I have already delivered him letters, and there\n\
807 appears much joy in him; even so much that joy could\n\
808 not show itself modest enough without a badge of\n\
809 bitterness.\n\
810 LEONATO\n\
811 Did he break out into tears?\n\
812 MESSENGER\n\
813 In great measure.\n\
814 LEONATO\n\
815 A kind overflow of kindness: there are no faces\n\
816 truer than those that are so washed. How much\n\
817 better is it to weep at joy than to joy at weeping!\n\
818 BEATRICE\n\
819 I pray you, is Signior Mountanto returned from the\n\
820 wars or no?\n\
821 MESSENGER\n\
822 I know none of that name, lady: there was none such\n\
823 in the army of any sort.\n\
824 LEONATO\n\
825 What is he that you ask for, niece?\n\
826 HERO\n\
827 My cousin means Signior Benedick of Padua.\n\
828 MESSENGER\n\
829 O, he's returned; and as pleasant as ever he was.\n\
830 BEATRICE\n\
831 He set up his bills here in Messina and challenged\n\
832 Cupid at the flight; and my uncle's fool, reading\n\
833 the challenge, subscribed for Cupid, and challenged\n\
834 him at the bird-bolt. I pray you, how many hath he\n\
835 killed and eaten in these wars? But how many hath\n\
836 he killed? for indeed I promised to eat all of his killing.\n\
837 LEONATO\n\
838 Faith, niece, you tax Signior Benedick too much;\n\
839 but he'll be meet with you, I doubt it not.\n\
840 MESSENGER\n\
841 He hath done good service, lady, in these wars.\n\
842 BEATRICE\n\
843 You had musty victual, and he hath holp to eat it:\n\
844 he is a very valiant trencherman; he hath an\n\
845 excellent stomach.\n\
846 MESSENGER\n\
847 And a good soldier too, lady.\n\
848 BEATRICE\n\
849 And a good soldier to a lady: but what is he to a lord?\n\
850 MESSENGER\n\
851 A lord to a lord, a man to a man; stuffed with all\n\
852 honourable virtues.\n\
853 BEATRICE\n\
854 It is so, indeed; he is no less than a stuffed man:\n\
855 but for the stuffing,--well, we are all mortal.\n\
856 LEONATO\n\
857 You must not, sir, mistake my niece. There is a\n\
858 kind of merry war betwixt Signior Benedick and her:\n\
859 they never meet but there's a skirmish of wit\n\
860 between them.\n\
861 BEATRICE\n\
862 Alas! he gets nothing by that. In our last\n\
863 conflict four of his five wits went halting off, and\n\
864 now is the whole man governed with one: so that if\n\
865 he have wit enough to keep himself warm, let him\n\
866 bear it for a difference between himself and his\n\
867 horse; for it is all the wealth that he hath left,\n\
868 to be known a reasonable creature. Who is his\n\
869 companion now? He hath every month a new sworn brother.\n\
870 MESSENGER\n\
871 Is't possible?\n\
872 BEATRICE\n\
873 Very easily possible: he wears his faith but as\n\
874 the fashion of his hat; it ever changes with the\n\
875 next block.\n\
876 MESSENGER\n\
877 I see, lady, the gentleman is not in your books.\n\
878 BEATRICE\n\
879 No; an he were, I would burn my study. But, I pray\n\
880 you, who is his companion? Is there no young\n\
881 squarer now that will make a voyage with him to the devil?\n\
882 MESSENGER\n\
883 He is most in the company of the right noble Claudio.\n\
884 BEATRICE\n\
885 O Lord, he will hang upon him like a disease: he\n\
886 is sooner caught than the pestilence, and the taker\n\
887 runs presently mad. God help the noble Claudio! if\n\
888 he have caught the Benedick, it will cost him a\n\
889 thousand pound ere a' be cured.\n\
890 MESSENGER\n\
891 I will hold friends with you, lady.\n\
892 BEATRICE\n\
893 Do, good friend.\n\
894 LEONATO\n\
895 You will never run mad, niece.\n\
896 BEATRICE\n\
897 No, not till a hot January.\n\
898 MESSENGER\n\
899 Don Pedro is approached.\n\
900 Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\
901 \n\
902 DON PEDRO\n\
903 Good Signior Leonato, you are come to meet your\n\
904 trouble: the fashion of the world is to avoid\n\
905 cost, and you encounter it\n\
906 LEONATO\n\
907 Never came trouble to my house in the likeness of your grace,\n\
908 for trouble being gone, comfort should remain, but\n\
909 when you depart from me, sorrow abides and happiness\n\
910 takes his leave.";
911
TEST(liblog,max_payload)912 TEST(liblog, max_payload) {
913 pid_t pid = getpid();
914 char tag[sizeof(max_payload_tag)];
915 memcpy(tag, max_payload_tag, sizeof(tag));
916 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
917
918 LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM, ANDROID_LOG_INFO,
919 tag, max_payload_buf));
920 sleep(2);
921
922 struct logger_list *logger_list;
923
924 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
925 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY, 100, 0)));
926
927 bool matches = false;
928 ssize_t max_len = 0;
929
930 for(;;) {
931 log_msg log_msg;
932 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
933 break;
934 }
935
936 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
937 continue;
938 }
939
940 char *data = log_msg.msg() + 1;
941
942 if (strcmp(data, tag)) {
943 continue;
944 }
945
946 data += strlen(data) + 1;
947
948 const char *left = data;
949 const char *right = max_payload_buf;
950 while (*left && *right && (*left == *right)) {
951 ++left;
952 ++right;
953 }
954
955 if (max_len <= (left - data)) {
956 max_len = left - data + 1;
957 }
958
959 if (max_len > 512) {
960 matches = true;
961 break;
962 }
963 }
964
965 android_logger_list_close(logger_list);
966
967 EXPECT_EQ(true, matches);
968
969 EXPECT_LE(SIZEOF_MAX_PAYLOAD_BUF, static_cast<size_t>(max_len));
970 }
971
TEST(liblog,__android_log_buf_print__maxtag)972 TEST(liblog, __android_log_buf_print__maxtag) {
973 struct logger_list *logger_list;
974
975 pid_t pid = getpid();
976
977 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
978 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
979
980 log_time ts(android_log_clockid());
981
982 EXPECT_LT(0, __android_log_buf_print(LOG_ID_MAIN, ANDROID_LOG_INFO,
983 max_payload_buf, max_payload_buf));
984 usleep(1000000);
985
986 int count = 0;
987
988 for (;;) {
989 log_msg log_msg;
990 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
991 break;
992 }
993
994 ASSERT_EQ(log_msg.entry.pid, pid);
995
996 if ((log_msg.entry.sec < (ts.tv_sec - 1))
997 || ((ts.tv_sec + 1) < log_msg.entry.sec)
998 || ((size_t)log_msg.entry.len < LOGGER_ENTRY_MAX_PAYLOAD)
999 || (log_msg.id() != LOG_ID_MAIN)) {
1000 continue;
1001 }
1002
1003 ++count;
1004
1005 AndroidLogFormat *logformat = android_log_format_new();
1006 EXPECT_TRUE(NULL != logformat);
1007 AndroidLogEntry entry;
1008 int processLogBuffer = android_log_processLogBuffer(&log_msg.entry_v1,
1009 &entry);
1010 EXPECT_EQ(0, processLogBuffer);
1011 if (processLogBuffer == 0) {
1012 fflush(stderr);
1013 int printLogLine =
1014 android_log_printLogLine(logformat, fileno(stderr), &entry);
1015 // Legacy tag truncation
1016 EXPECT_LE(128, printLogLine);
1017 // Measured maximum if we try to print part of the tag as message
1018 EXPECT_GT(LOGGER_ENTRY_MAX_PAYLOAD * 13 / 8, printLogLine);
1019 }
1020 android_log_format_free(logformat);
1021 }
1022
1023 EXPECT_EQ(1, count);
1024
1025 android_logger_list_close(logger_list);
1026 }
1027
TEST(liblog,too_big_payload)1028 TEST(liblog, too_big_payload) {
1029 pid_t pid = getpid();
1030 static const char big_payload_tag[] = "TEST_big_payload_XXXX";
1031 char tag[sizeof(big_payload_tag)];
1032 memcpy(tag, big_payload_tag, sizeof(tag));
1033 snprintf(tag + sizeof(tag) - 5, 5, "%04X", pid & 0xFFFF);
1034
1035 std::string longString(3266519, 'x');
1036
1037 ssize_t ret = LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_SYSTEM,
1038 ANDROID_LOG_INFO, tag, longString.c_str()));
1039
1040 struct logger_list *logger_list;
1041
1042 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1043 LOG_ID_SYSTEM, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 100, 0)));
1044
1045 ssize_t max_len = 0;
1046
1047 for(;;) {
1048 log_msg log_msg;
1049 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1050 break;
1051 }
1052
1053 if ((log_msg.entry.pid != pid) || (log_msg.id() != LOG_ID_SYSTEM)) {
1054 continue;
1055 }
1056
1057 char *data = log_msg.msg() + 1;
1058
1059 if (strcmp(data, tag)) {
1060 continue;
1061 }
1062
1063 data += strlen(data) + 1;
1064
1065 const char *left = data;
1066 const char *right = longString.c_str();
1067 while (*left && *right && (*left == *right)) {
1068 ++left;
1069 ++right;
1070 }
1071
1072 if (max_len <= (left - data)) {
1073 max_len = left - data + 1;
1074 }
1075 }
1076
1077 android_logger_list_close(logger_list);
1078
1079 EXPECT_LE(LOGGER_ENTRY_MAX_PAYLOAD - sizeof(big_payload_tag),
1080 static_cast<size_t>(max_len));
1081
1082 EXPECT_EQ(ret, max_len + static_cast<ssize_t>(sizeof(big_payload_tag)));
1083 }
1084
TEST(liblog,dual_reader)1085 TEST(liblog, dual_reader) {
1086 struct logger_list *logger_list1;
1087
1088 // >25 messages due to liblog.__android_log_buf_print__concurrentXX above.
1089 ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
1090 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 25, 0)));
1091
1092 struct logger_list *logger_list2;
1093
1094 if (NULL == (logger_list2 = android_logger_list_open(
1095 LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 15, 0))) {
1096 android_logger_list_close(logger_list1);
1097 ASSERT_TRUE(NULL != logger_list2);
1098 }
1099
1100 int count1 = 0;
1101 bool done1 = false;
1102 int count2 = 0;
1103 bool done2 = false;
1104
1105 do {
1106 log_msg log_msg;
1107
1108 if (!done1) {
1109 if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
1110 done1 = true;
1111 } else {
1112 ++count1;
1113 }
1114 }
1115
1116 if (!done2) {
1117 if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
1118 done2 = true;
1119 } else {
1120 ++count2;
1121 }
1122 }
1123 } while ((!done1) || (!done2));
1124
1125 android_logger_list_close(logger_list1);
1126 android_logger_list_close(logger_list2);
1127
1128 EXPECT_EQ(25, count1);
1129 EXPECT_EQ(15, count2);
1130 }
1131
TEST(liblog,android_logger_get_)1132 TEST(liblog, android_logger_get_) {
1133 struct logger_list * logger_list = android_logger_list_alloc(ANDROID_LOG_WRONLY, 0, 0);
1134
1135 for(int i = LOG_ID_MIN; i < LOG_ID_MAX; ++i) {
1136 log_id_t id = static_cast<log_id_t>(i);
1137 const char *name = android_log_id_to_name(id);
1138 if (id != android_name_to_log_id(name)) {
1139 continue;
1140 }
1141 fprintf(stderr, "log buffer %s\r", name);
1142 struct logger * logger;
1143 EXPECT_TRUE(NULL != (logger = android_logger_open(logger_list, id)));
1144 EXPECT_EQ(id, android_logger_get_id(logger));
1145 ssize_t get_log_size = android_logger_get_log_size(logger);
1146 /* security buffer is allowed to be denied */
1147 if (strcmp("security", name)) {
1148 EXPECT_LT(0, get_log_size);
1149 /* crash buffer is allowed to be empty, that is actually healthy! */
1150 EXPECT_LE((strcmp("crash", name)) != 0,
1151 android_logger_get_log_readable_size(logger));
1152 } else {
1153 EXPECT_NE(0, get_log_size);
1154 if (get_log_size < 0) {
1155 EXPECT_GT(0, android_logger_get_log_readable_size(logger));
1156 } else {
1157 EXPECT_LE(0, android_logger_get_log_readable_size(logger));
1158 }
1159 }
1160 EXPECT_LT(0, android_logger_get_log_version(logger));
1161 }
1162
1163 android_logger_list_close(logger_list);
1164 }
1165
checkPriForTag(AndroidLogFormat * p_format,const char * tag,android_LogPriority pri)1166 static bool checkPriForTag(AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) {
1167 return android_log_shouldPrintLine(p_format, tag, pri)
1168 && !android_log_shouldPrintLine(p_format, tag, (android_LogPriority)(pri - 1));
1169 }
1170
TEST(liblog,filterRule)1171 TEST(liblog, filterRule) {
1172 static const char tag[] = "random";
1173
1174 AndroidLogFormat *p_format = android_log_format_new();
1175
1176 android_log_addFilterRule(p_format,"*:i");
1177
1178 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1179 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1180 android_log_addFilterRule(p_format, "*");
1181 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1182 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1183 android_log_addFilterRule(p_format, "*:v");
1184 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1185 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1186 android_log_addFilterRule(p_format, "*:i");
1187 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_INFO));
1188 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1189
1190 android_log_addFilterRule(p_format, tag);
1191 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1192 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1193 android_log_addFilterRule(p_format, "random:v");
1194 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_VERBOSE));
1195 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1196 android_log_addFilterRule(p_format, "random:d");
1197 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1198 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0);
1199 android_log_addFilterRule(p_format, "random:w");
1200 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1201 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1202
1203 android_log_addFilterRule(p_format, "crap:*");
1204 EXPECT_TRUE (checkPriForTag(p_format, "crap", ANDROID_LOG_VERBOSE));
1205 EXPECT_TRUE(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0);
1206
1207 // invalid expression
1208 EXPECT_TRUE (android_log_addFilterRule(p_format, "random:z") < 0);
1209 EXPECT_TRUE (checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1210 EXPECT_TRUE(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0);
1211
1212 // Issue #550946
1213 EXPECT_TRUE(android_log_addFilterString(p_format, " ") == 0);
1214 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_WARN));
1215
1216 // note trailing space
1217 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:d ") == 0);
1218 EXPECT_TRUE(checkPriForTag(p_format, tag, ANDROID_LOG_DEBUG));
1219
1220 EXPECT_TRUE(android_log_addFilterString(p_format, "*:s random:z") < 0);
1221
1222 #if 0 // bitrot, seek update
1223 char defaultBuffer[512];
1224
1225 android_log_formatLogLine(p_format,
1226 defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123,
1227 123, 123, tag, "nofile", strlen("Hello"), "Hello", NULL);
1228
1229 fprintf(stderr, "%s\n", defaultBuffer);
1230 #endif
1231
1232 android_log_format_free(p_format);
1233 }
1234
TEST(liblog,is_loggable)1235 TEST(liblog, is_loggable) {
1236 static const char tag[] = "is_loggable";
1237 static const char log_namespace[] = "persist.log.tag.";
1238 static const size_t base_offset = 8; /* skip "persist." */
1239 // sizeof("string") = strlen("string") + 1
1240 char key[sizeof(log_namespace) + sizeof(tag) - 1];
1241 char hold[4][PROP_VALUE_MAX];
1242 static const struct {
1243 int level;
1244 char type;
1245 } levels[] = {
1246 { ANDROID_LOG_VERBOSE, 'v' },
1247 { ANDROID_LOG_DEBUG , 'd' },
1248 { ANDROID_LOG_INFO , 'i' },
1249 { ANDROID_LOG_WARN , 'w' },
1250 { ANDROID_LOG_ERROR , 'e' },
1251 { ANDROID_LOG_FATAL , 'a' },
1252 { -1 , 's' },
1253 { -2 , 'g' }, // Illegal value, resort to default
1254 };
1255
1256 // Set up initial test condition
1257 memset(hold, 0, sizeof(hold));
1258 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1259 property_get(key, hold[0], "");
1260 property_set(key, "");
1261 property_get(key + base_offset, hold[1], "");
1262 property_set(key + base_offset, "");
1263 strcpy(key, log_namespace);
1264 key[sizeof(log_namespace) - 2] = '\0';
1265 property_get(key, hold[2], "");
1266 property_set(key, "");
1267 property_get(key, hold[3], "");
1268 property_set(key + base_offset, "");
1269
1270 // All combinations of level and defaults
1271 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1272 if (levels[i].level == -2) {
1273 continue;
1274 }
1275 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1276 if (levels[j].level == -2) {
1277 continue;
1278 }
1279 fprintf(stderr, "i=%zu j=%zu\r", i, j);
1280 bool android_log_is_loggable = __android_log_is_loggable(
1281 levels[i].level, tag, levels[j].level);
1282 if ((levels[i].level < levels[j].level)
1283 || (levels[j].level == -1)) {
1284 if (android_log_is_loggable) {
1285 fprintf(stderr, "\n");
1286 }
1287 EXPECT_FALSE(android_log_is_loggable);
1288 for(size_t k = 10; k; --k) {
1289 EXPECT_FALSE(__android_log_is_loggable(
1290 levels[i].level, tag, levels[j].level));
1291 }
1292 } else {
1293 if (!android_log_is_loggable) {
1294 fprintf(stderr, "\n");
1295 }
1296 EXPECT_TRUE(android_log_is_loggable);
1297 for(size_t k = 10; k; --k) {
1298 EXPECT_TRUE(__android_log_is_loggable(
1299 levels[i].level, tag, levels[j].level));
1300 }
1301 }
1302 }
1303 }
1304
1305 // All combinations of level and tag and global properties
1306 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1307 if (levels[i].level == -2) {
1308 continue;
1309 }
1310 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1311 char buf[2];
1312 buf[0] = levels[j].type;
1313 buf[1] = '\0';
1314
1315 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1316 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1317 i, j, key, buf);
1318 property_set(key, buf);
1319 bool android_log_is_loggable = __android_log_is_loggable(
1320 levels[i].level, tag, ANDROID_LOG_DEBUG);
1321 if ((levels[i].level < levels[j].level)
1322 || (levels[j].level == -1)
1323 || ((levels[i].level < ANDROID_LOG_DEBUG)
1324 && (levels[j].level == -2))) {
1325 if (android_log_is_loggable) {
1326 fprintf(stderr, "\n");
1327 }
1328 EXPECT_FALSE(android_log_is_loggable);
1329 for(size_t k = 10; k; --k) {
1330 EXPECT_FALSE(__android_log_is_loggable(
1331 levels[i].level, tag, ANDROID_LOG_DEBUG));
1332 }
1333 } else {
1334 if (!android_log_is_loggable) {
1335 fprintf(stderr, "\n");
1336 }
1337 EXPECT_TRUE(android_log_is_loggable);
1338 for(size_t k = 10; k; --k) {
1339 EXPECT_TRUE(__android_log_is_loggable(
1340 levels[i].level, tag, ANDROID_LOG_DEBUG));
1341 }
1342 }
1343 property_set(key, "");
1344
1345 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1346 i, j, key + base_offset, buf);
1347 property_set(key + base_offset, buf);
1348 android_log_is_loggable = __android_log_is_loggable(
1349 levels[i].level, tag, ANDROID_LOG_DEBUG);
1350 if ((levels[i].level < levels[j].level)
1351 || (levels[j].level == -1)
1352 || ((levels[i].level < ANDROID_LOG_DEBUG)
1353 && (levels[j].level == -2))) {
1354 if (android_log_is_loggable) {
1355 fprintf(stderr, "\n");
1356 }
1357 EXPECT_FALSE(android_log_is_loggable);
1358 for(size_t k = 10; k; --k) {
1359 EXPECT_FALSE(__android_log_is_loggable(
1360 levels[i].level, tag, ANDROID_LOG_DEBUG));
1361 }
1362 } else {
1363 if (!android_log_is_loggable) {
1364 fprintf(stderr, "\n");
1365 }
1366 EXPECT_TRUE(android_log_is_loggable);
1367 for(size_t k = 10; k; --k) {
1368 EXPECT_TRUE(__android_log_is_loggable(
1369 levels[i].level, tag, ANDROID_LOG_DEBUG));
1370 }
1371 }
1372 property_set(key + base_offset, "");
1373
1374 strcpy(key, log_namespace);
1375 key[sizeof(log_namespace) - 2] = '\0';
1376 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1377 i, j, key, buf);
1378 property_set(key, buf);
1379 android_log_is_loggable = __android_log_is_loggable(
1380 levels[i].level, tag, ANDROID_LOG_DEBUG);
1381 if ((levels[i].level < levels[j].level)
1382 || (levels[j].level == -1)
1383 || ((levels[i].level < ANDROID_LOG_DEBUG)
1384 && (levels[j].level == -2))) {
1385 if (android_log_is_loggable) {
1386 fprintf(stderr, "\n");
1387 }
1388 EXPECT_FALSE(android_log_is_loggable);
1389 for(size_t k = 10; k; --k) {
1390 EXPECT_FALSE(__android_log_is_loggable(
1391 levels[i].level, tag, ANDROID_LOG_DEBUG));
1392 }
1393 } else {
1394 if (!android_log_is_loggable) {
1395 fprintf(stderr, "\n");
1396 }
1397 EXPECT_TRUE(android_log_is_loggable);
1398 for(size_t k = 10; k; --k) {
1399 EXPECT_TRUE(__android_log_is_loggable(
1400 levels[i].level, tag, ANDROID_LOG_DEBUG));
1401 }
1402 }
1403 property_set(key, "");
1404
1405 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1406 i, j, key + base_offset, buf);
1407 property_set(key + base_offset, buf);
1408 android_log_is_loggable = __android_log_is_loggable(
1409 levels[i].level, tag, ANDROID_LOG_DEBUG);
1410 if ((levels[i].level < levels[j].level)
1411 || (levels[j].level == -1)
1412 || ((levels[i].level < ANDROID_LOG_DEBUG)
1413 && (levels[j].level == -2))) {
1414 if (android_log_is_loggable) {
1415 fprintf(stderr, "\n");
1416 }
1417 EXPECT_FALSE(android_log_is_loggable);
1418 for(size_t k = 10; k; --k) {
1419 EXPECT_FALSE(__android_log_is_loggable(
1420 levels[i].level, tag, ANDROID_LOG_DEBUG));
1421 }
1422 } else {
1423 if (!android_log_is_loggable) {
1424 fprintf(stderr, "\n");
1425 }
1426 EXPECT_TRUE(android_log_is_loggable);
1427 for(size_t k = 10; k; --k) {
1428 EXPECT_TRUE(__android_log_is_loggable(
1429 levels[i].level, tag, ANDROID_LOG_DEBUG));
1430 }
1431 }
1432 property_set(key + base_offset, "");
1433 }
1434 }
1435
1436 // All combinations of level and tag properties, but with global set to INFO
1437 strcpy(key, log_namespace);
1438 key[sizeof(log_namespace) - 2] = '\0';
1439 property_set(key, "I");
1440 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1441 for(size_t i = 0; i < (sizeof(levels) / sizeof(levels[0])); ++i) {
1442 if (levels[i].level == -2) {
1443 continue;
1444 }
1445 for(size_t j = 0; j < (sizeof(levels) / sizeof(levels[0])); ++j) {
1446 char buf[2];
1447 buf[0] = levels[j].type;
1448 buf[1] = '\0';
1449
1450 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1451 i, j, key, buf);
1452 property_set(key, buf);
1453 bool android_log_is_loggable = __android_log_is_loggable(
1454 levels[i].level, tag, ANDROID_LOG_DEBUG);
1455 if ((levels[i].level < levels[j].level)
1456 || (levels[j].level == -1)
1457 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1458 && (levels[j].level == -2))) {
1459 if (android_log_is_loggable) {
1460 fprintf(stderr, "\n");
1461 }
1462 EXPECT_FALSE(android_log_is_loggable);
1463 for(size_t k = 10; k; --k) {
1464 EXPECT_FALSE(__android_log_is_loggable(
1465 levels[i].level, tag, ANDROID_LOG_DEBUG));
1466 }
1467 } else {
1468 if (!android_log_is_loggable) {
1469 fprintf(stderr, "\n");
1470 }
1471 EXPECT_TRUE(android_log_is_loggable);
1472 for(size_t k = 10; k; --k) {
1473 EXPECT_TRUE(__android_log_is_loggable(
1474 levels[i].level, tag, ANDROID_LOG_DEBUG));
1475 }
1476 }
1477 property_set(key, "");
1478
1479 fprintf(stderr, "i=%zu j=%zu property_set(\"%s\",\"%s\")\r",
1480 i, j, key + base_offset, buf);
1481 property_set(key + base_offset, buf);
1482 android_log_is_loggable = __android_log_is_loggable(
1483 levels[i].level, tag, ANDROID_LOG_DEBUG);
1484 if ((levels[i].level < levels[j].level)
1485 || (levels[j].level == -1)
1486 || ((levels[i].level < ANDROID_LOG_INFO) // Yes INFO
1487 && (levels[j].level == -2))) {
1488 if (android_log_is_loggable) {
1489 fprintf(stderr, "\n");
1490 }
1491 EXPECT_FALSE(android_log_is_loggable);
1492 for(size_t k = 10; k; --k) {
1493 EXPECT_FALSE(__android_log_is_loggable(
1494 levels[i].level, tag, ANDROID_LOG_DEBUG));
1495 }
1496 } else {
1497 if (!android_log_is_loggable) {
1498 fprintf(stderr, "\n");
1499 }
1500 EXPECT_TRUE(android_log_is_loggable);
1501 for(size_t k = 10; k; --k) {
1502 EXPECT_TRUE(__android_log_is_loggable(
1503 levels[i].level, tag, ANDROID_LOG_DEBUG));
1504 }
1505 }
1506 property_set(key + base_offset, "");
1507 }
1508 }
1509
1510 // reset parms
1511 snprintf(key, sizeof(key), "%s%s", log_namespace, tag);
1512 property_set(key, hold[0]);
1513 property_set(key + base_offset, hold[1]);
1514 strcpy(key, log_namespace);
1515 key[sizeof(log_namespace) - 2] = '\0';
1516 property_set(key, hold[2]);
1517 property_set(key + base_offset, hold[3]);
1518 }
1519
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__typical)1520 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__typical) {
1521 const int TAG = 123456781;
1522 const char SUBTAG[] = "test-subtag";
1523 const int UID = -1;
1524 const int DATA_LEN = 200;
1525 struct logger_list *logger_list;
1526
1527 pid_t pid = getpid();
1528
1529 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1530 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1531
1532 ASSERT_LT(0, android_errorWriteWithInfoLog(
1533 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1534
1535 sleep(2);
1536
1537 int count = 0;
1538
1539 for (;;) {
1540 log_msg log_msg;
1541 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1542 break;
1543 }
1544
1545 char *eventData = log_msg.msg();
1546
1547 // Tag
1548 int tag = get4LE(eventData);
1549 eventData += 4;
1550
1551 if (tag != TAG) {
1552 continue;
1553 }
1554
1555 // List type
1556 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1557 eventData++;
1558
1559 // Number of elements in list
1560 ASSERT_EQ(3, eventData[0]);
1561 eventData++;
1562
1563 // Element #1: string type for subtag
1564 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1565 eventData++;
1566
1567 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1568 eventData +=4;
1569
1570 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1571 continue;
1572 }
1573 eventData += strlen(SUBTAG);
1574
1575 // Element #2: int type for uid
1576 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1577 eventData++;
1578
1579 ASSERT_EQ(UID, get4LE(eventData));
1580 eventData += 4;
1581
1582 // Element #3: string type for data
1583 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1584 eventData++;
1585
1586 ASSERT_EQ(DATA_LEN, get4LE(eventData));
1587 eventData += 4;
1588
1589 if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1590 continue;
1591 }
1592
1593 ++count;
1594 }
1595
1596 EXPECT_EQ(1, count);
1597
1598 android_logger_list_close(logger_list);
1599 }
1600
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__data_too_large)1601 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__data_too_large) {
1602 const int TAG = 123456782;
1603 const char SUBTAG[] = "test-subtag";
1604 const int UID = -1;
1605 const int DATA_LEN = sizeof(max_payload_buf);
1606 struct logger_list *logger_list;
1607
1608 pid_t pid = getpid();
1609
1610 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1611 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1612
1613 ASSERT_LT(0, android_errorWriteWithInfoLog(
1614 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1615
1616 sleep(2);
1617
1618 int count = 0;
1619
1620 for (;;) {
1621 log_msg log_msg;
1622 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1623 break;
1624 }
1625
1626 char *eventData = log_msg.msg();
1627 char *original = eventData;
1628
1629 // Tag
1630 int tag = get4LE(eventData);
1631 eventData += 4;
1632
1633 if (tag != TAG) {
1634 continue;
1635 }
1636
1637 // List type
1638 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1639 eventData++;
1640
1641 // Number of elements in list
1642 ASSERT_EQ(3, eventData[0]);
1643 eventData++;
1644
1645 // Element #1: string type for subtag
1646 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1647 eventData++;
1648
1649 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1650 eventData +=4;
1651
1652 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1653 continue;
1654 }
1655 eventData += strlen(SUBTAG);
1656
1657 // Element #2: int type for uid
1658 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1659 eventData++;
1660
1661 ASSERT_EQ(UID, get4LE(eventData));
1662 eventData += 4;
1663
1664 // Element #3: string type for data
1665 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1666 eventData++;
1667
1668 size_t dataLen = get4LE(eventData);
1669 eventData += 4;
1670
1671 if (memcmp(max_payload_buf, eventData, dataLen)) {
1672 continue;
1673 }
1674 eventData += dataLen;
1675
1676 // 4 bytes for the tag, and max_payload_buf should be truncated.
1677 ASSERT_LE(4 + 512, eventData - original); // worst expectations
1678 ASSERT_GT(4 + DATA_LEN, eventData - original); // must be truncated
1679
1680 ++count;
1681 }
1682
1683 EXPECT_EQ(1, count);
1684
1685 android_logger_list_close(logger_list);
1686 }
1687
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__null_data)1688 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__null_data) {
1689 const int TAG = 123456783;
1690 const char SUBTAG[] = "test-subtag";
1691 const int UID = -1;
1692 const int DATA_LEN = 200;
1693 struct logger_list *logger_list;
1694
1695 pid_t pid = getpid();
1696
1697 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1698 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1699
1700 ASSERT_GT(0, android_errorWriteWithInfoLog(
1701 TAG, SUBTAG, UID, NULL, DATA_LEN));
1702
1703 sleep(2);
1704
1705 int count = 0;
1706
1707 for (;;) {
1708 log_msg log_msg;
1709 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1710 break;
1711 }
1712
1713 char *eventData = log_msg.msg();
1714
1715 // Tag
1716 int tag = get4LE(eventData);
1717 eventData += 4;
1718
1719 if (tag == TAG) {
1720 // This tag should not have been written because the data was null
1721 count++;
1722 break;
1723 }
1724 }
1725
1726 EXPECT_EQ(0, count);
1727
1728 android_logger_list_close(logger_list);
1729 }
1730
TEST(liblog,android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long)1731 TEST(liblog, android_errorWriteWithInfoLog__android_logger_list_read__subtag_too_long) {
1732 const int TAG = 123456784;
1733 const char SUBTAG[] = "abcdefghijklmnopqrstuvwxyz now i know my abc";
1734 const int UID = -1;
1735 const int DATA_LEN = 200;
1736 struct logger_list *logger_list;
1737
1738 pid_t pid = getpid();
1739
1740 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1741 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1742
1743 ASSERT_LT(0, android_errorWriteWithInfoLog(
1744 TAG, SUBTAG, UID, max_payload_buf, DATA_LEN));
1745
1746 sleep(2);
1747
1748 int count = 0;
1749
1750 for (;;) {
1751 log_msg log_msg;
1752 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1753 break;
1754 }
1755
1756 char *eventData = log_msg.msg();
1757
1758 // Tag
1759 int tag = get4LE(eventData);
1760 eventData += 4;
1761
1762 if (tag != TAG) {
1763 continue;
1764 }
1765
1766 // List type
1767 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1768 eventData++;
1769
1770 // Number of elements in list
1771 ASSERT_EQ(3, eventData[0]);
1772 eventData++;
1773
1774 // Element #1: string type for subtag
1775 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1776 eventData++;
1777
1778 // The subtag is longer than 32 and should be truncated to that.
1779 ASSERT_EQ(32, get4LE(eventData));
1780 eventData +=4;
1781
1782 if (memcmp(SUBTAG, eventData, 32)) {
1783 continue;
1784 }
1785 eventData += 32;
1786
1787 // Element #2: int type for uid
1788 ASSERT_EQ(EVENT_TYPE_INT, eventData[0]);
1789 eventData++;
1790
1791 ASSERT_EQ(UID, get4LE(eventData));
1792 eventData += 4;
1793
1794 // Element #3: string type for data
1795 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1796 eventData++;
1797
1798 ASSERT_EQ(DATA_LEN, get4LE(eventData));
1799 eventData += 4;
1800
1801 if (memcmp(max_payload_buf, eventData, DATA_LEN)) {
1802 continue;
1803 }
1804
1805 ++count;
1806 }
1807
1808 EXPECT_EQ(1, count);
1809
1810 android_logger_list_close(logger_list);
1811 }
1812
TEST(liblog,android_errorWriteLog__android_logger_list_read__success)1813 TEST(liblog, android_errorWriteLog__android_logger_list_read__success) {
1814 const int TAG = 123456785;
1815 const char SUBTAG[] = "test-subtag";
1816 struct logger_list *logger_list;
1817
1818 pid_t pid = getpid();
1819
1820 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1821 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1822
1823 ASSERT_LT(0, android_errorWriteLog(TAG, SUBTAG));
1824
1825 sleep(2);
1826
1827 int count = 0;
1828
1829 for (;;) {
1830 log_msg log_msg;
1831 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1832 break;
1833 }
1834
1835 char *eventData = log_msg.msg();
1836
1837 // Tag
1838 int tag = get4LE(eventData);
1839 eventData += 4;
1840
1841 if (tag != TAG) {
1842 continue;
1843 }
1844
1845 // List type
1846 ASSERT_EQ(EVENT_TYPE_LIST, eventData[0]);
1847 eventData++;
1848
1849 // Number of elements in list
1850 ASSERT_EQ(3, eventData[0]);
1851 eventData++;
1852
1853 // Element #1: string type for subtag
1854 ASSERT_EQ(EVENT_TYPE_STRING, eventData[0]);
1855 eventData++;
1856
1857 ASSERT_EQ((int) strlen(SUBTAG), get4LE(eventData));
1858 eventData +=4;
1859
1860 if (memcmp(SUBTAG, eventData, strlen(SUBTAG))) {
1861 continue;
1862 }
1863 ++count;
1864 }
1865
1866 EXPECT_EQ(1, count);
1867
1868 android_logger_list_close(logger_list);
1869 }
1870
TEST(liblog,android_errorWriteLog__android_logger_list_read__null_subtag)1871 TEST(liblog, android_errorWriteLog__android_logger_list_read__null_subtag) {
1872 const int TAG = 123456786;
1873 struct logger_list *logger_list;
1874
1875 pid_t pid = getpid();
1876
1877 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
1878 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
1879
1880 ASSERT_GT(0, android_errorWriteLog(TAG, NULL));
1881
1882 sleep(2);
1883
1884 int count = 0;
1885
1886 for (;;) {
1887 log_msg log_msg;
1888 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
1889 break;
1890 }
1891
1892 char *eventData = log_msg.msg();
1893
1894 // Tag
1895 int tag = get4LE(eventData);
1896 eventData += 4;
1897
1898 if (tag == TAG) {
1899 // This tag should not have been written because the data was null
1900 count++;
1901 break;
1902 }
1903 }
1904
1905 EXPECT_EQ(0, count);
1906
1907 android_logger_list_close(logger_list);
1908 }
1909
is_real_element(int type)1910 static int is_real_element(int type) {
1911 return ((type == EVENT_TYPE_INT) ||
1912 (type == EVENT_TYPE_LONG) ||
1913 (type == EVENT_TYPE_STRING) ||
1914 (type == EVENT_TYPE_FLOAT));
1915 }
1916
android_log_buffer_to_string(const char * msg,size_t len,char * strOut,size_t strOutLen)1917 int android_log_buffer_to_string(const char *msg, size_t len,
1918 char *strOut, size_t strOutLen) {
1919 android_log_context context = create_android_log_parser(msg, len);
1920 android_log_list_element elem;
1921 bool overflow = false;
1922 /* Reserve 1 byte for null terminator. */
1923 size_t origStrOutLen = strOutLen--;
1924
1925 if (!context) {
1926 return -EBADF;
1927 }
1928
1929 memset(&elem, 0, sizeof(elem));
1930
1931 size_t outCount;
1932
1933 do {
1934 elem = android_log_read_next(context);
1935 switch ((int)elem.type) {
1936 case EVENT_TYPE_LIST:
1937 if (strOutLen == 0) {
1938 overflow = true;
1939 } else {
1940 *strOut++ = '[';
1941 strOutLen--;
1942 }
1943 break;
1944
1945 case EVENT_TYPE_LIST_STOP:
1946 if (strOutLen == 0) {
1947 overflow = true;
1948 } else {
1949 *strOut++ = ']';
1950 strOutLen--;
1951 }
1952 break;
1953
1954 case EVENT_TYPE_INT:
1955 /*
1956 * snprintf also requires room for the null terminator, which
1957 * we don't care about but we have allocated enough room for
1958 * that
1959 */
1960 outCount = snprintf(strOut, strOutLen + 1,
1961 "%" PRId32, elem.data.int32);
1962 if (outCount <= strOutLen) {
1963 strOut += outCount;
1964 strOutLen -= outCount;
1965 } else {
1966 overflow = true;
1967 }
1968 break;
1969
1970 case EVENT_TYPE_LONG:
1971 /*
1972 * snprintf also requires room for the null terminator, which
1973 * we don't care about but we have allocated enough room for
1974 * that
1975 */
1976 outCount = snprintf(strOut, strOutLen + 1,
1977 "%" PRId64, elem.data.int64);
1978 if (outCount <= strOutLen) {
1979 strOut += outCount;
1980 strOutLen -= outCount;
1981 } else {
1982 overflow = true;
1983 }
1984 break;
1985
1986 case EVENT_TYPE_FLOAT:
1987 /*
1988 * snprintf also requires room for the null terminator, which
1989 * we don't care about but we have allocated enough room for
1990 * that
1991 */
1992 outCount = snprintf(strOut, strOutLen + 1, "%f", elem.data.float32);
1993 if (outCount <= strOutLen) {
1994 strOut += outCount;
1995 strOutLen -= outCount;
1996 } else {
1997 overflow = true;
1998 }
1999 break;
2000
2001 default:
2002 elem.complete = true;
2003 break;
2004
2005 case EVENT_TYPE_UNKNOWN:
2006 #if 0 // Ideal purity in the test, we want to complain about UNKNOWN showing up
2007 if (elem.complete) {
2008 break;
2009 }
2010 #endif
2011 elem.data.string = const_cast<char *>("<unknown>");
2012 elem.len = strlen(elem.data.string);
2013 /* FALLTHRU */
2014 case EVENT_TYPE_STRING:
2015 if (elem.len <= strOutLen) {
2016 memcpy(strOut, elem.data.string, elem.len);
2017 strOut += elem.len;
2018 strOutLen -= elem.len;
2019 } else if (strOutLen > 0) {
2020 /* copy what we can */
2021 memcpy(strOut, elem.data.string, strOutLen);
2022 strOut += strOutLen;
2023 strOutLen = 0;
2024 overflow = true;
2025 }
2026 break;
2027 }
2028
2029 if (elem.complete) {
2030 break;
2031 }
2032 /* Determine whether to put a comma or not. */
2033 if (!overflow && (is_real_element(elem.type) ||
2034 (elem.type == EVENT_TYPE_LIST_STOP))) {
2035 android_log_list_element next = android_log_peek_next(context);
2036 if (!next.complete && (is_real_element(next.type) ||
2037 (next.type == EVENT_TYPE_LIST))) {
2038 if (strOutLen == 0) {
2039 overflow = true;
2040 } else {
2041 *strOut++ = ',';
2042 strOutLen--;
2043 }
2044 }
2045 }
2046 } while ((elem.type != EVENT_TYPE_UNKNOWN) && !overflow && !elem.complete);
2047
2048 android_log_destroy(&context);
2049
2050 if (overflow) {
2051 if (strOutLen < origStrOutLen) {
2052 /* leave an indicator */
2053 *(strOut-1) = '!';
2054 } else {
2055 /* nothing was written at all */
2056 *strOut++ = '!';
2057 }
2058 }
2059 *strOut++ = '\0';
2060
2061 if ((elem.type == EVENT_TYPE_UNKNOWN) && !elem.complete) {
2062 fprintf(stderr, "Binary log entry conversion failed\n");
2063 return -EINVAL;
2064 }
2065
2066 return 0;
2067 }
2068
event_test_int32(uint32_t tag,size_t & expected_len)2069 static const char *event_test_int32(uint32_t tag, size_t &expected_len) {
2070 android_log_context ctx;
2071
2072 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2073 if (!ctx) {
2074 return NULL;
2075 }
2076 EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2077 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2078 EXPECT_LE(0, android_log_destroy(&ctx));
2079 EXPECT_TRUE(NULL == ctx);
2080
2081 expected_len = sizeof(uint32_t) +
2082 sizeof(uint8_t) + sizeof(uint32_t);
2083
2084 return "1076895760";
2085 }
2086
event_test_int64(uint32_t tag,size_t & expected_len)2087 static const char *event_test_int64(uint32_t tag, size_t &expected_len) {
2088 android_log_context ctx;
2089
2090 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2091 if (!ctx) {
2092 return NULL;
2093 }
2094 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2095 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2096 EXPECT_LE(0, android_log_destroy(&ctx));
2097 EXPECT_TRUE(NULL == ctx);
2098
2099 expected_len = sizeof(uint32_t) +
2100 sizeof(uint8_t) + sizeof(uint64_t);
2101
2102 return "-9191740941672636400";
2103 }
2104
event_test_list_int64(uint32_t tag,size_t & expected_len)2105 static const char *event_test_list_int64(uint32_t tag, size_t &expected_len) {
2106 android_log_context ctx;
2107
2108 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2109 if (!ctx) {
2110 return NULL;
2111 }
2112 EXPECT_LE(0, android_log_write_list_begin(ctx));
2113 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2114 EXPECT_LE(0, android_log_write_list_end(ctx));
2115 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2116 EXPECT_LE(0, android_log_destroy(&ctx));
2117 EXPECT_TRUE(NULL == ctx);
2118
2119 expected_len = sizeof(uint32_t) +
2120 sizeof(uint8_t) + sizeof(uint8_t) +
2121 sizeof(uint8_t) + sizeof(uint64_t);
2122
2123 return "[-9191740941672636400]";
2124 }
2125
event_test_simple_automagic_list(uint32_t tag,size_t & expected_len)2126 static const char *event_test_simple_automagic_list(uint32_t tag, size_t &expected_len) {
2127 android_log_context ctx;
2128
2129 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2130 if (!ctx) {
2131 return NULL;
2132 }
2133 // The convenience API where we allow a simple list to be
2134 // created without explicit begin or end calls.
2135 EXPECT_LE(0, android_log_write_int32(ctx, 0x40302010));
2136 EXPECT_LE(0, android_log_write_int64(ctx, 0x8070605040302010));
2137 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2138 EXPECT_LE(0, android_log_destroy(&ctx));
2139 EXPECT_TRUE(NULL == ctx);
2140
2141 expected_len = sizeof(uint32_t) +
2142 sizeof(uint8_t) + sizeof(uint8_t) +
2143 sizeof(uint8_t) + sizeof(uint32_t) +
2144 sizeof(uint8_t) + sizeof(uint64_t);
2145
2146 return "[1076895760,-9191740941672636400]";
2147 }
2148
event_test_list_empty(uint32_t tag,size_t & expected_len)2149 static const char *event_test_list_empty(uint32_t tag, size_t &expected_len) {
2150 android_log_context ctx;
2151
2152 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2153 if (!ctx) {
2154 return NULL;
2155 }
2156 EXPECT_LE(0, android_log_write_list_begin(ctx));
2157 EXPECT_LE(0, android_log_write_list_end(ctx));
2158 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2159 EXPECT_LE(0, android_log_destroy(&ctx));
2160 EXPECT_TRUE(NULL == ctx);
2161
2162 expected_len = sizeof(uint32_t) +
2163 sizeof(uint8_t) + sizeof(uint8_t);
2164
2165 return "[]";
2166 }
2167
event_test_complex_nested_list(uint32_t tag,size_t & expected_len)2168 static const char *event_test_complex_nested_list(uint32_t tag, size_t &expected_len) {
2169 android_log_context ctx;
2170
2171 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2172 if (!ctx) {
2173 return NULL;
2174 }
2175
2176 EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2177 EXPECT_LE(0, android_log_write_int32(ctx, 0x01020304));
2178 EXPECT_LE(0, android_log_write_int64(ctx, 0x0102030405060708));
2179 EXPECT_LE(0, android_log_write_string8(ctx, "Hello World"));
2180 EXPECT_LE(0, android_log_write_list_begin(ctx)); // [
2181 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2182 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2183 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2184 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2185 EXPECT_LE(0, android_log_write_list_end(ctx)); // ]
2186 EXPECT_LE(0, android_log_write_float32(ctx, 1.0102030405060708));
2187 EXPECT_LE(0, android_log_write_list_end(ctx)); // ]
2188
2189 //
2190 // This one checks for the automagic list creation because a list
2191 // begin and end was missing for it! This is actually an <oops> corner
2192 // case, and not the behavior we morally support. The automagic API is to
2193 // allow for a simple case of a series of objects in a single list. e.g.
2194 // int32,int32,int32,string -> [int32,int32,int32,string]
2195 //
2196 EXPECT_LE(0, android_log_write_string8(ctx, "dlroW olleH"));
2197
2198 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2199 EXPECT_LE(0, android_log_destroy(&ctx));
2200 EXPECT_TRUE(NULL == ctx);
2201
2202 expected_len = sizeof(uint32_t) +
2203 sizeof(uint8_t) + sizeof(uint8_t) +
2204 sizeof(uint8_t) + sizeof(uint8_t) +
2205 sizeof(uint8_t) + sizeof(uint32_t) +
2206 sizeof(uint8_t) + sizeof(uint64_t) +
2207 sizeof(uint8_t) + sizeof(uint32_t) +
2208 sizeof("Hello World") - 1 +
2209 sizeof(uint8_t) + sizeof(uint8_t) +
2210 4 * (sizeof(uint8_t) + sizeof(uint32_t)) +
2211 sizeof(uint8_t) + sizeof(uint32_t) +
2212 sizeof(uint8_t) + sizeof(uint32_t) +
2213 sizeof("dlroW olleH") - 1;
2214
2215 return "[[16909060,72623859790382856,Hello World,[1,2,3,4],1.010203],dlroW olleH]";
2216 }
2217
event_test_7_level_prefix(uint32_t tag,size_t & expected_len)2218 static const char *event_test_7_level_prefix(uint32_t tag, size_t &expected_len) {
2219 android_log_context ctx;
2220
2221 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2222 if (!ctx) {
2223 return NULL;
2224 }
2225 EXPECT_LE(0, android_log_write_list_begin(ctx));
2226 EXPECT_LE(0, android_log_write_list_begin(ctx));
2227 EXPECT_LE(0, android_log_write_list_begin(ctx));
2228 EXPECT_LE(0, android_log_write_list_begin(ctx));
2229 EXPECT_LE(0, android_log_write_list_begin(ctx));
2230 EXPECT_LE(0, android_log_write_list_begin(ctx));
2231 EXPECT_LE(0, android_log_write_list_begin(ctx));
2232 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2233 EXPECT_LE(0, android_log_write_list_end(ctx));
2234 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2235 EXPECT_LE(0, android_log_write_list_end(ctx));
2236 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2237 EXPECT_LE(0, android_log_write_list_end(ctx));
2238 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2239 EXPECT_LE(0, android_log_write_list_end(ctx));
2240 EXPECT_LE(0, android_log_write_int32(ctx, 5));
2241 EXPECT_LE(0, android_log_write_list_end(ctx));
2242 EXPECT_LE(0, android_log_write_int32(ctx, 6));
2243 EXPECT_LE(0, android_log_write_list_end(ctx));
2244 EXPECT_LE(0, android_log_write_int32(ctx, 7));
2245 EXPECT_LE(0, android_log_write_list_end(ctx));
2246 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2247 EXPECT_LE(0, android_log_destroy(&ctx));
2248 EXPECT_TRUE(NULL == ctx);
2249
2250 expected_len = sizeof(uint32_t) + 7 *
2251 (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2252
2253 return "[[[[[[[1],2],3],4],5],6],7]";
2254 }
2255
event_test_7_level_suffix(uint32_t tag,size_t & expected_len)2256 static const char *event_test_7_level_suffix(uint32_t tag, size_t &expected_len) {
2257 android_log_context ctx;
2258
2259 EXPECT_TRUE(NULL != (ctx = create_android_logger(tag)));
2260 if (!ctx) {
2261 return NULL;
2262 }
2263 EXPECT_LE(0, android_log_write_list_begin(ctx));
2264 EXPECT_LE(0, android_log_write_int32(ctx, 1));
2265 EXPECT_LE(0, android_log_write_list_begin(ctx));
2266 EXPECT_LE(0, android_log_write_int32(ctx, 2));
2267 EXPECT_LE(0, android_log_write_list_begin(ctx));
2268 EXPECT_LE(0, android_log_write_int32(ctx, 3));
2269 EXPECT_LE(0, android_log_write_list_begin(ctx));
2270 EXPECT_LE(0, android_log_write_int32(ctx, 4));
2271 EXPECT_LE(0, android_log_write_list_begin(ctx));
2272 EXPECT_LE(0, android_log_write_int32(ctx, 5));
2273 EXPECT_LE(0, android_log_write_list_begin(ctx));
2274 EXPECT_LE(0, android_log_write_int32(ctx, 6));
2275 EXPECT_LE(0, android_log_write_list_end(ctx));
2276 EXPECT_LE(0, android_log_write_list_end(ctx));
2277 EXPECT_LE(0, android_log_write_list_end(ctx));
2278 EXPECT_LE(0, android_log_write_list_end(ctx));
2279 EXPECT_LE(0, android_log_write_list_end(ctx));
2280 EXPECT_LE(0, android_log_write_list_end(ctx));
2281 EXPECT_LE(0, android_log_write_list(ctx, LOG_ID_EVENTS));
2282 EXPECT_LE(0, android_log_destroy(&ctx));
2283 EXPECT_TRUE(NULL == ctx);
2284
2285 expected_len = sizeof(uint32_t) + 6 *
2286 (sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint8_t) + sizeof(uint32_t));
2287
2288 return "[1,[2,[3,[4,[5,[6]]]]]]";
2289 }
2290
event_test_android_log_error_write(uint32_t tag,size_t & expected_len)2291 static const char *event_test_android_log_error_write(uint32_t tag, size_t &expected_len) {
2292 EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, "dlroW olleH", 11));
2293
2294 expected_len = sizeof(uint32_t) +
2295 sizeof(uint8_t) + sizeof(uint8_t) +
2296 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2297 sizeof(uint8_t) + sizeof(uint32_t) +
2298 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("dlroW olleH") - 1;
2299
2300 return "[Hello World,42,dlroW olleH]";
2301 }
2302
event_test_android_log_error_write_null(uint32_t tag,size_t & expected_len)2303 static const char *event_test_android_log_error_write_null(uint32_t tag, size_t &expected_len) {
2304 EXPECT_LE(0, __android_log_error_write(tag, "Hello World", 42, NULL, 0));
2305
2306 expected_len = sizeof(uint32_t) +
2307 sizeof(uint8_t) + sizeof(uint8_t) +
2308 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("Hello World") - 1 +
2309 sizeof(uint8_t) + sizeof(uint32_t) +
2310 sizeof(uint8_t) + sizeof(uint32_t) + sizeof("") - 1;
2311
2312 return "[Hello World,42,]";
2313 }
2314
2315 // make sure all user buffers are flushed
print_barrier()2316 static void print_barrier() {
2317 std::cout.flush();
2318 fflush(stdout);
2319 std::cerr.flush();
2320 fflush(stderr); // everything else is paranoia ...
2321 }
2322
create_android_logger(const char * (* fn)(uint32_t tag,size_t & expected_len))2323 static void create_android_logger(const char *(*fn)(uint32_t tag, size_t &expected_len)) {
2324 struct logger_list *logger_list;
2325
2326 pid_t pid = getpid();
2327
2328 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open(
2329 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
2330
2331 log_time ts(android_log_clockid());
2332
2333 size_t expected_len;
2334 const char *expected_string = (*fn)(1005, expected_len);
2335
2336 if (!expected_string) {
2337 android_logger_list_close(logger_list);
2338 return;
2339 }
2340
2341 usleep(1000000);
2342
2343 int count = 0;
2344
2345 for (;;) {
2346 log_msg log_msg;
2347 if (android_logger_list_read(logger_list, &log_msg) <= 0) {
2348 break;
2349 }
2350
2351 ASSERT_EQ(log_msg.entry.pid, pid);
2352
2353 if ((log_msg.entry.sec < (ts.tv_sec - 1))
2354 || ((ts.tv_sec + 1) < log_msg.entry.sec)
2355 || ((size_t)log_msg.entry.len != expected_len)
2356 || (log_msg.id() != LOG_ID_EVENTS)) {
2357 continue;
2358 }
2359
2360 char *eventData = log_msg.msg();
2361
2362 ++count;
2363
2364 AndroidLogFormat *logformat = android_log_format_new();
2365 EXPECT_TRUE(NULL != logformat);
2366 AndroidLogEntry entry;
2367 char msgBuf[1024];
2368 int processBinaryLogBuffer = android_log_processBinaryLogBuffer(
2369 &log_msg.entry_v1, &entry, NULL, msgBuf, sizeof(msgBuf));
2370 EXPECT_EQ(0, processBinaryLogBuffer);
2371 if (processBinaryLogBuffer == 0) {
2372 print_barrier();
2373 int printLogLine = android_log_printLogLine(
2374 logformat, fileno(stderr), &entry);
2375 print_barrier();
2376 EXPECT_EQ(20 + (int)strlen(expected_string), printLogLine);
2377 }
2378 android_log_format_free(logformat);
2379
2380 // test buffer reading API
2381 snprintf(msgBuf, sizeof(msgBuf), "I/[%d]", get4LE(eventData));
2382 print_barrier();
2383 fprintf(stderr, "%-10s(%5u): ", msgBuf, pid);
2384 memset(msgBuf, 0, sizeof(msgBuf));
2385 int buffer_to_string = android_log_buffer_to_string(
2386 eventData + sizeof(uint32_t),
2387 log_msg.entry.len - sizeof(uint32_t),
2388 msgBuf, sizeof(msgBuf));
2389 fprintf(stderr, "%s\n", msgBuf);
2390 print_barrier();
2391 EXPECT_EQ(0, buffer_to_string);
2392 EXPECT_EQ(strlen(expected_string), strlen(msgBuf));
2393 EXPECT_EQ(0, strcmp(expected_string, msgBuf));
2394 }
2395
2396 EXPECT_EQ(1, count);
2397
2398 android_logger_list_close(logger_list);
2399 }
2400
TEST(liblog,create_android_logger_int32)2401 TEST(liblog, create_android_logger_int32) {
2402 create_android_logger(event_test_int32);
2403 }
2404
TEST(liblog,create_android_logger_int64)2405 TEST(liblog, create_android_logger_int64) {
2406 create_android_logger(event_test_int64);
2407 }
2408
TEST(liblog,create_android_logger_list_int64)2409 TEST(liblog, create_android_logger_list_int64) {
2410 create_android_logger(event_test_list_int64);
2411 }
2412
TEST(liblog,create_android_logger_simple_automagic_list)2413 TEST(liblog, create_android_logger_simple_automagic_list) {
2414 create_android_logger(event_test_simple_automagic_list);
2415 }
2416
TEST(liblog,create_android_logger_list_empty)2417 TEST(liblog, create_android_logger_list_empty) {
2418 create_android_logger(event_test_list_empty);
2419 }
2420
TEST(liblog,create_android_logger_complex_nested_list)2421 TEST(liblog, create_android_logger_complex_nested_list) {
2422 create_android_logger(event_test_complex_nested_list);
2423 }
2424
TEST(liblog,create_android_logger_7_level_prefix)2425 TEST(liblog, create_android_logger_7_level_prefix) {
2426 create_android_logger(event_test_7_level_prefix);
2427 }
2428
TEST(liblog,create_android_logger_7_level_suffix)2429 TEST(liblog, create_android_logger_7_level_suffix) {
2430 create_android_logger(event_test_7_level_suffix);
2431 }
2432
TEST(liblog,create_android_logger_android_log_error_write)2433 TEST(liblog, create_android_logger_android_log_error_write) {
2434 create_android_logger(event_test_android_log_error_write);
2435 }
2436
TEST(liblog,create_android_logger_android_log_error_write_null)2437 TEST(liblog, create_android_logger_android_log_error_write_null) {
2438 create_android_logger(event_test_android_log_error_write_null);
2439 }
2440
TEST(liblog,create_android_logger_overflow)2441 TEST(liblog, create_android_logger_overflow) {
2442 android_log_context ctx;
2443
2444 EXPECT_TRUE(NULL != (ctx = create_android_logger(1005)));
2445 if (ctx) {
2446 for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2447 EXPECT_LE(0, android_log_write_list_begin(ctx));
2448 }
2449 EXPECT_GT(0, android_log_write_list_begin(ctx));
2450 /* One more for good measure, must be permanently unhappy */
2451 EXPECT_GT(0, android_log_write_list_begin(ctx));
2452 EXPECT_LE(0, android_log_destroy(&ctx));
2453 EXPECT_TRUE(NULL == ctx);
2454 }
2455
2456 ASSERT_TRUE(NULL != (ctx = create_android_logger(1005)));
2457 for (size_t i = 0; i < ANDROID_MAX_LIST_NEST_DEPTH; ++i) {
2458 EXPECT_LE(0, android_log_write_list_begin(ctx));
2459 EXPECT_LE(0, android_log_write_int32(ctx, i));
2460 }
2461 EXPECT_GT(0, android_log_write_list_begin(ctx));
2462 /* One more for good measure, must be permanently unhappy */
2463 EXPECT_GT(0, android_log_write_list_begin(ctx));
2464 EXPECT_LE(0, android_log_destroy(&ctx));
2465 ASSERT_TRUE(NULL == ctx);
2466 }
2467
2468 static const char __pmsg_file[] =
2469 "/data/william-shakespeare/MuchAdoAboutNothing.txt";
2470
TEST(liblog,__android_log_pmsg_file_write)2471 TEST(liblog, __android_log_pmsg_file_write) {
2472 EXPECT_LT(0, __android_log_pmsg_file_write(
2473 LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2474 __pmsg_file, max_payload_buf, sizeof(max_payload_buf)));
2475 fprintf(stderr, "Reboot, ensure file %s matches\n"
2476 "with liblog.__android_log_msg_file_read test\n",
2477 __pmsg_file);
2478 }
2479
__pmsg_fn(log_id_t logId,char prio,const char * filename,const char * buf,size_t len,void * arg)2480 ssize_t __pmsg_fn(log_id_t logId, char prio, const char *filename,
2481 const char *buf, size_t len, void *arg) {
2482 EXPECT_TRUE(NULL == arg);
2483 EXPECT_EQ(LOG_ID_CRASH, logId);
2484 EXPECT_EQ(ANDROID_LOG_VERBOSE, prio);
2485 EXPECT_FALSE(NULL == strstr(__pmsg_file, filename));
2486 EXPECT_EQ(len, sizeof(max_payload_buf));
2487 EXPECT_EQ(0, strcmp(max_payload_buf, buf));
2488
2489 ++signaled;
2490 if ((len != sizeof(max_payload_buf)) ||
2491 strcmp(max_payload_buf, buf)) {
2492 fprintf(stderr, "comparison fails on content \"%s\"\n", buf);
2493 }
2494 return !arg ||
2495 (LOG_ID_CRASH != logId) ||
2496 (ANDROID_LOG_VERBOSE != prio) ||
2497 !strstr(__pmsg_file, filename) ||
2498 (len != sizeof(max_payload_buf)) ||
2499 !!strcmp(max_payload_buf, buf) ? -ENOEXEC : 1;
2500 }
2501
TEST(liblog,__android_log_pmsg_file_read)2502 TEST(liblog, __android_log_pmsg_file_read) {
2503 signaled = 0;
2504
2505 ssize_t ret = __android_log_pmsg_file_read(
2506 LOG_ID_CRASH, ANDROID_LOG_VERBOSE,
2507 __pmsg_file, __pmsg_fn, NULL);
2508
2509 if (ret == -ENOENT) {
2510 fprintf(stderr,
2511 "No pre-boot results of liblog.__android_log_mesg_file_write to "
2512 "compare with,\n"
2513 "false positive test result.\n");
2514 return;
2515 }
2516
2517 EXPECT_LT(0, ret);
2518 EXPECT_EQ(1U, signaled);
2519 }
2520