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