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 #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 
TEST(libc,__libc_android_log_event_int)36 TEST(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 
TEST(libc,__libc_fatal_no_abort)96 TEST(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 
TEST(libc,__pstore_append)140 TEST(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