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 49TEST(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 64TEST(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 79TEST(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 96static 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 107TEST(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 127TEST(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 180static inline int32_t get4LE(const char* src) 181{ 182 return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); 183} 184 185TEST(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 246TEST(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 307TEST(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 344TEST(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 481static unsigned signaled; 482static 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 */ 490static 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 506static 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 540TEST(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 */ 632static sem_t thread_trigger; 633 634static void caught_blocking_thread(int /*signum*/) 635{ 636 sem_post(&thread_trigger); 637} 638 639static 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 660int 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 690TEST(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 778static 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) 781static const char max_payload_buf[] = "LEONATO\n\ 782I learn in this letter that Don Peter of Arragon\n\ 783comes this night to Messina\n\ 784MESSENGER\n\ 785He is very near by this: he was not three leagues off\n\ 786when I left him\n\ 787LEONATO\n\ 788How many gentlemen have you lost in this action?\n\ 789MESSENGER\n\ 790But few of any sort, and none of name\n\ 791LEONATO\n\ 792A victory is twice itself when the achiever brings\n\ 793home full numbers. I find here that Don Peter hath\n\ 794bestowed much honour on a young Florentine called Claudio\n\ 795MESSENGER\n\ 796Much deserved on his part and equally remembered by\n\ 797Don Pedro: he hath borne himself beyond the\n\ 798promise of his age, doing, in the figure of a lamb,\n\ 799the feats of a lion: he hath indeed better\n\ 800bettered expectation than you must expect of me to\n\ 801tell you how\n\ 802LEONATO\n\ 803He hath an uncle here in Messina will be very much\n\ 804glad of it.\n\ 805MESSENGER\n\ 806I have already delivered him letters, and there\n\ 807appears much joy in him; even so much that joy could\n\ 808not show itself modest enough without a badge of\n\ 809bitterness.\n\ 810LEONATO\n\ 811Did he break out into tears?\n\ 812MESSENGER\n\ 813In great measure.\n\ 814LEONATO\n\ 815A kind overflow of kindness: there are no faces\n\ 816truer than those that are so washed. How much\n\ 817better is it to weep at joy than to joy at weeping!\n\ 818BEATRICE\n\ 819I pray you, is Signior Mountanto returned from the\n\ 820wars or no?\n\ 821MESSENGER\n\ 822I know none of that name, lady: there was none such\n\ 823in the army of any sort.\n\ 824LEONATO\n\ 825What is he that you ask for, niece?\n\ 826HERO\n\ 827My cousin means Signior Benedick of Padua.\n\ 828MESSENGER\n\ 829O, he's returned; and as pleasant as ever he was.\n\ 830BEATRICE\n\ 831He set up his bills here in Messina and challenged\n\ 832Cupid at the flight; and my uncle's fool, reading\n\ 833the challenge, subscribed for Cupid, and challenged\n\ 834him at the bird-bolt. I pray you, how many hath he\n\ 835killed and eaten in these wars? But how many hath\n\ 836he killed? for indeed I promised to eat all of his killing.\n\ 837LEONATO\n\ 838Faith, niece, you tax Signior Benedick too much;\n\ 839but he'll be meet with you, I doubt it not.\n\ 840MESSENGER\n\ 841He hath done good service, lady, in these wars.\n\ 842BEATRICE\n\ 843You had musty victual, and he hath holp to eat it:\n\ 844he is a very valiant trencherman; he hath an\n\ 845excellent stomach.\n\ 846MESSENGER\n\ 847And a good soldier too, lady.\n\ 848BEATRICE\n\ 849And a good soldier to a lady: but what is he to a lord?\n\ 850MESSENGER\n\ 851A lord to a lord, a man to a man; stuffed with all\n\ 852honourable virtues.\n\ 853BEATRICE\n\ 854It is so, indeed; he is no less than a stuffed man:\n\ 855but for the stuffing,--well, we are all mortal.\n\ 856LEONATO\n\ 857You must not, sir, mistake my niece. There is a\n\ 858kind of merry war betwixt Signior Benedick and her:\n\ 859they never meet but there's a skirmish of wit\n\ 860between them.\n\ 861BEATRICE\n\ 862Alas! he gets nothing by that. In our last\n\ 863conflict four of his five wits went halting off, and\n\ 864now is the whole man governed with one: so that if\n\ 865he have wit enough to keep himself warm, let him\n\ 866bear it for a difference between himself and his\n\ 867horse; for it is all the wealth that he hath left,\n\ 868to be known a reasonable creature. Who is his\n\ 869companion now? He hath every month a new sworn brother.\n\ 870MESSENGER\n\ 871Is't possible?\n\ 872BEATRICE\n\ 873Very easily possible: he wears his faith but as\n\ 874the fashion of his hat; it ever changes with the\n\ 875next block.\n\ 876MESSENGER\n\ 877I see, lady, the gentleman is not in your books.\n\ 878BEATRICE\n\ 879No; an he were, I would burn my study. But, I pray\n\ 880you, who is his companion? Is there no young\n\ 881squarer now that will make a voyage with him to the devil?\n\ 882MESSENGER\n\ 883He is most in the company of the right noble Claudio.\n\ 884BEATRICE\n\ 885O Lord, he will hang upon him like a disease: he\n\ 886is sooner caught than the pestilence, and the taker\n\ 887runs presently mad. God help the noble Claudio! if\n\ 888he have caught the Benedick, it will cost him a\n\ 889thousand pound ere a' be cured.\n\ 890MESSENGER\n\ 891I will hold friends with you, lady.\n\ 892BEATRICE\n\ 893Do, good friend.\n\ 894LEONATO\n\ 895You will never run mad, niece.\n\ 896BEATRICE\n\ 897No, not till a hot January.\n\ 898MESSENGER\n\ 899Don Pedro is approached.\n\ 900Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK, and BALTHASAR\n\ 901\n\ 902DON PEDRO\n\ 903Good Signior Leonato, you are come to meet your\n\ 904trouble: the fashion of the world is to avoid\n\ 905cost, and you encounter it\n\ 906LEONATO\n\ 907Never came trouble to my house in the likeness of your grace,\n\ 908for trouble being gone, comfort should remain, but\n\ 909when you depart from me, sorrow abides and happiness\n\ 910takes his leave."; 911 912TEST(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 972TEST(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 1028TEST(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 1085TEST(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 1132TEST(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 1166static 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 1171TEST(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 1235TEST(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 1520TEST(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 1601TEST(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 1688TEST(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 1731TEST(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 1813TEST(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 1871TEST(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 1910static 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 1917int 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 2069static 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 2087static 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 2105static 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 2126static 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 2149static 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 2168static 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 2218static 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 2256static 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 2291static 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 2303static 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 2316static void print_barrier() { 2317 std::cout.flush(); 2318 fflush(stdout); 2319 std::cerr.flush(); 2320 fflush(stderr); // everything else is paranoia ... 2321} 2322 2323static 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 2401TEST(liblog, create_android_logger_int32) { 2402 create_android_logger(event_test_int32); 2403} 2404 2405TEST(liblog, create_android_logger_int64) { 2406 create_android_logger(event_test_int64); 2407} 2408 2409TEST(liblog, create_android_logger_list_int64) { 2410 create_android_logger(event_test_list_int64); 2411} 2412 2413TEST(liblog, create_android_logger_simple_automagic_list) { 2414 create_android_logger(event_test_simple_automagic_list); 2415} 2416 2417TEST(liblog, create_android_logger_list_empty) { 2418 create_android_logger(event_test_list_empty); 2419} 2420 2421TEST(liblog, create_android_logger_complex_nested_list) { 2422 create_android_logger(event_test_complex_nested_list); 2423} 2424 2425TEST(liblog, create_android_logger_7_level_prefix) { 2426 create_android_logger(event_test_7_level_prefix); 2427} 2428 2429TEST(liblog, create_android_logger_7_level_suffix) { 2430 create_android_logger(event_test_7_level_suffix); 2431} 2432 2433TEST(liblog, create_android_logger_android_log_error_write) { 2434 create_android_logger(event_test_android_log_error_write); 2435} 2436 2437TEST(liblog, create_android_logger_android_log_error_write_null) { 2438 create_android_logger(event_test_android_log_error_write_null); 2439} 2440 2441TEST(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 2468static const char __pmsg_file[] = 2469 "/data/william-shakespeare/MuchAdoAboutNothing.txt"; 2470 2471TEST(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 2480ssize_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 2502TEST(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