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
27 typedef 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
TEST(libc,__libc_android_log_event_int)34 TEST(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
TEST(libc,__libc_fatal_no_abort)94 TEST(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
TEST(libc,__pstore_append)138 TEST(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