1/* 2 * Copyright (C) 2014 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 <sys/cdefs.h> 19 20#include <gtest/gtest.h> 21 22// Should be in bionic test suite, *but* we are using liblog to confirm 23// end-to-end logging, so let the overly cute oedipus complex begin ... 24#include "../../../../bionic/libc/bionic/libc_logging.cpp" // not Standalone 25#define _ANDROID_LOG_H // Priorities redefined 26#define _LIBS_LOG_LOG_H // log ids redefined 27typedef unsigned char log_id_t; // log_id_t missing as a result 28#ifdef TARGET_USES_LOGD 29#define _LIBS_LOG_LOG_READ_H // log_time redefined 30#endif 31 32#include <log/log.h> 33#include <log/logger.h> 34#include <log/log_read.h> 35 36TEST(libc, __libc_android_log_event_int) { 37 struct logger_list *logger_list; 38 39 pid_t pid = getpid(); 40 41 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( 42 LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); 43 44 struct timespec ts; 45 clock_gettime(CLOCK_MONOTONIC, &ts); 46 int value = ts.tv_nsec; 47 48 __libc_android_log_event_int(0, value); 49 usleep(1000000); 50 51 int count = 0; 52 53 for (;;) { 54 log_msg log_msg; 55 if (android_logger_list_read(logger_list, &log_msg) <= 0) { 56 break; 57 } 58 59 ASSERT_EQ(log_msg.entry.pid, pid); 60 61 if ((log_msg.entry.len != (4 + 1 + 4)) 62 || ((int)log_msg.id() != LOG_ID_EVENTS)) { 63 continue; 64 } 65 66 char *eventData = log_msg.msg(); 67 68 int incoming = (eventData[0] & 0xFF) | 69 ((eventData[1] & 0xFF) << 8) | 70 ((eventData[2] & 0xFF) << 16) | 71 ((eventData[3] & 0xFF) << 24); 72 73 if (incoming != 0) { 74 continue; 75 } 76 77 if (eventData[4] != EVENT_TYPE_INT) { 78 continue; 79 } 80 81 incoming = (eventData[4 + 1 + 0] & 0xFF) | 82 ((eventData[4 + 1 + 1] & 0xFF) << 8) | 83 ((eventData[4 + 1 + 2] & 0xFF) << 16) | 84 ((eventData[4 + 1 + 3] & 0xFF) << 24); 85 86 if (incoming == value) { 87 ++count; 88 } 89 } 90 91 EXPECT_EQ(1, count); 92 93 android_logger_list_close(logger_list); 94} 95 96TEST(libc, __libc_fatal_no_abort) { 97 struct logger_list *logger_list; 98 99 pid_t pid = getpid(); 100 101 ASSERT_TRUE(NULL != (logger_list = android_logger_list_open( 102 (log_id_t)LOG_ID_CRASH, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid))); 103 104 char b[80]; 105 struct timespec ts; 106 clock_gettime(CLOCK_MONOTONIC, &ts); 107 108 __libc_fatal_no_abort("%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec); 109 snprintf(b, sizeof(b),"%u.%09u", (unsigned)ts.tv_sec, (unsigned)ts.tv_nsec); 110 usleep(1000000); 111 112 int count = 0; 113 114 for (;;) { 115 log_msg log_msg; 116 if (android_logger_list_read(logger_list, &log_msg) <= 0) { 117 break; 118 } 119 120 ASSERT_EQ(log_msg.entry.pid, pid); 121 122 if ((int)log_msg.id() != LOG_ID_CRASH) { 123 continue; 124 } 125 126 char *data = log_msg.msg(); 127 128 if ((*data == ANDROID_LOG_FATAL) 129 && !strcmp(data + 1, "libc") 130 && !strcmp(data + 1 + strlen(data + 1) + 1, b)) { 131 ++count; 132 } 133 } 134 135 EXPECT_EQ(1, count); 136 137 android_logger_list_close(logger_list); 138} 139 140TEST(libc, __pstore_append) { 141 FILE *fp; 142 ASSERT_TRUE(NULL != (fp = fopen("/dev/pmsg0", "a"))); 143 static const char message[] = "libc.__pstore_append\n"; 144 ASSERT_EQ((size_t)1, fwrite(message, sizeof(message), 1, fp)); 145 ASSERT_EQ(0, fclose(fp)); 146 fprintf(stderr, "Reboot, ensure string libc.__pstore_append is in /sys/fs/pstore/pmsg-ramoops-0\n"); 147} 148