Merge "Utility class for COW size calculation"
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index e5a4917..9ebab74 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -248,6 +248,12 @@
prop_port = android::base::GetProperty("persist.adb.tcp.port", "");
}
+#if !defined(__ANDROID__)
+ if (prop_port.empty() && getenv("ADBD_PORT")) {
+ prop_port = getenv("ADBD_PORT");
+ }
+#endif
+
int port;
if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) {
D("using port=%d", port);
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 7405039..54350a5 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -171,7 +171,8 @@
std::unique_ptr<MetadataBuilder> MetadataBuilder::NewForUpdate(const IPartitionOpener& opener,
const std::string& source_partition,
uint32_t source_slot_number,
- uint32_t target_slot_number) {
+ uint32_t target_slot_number,
+ bool always_keep_source_slot) {
auto metadata = ReadMetadata(opener, source_partition, source_slot_number);
if (!metadata) {
return nullptr;
@@ -189,7 +190,8 @@
}
}
- if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.virtual_ab.enabled", false)) {
+ if (IPropertyFetcher::GetInstance()->GetBoolProperty("ro.virtual_ab.enabled", false) &&
+ !always_keep_source_slot) {
if (!UpdateMetadataForInPlaceSnapshot(metadata.get(), source_slot_number,
target_slot_number)) {
return nullptr;
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index b43ccf0..1e9d636 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -209,10 +209,13 @@
// metadata may not have the target slot's devices listed yet, in which
// case, it is automatically upgraded to include all available block
// devices.
+ // If |always_keep_source_slot| is set, on a Virtual A/B device, source slot
+ // partitions are kept. This is useful when applying a downgrade package.
static std::unique_ptr<MetadataBuilder> NewForUpdate(const IPartitionOpener& opener,
const std::string& source_partition,
uint32_t source_slot_number,
- uint32_t target_slot_number);
+ uint32_t target_slot_number,
+ bool always_keep_source_slot = false);
// Import an existing table for modification. If the table is not valid, for
// example it contains duplicate partition names, then nullptr is returned.
diff --git a/fs_mgr/libsnapshot/test_helpers.cpp b/fs_mgr/libsnapshot/test_helpers.cpp
index 1a6a593..539c5c5 100644
--- a/fs_mgr/libsnapshot/test_helpers.cpp
+++ b/fs_mgr/libsnapshot/test_helpers.cpp
@@ -92,21 +92,14 @@
}
std::optional<std::string> GetHash(const std::string& path) {
- unique_fd fd(open(path.c_str(), O_RDONLY));
- char buf[4096];
+ std::string content;
+ if (!android::base::ReadFileToString(path, &content, true)) {
+ PLOG(ERROR) << "Cannot access " << path;
+ return std::nullopt;
+ }
SHA256_CTX ctx;
SHA256_Init(&ctx);
- while (true) {
- ssize_t n = TEMP_FAILURE_RETRY(read(fd.get(), buf, sizeof(buf)));
- if (n < 0) {
- PLOG(ERROR) << "Cannot read " << path;
- return std::nullopt;
- }
- if (n == 0) {
- break;
- }
- SHA256_Update(&ctx, buf, n);
- }
+ SHA256_Update(&ctx, content.c_str(), content.size());
uint8_t out[32];
SHA256_Final(out, &ctx);
return ToHexString(out, sizeof(out));
diff --git a/libcutils/sched_policy_test.cpp b/libcutils/sched_policy_test.cpp
index a321c90..b9e2832 100644
--- a/libcutils/sched_policy_test.cpp
+++ b/libcutils/sched_policy_test.cpp
@@ -107,6 +107,18 @@
TEST(SchedPolicy, get_sched_policy_name) {
EXPECT_STREQ("bg", get_sched_policy_name(SP_BACKGROUND));
- EXPECT_STREQ("error", get_sched_policy_name(SchedPolicy(-2)));
- EXPECT_STREQ("error", get_sched_policy_name(SP_CNT));
+ EXPECT_EQ(nullptr, get_sched_policy_name(SchedPolicy(-2)));
+ EXPECT_EQ(nullptr, get_sched_policy_name(SP_CNT));
+}
+
+TEST(SchedPolicy, get_cpuset_policy_profile_name) {
+ EXPECT_STREQ("CPUSET_SP_BACKGROUND", get_cpuset_policy_profile_name(SP_BACKGROUND));
+ EXPECT_EQ(nullptr, get_cpuset_policy_profile_name(SchedPolicy(-2)));
+ EXPECT_EQ(nullptr, get_cpuset_policy_profile_name(SP_CNT));
+}
+
+TEST(SchedPolicy, get_sched_policy_profile_name) {
+ EXPECT_STREQ("SCHED_SP_BACKGROUND", get_sched_policy_profile_name(SP_BACKGROUND));
+ EXPECT_EQ(nullptr, get_sched_policy_profile_name(SchedPolicy(-2)));
+ EXPECT_EQ(nullptr, get_sched_policy_profile_name(SP_CNT));
}
diff --git a/liblog/include/android/log.h b/liblog/include/android/log.h
index 935590d..2e6210e 100644
--- a/liblog/include/android/log.h
+++ b/liblog/include/android/log.h
@@ -96,20 +96,14 @@
* [printf(3)](http://man7.org/linux/man-pages/man3/printf.3.html).
*/
int __android_log_print(int prio, const char* tag, const char* fmt, ...)
-#if defined(__GNUC__)
- __attribute__((__format__(printf, 3, 4)))
-#endif
- ;
+ __attribute__((__format__(printf, 3, 4)));
/**
* Equivalent to `__android_log_print`, but taking a `va_list`.
* (If `__android_log_print` is like `printf`, this is like `vprintf`.)
*/
int __android_log_vprint(int prio, const char* tag, const char* fmt, va_list ap)
-#if defined(__GNUC__)
- __attribute__((__format__(printf, 3, 0)))
-#endif
- ;
+ __attribute__((__format__(printf, 3, 0)));
/**
* Writes an assertion failure to the log (as `ANDROID_LOG_FATAL`) and to
@@ -127,13 +121,8 @@
* including the source filename and line number more conveniently than this
* function.
*/
-void __android_log_assert(const char* cond, const char* tag, const char* fmt,
- ...)
-#if defined(__GNUC__)
- __attribute__((__noreturn__))
- __attribute__((__format__(printf, 3, 4)))
-#endif
- ;
+void __android_log_assert(const char* cond, const char* tag, const char* fmt, ...)
+ __attribute__((__noreturn__)) __attribute__((__format__(printf, 3, 4)));
#ifndef log_id_t_defined
#define log_id_t_defined
@@ -171,8 +160,7 @@
*
* Apps should use __android_log_write() instead.
*/
-int __android_log_buf_write(int bufID, int prio, const char* tag,
- const char* text);
+int __android_log_buf_write(int bufID, int prio, const char* tag, const char* text);
/**
* Writes a formatted string to log buffer `id`,
@@ -182,12 +170,8 @@
*
* Apps should use __android_log_print() instead.
*/
-int __android_log_buf_print(int bufID, int prio, const char* tag,
- const char* fmt, ...)
-#if defined(__GNUC__)
- __attribute__((__format__(printf, 4, 5)))
-#endif
- ;
+int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...)
+ __attribute__((__format__(printf, 4, 5)));
#ifdef __cplusplus
}
diff --git a/liblog/include/log/event_tag_map.h b/liblog/include/log/event_tag_map.h
index 2687b3a..f7ec208 100644
--- a/liblog/include/log/event_tag_map.h
+++ b/liblog/include/log/event_tag_map.h
@@ -16,6 +16,8 @@
#pragma once
+#include <stddef.h>
+
#ifdef __cplusplus
extern "C" {
#endif
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index 5928649..90d1e76 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -22,7 +22,6 @@
#endif
#include <stdint.h> /* uint16_t, int32_t */
#include <stdio.h>
-#include <sys/types.h>
#include <time.h>
#include <unistd.h>
@@ -65,21 +64,6 @@
#endif
#endif
-/* --------------------------------------------------------------------- */
-
-/*
- * This file uses ", ## __VA_ARGS__" zero-argument token pasting to
- * work around issues with debug-only syntax errors in assertions
- * that are missing format strings. See commit
- * 19299904343daf191267564fe32e6cd5c165cd42
- */
-#if defined(__clang__)
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
-#endif
-
-/* --------------------------------------------------------------------- */
-
/*
* Event logging.
*/
@@ -164,10 +148,6 @@
*/
void __android_log_close(void);
-#if defined(__clang__)
-#pragma clang diagnostic pop
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/liblog/include/log/log_event_list.h b/liblog/include/log/log_event_list.h
index 636d417..deadf20 100644
--- a/liblog/include/log/log_event_list.h
+++ b/liblog/include/log/log_event_list.h
@@ -36,16 +36,11 @@
/*
* The opaque context used to manipulate lists of events.
*/
-#ifndef __android_log_context_defined
-#define __android_log_context_defined
typedef struct android_log_context_internal* android_log_context;
-#endif
/*
* Elements returned when reading a list of events.
*/
-#ifndef __android_log_list_element_defined
-#define __android_log_list_element_defined
typedef struct {
AndroidEventLogType type;
uint16_t complete;
@@ -57,7 +52,6 @@
float float32;
} data;
} android_log_list_element;
-#endif
/*
* Creates a context associated with an event tag to write elements to
@@ -104,8 +98,6 @@
int android_log_destroy(android_log_context* ctx);
#ifdef __cplusplus
-#ifndef __class_android_log_event_list_defined
-#define __class_android_log_event_list_defined
/* android_log_list C++ helpers */
extern "C++" {
class android_log_event_list {
@@ -280,7 +272,6 @@
};
}
#endif
-#endif
#ifdef __cplusplus
}
diff --git a/liblog/include/log/log_id.h b/liblog/include/log/log_id.h
index c052a50..4c6d809 100644
--- a/liblog/include/log/log_id.h
+++ b/liblog/include/log/log_id.h
@@ -45,12 +45,8 @@
*/
int __android_log_buf_write(int bufID, int prio, const char* tag,
const char* text);
-int __android_log_buf_print(int bufID, int prio, const char* tag,
- const char* fmt, ...)
-#if defined(__GNUC__)
- __attribute__((__format__(printf, 4, 5)))
-#endif
- ;
+int __android_log_buf_print(int bufID, int prio, const char* tag, const char* fmt, ...)
+ __attribute__((__format__(printf, 4, 5)));
/*
* log_id_t helpers
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index fdef306..2079e7a 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -53,8 +53,6 @@
/*
* The userspace structure for version 1 of the logger_entry ABI.
*/
-#ifndef __struct_logger_entry_defined
-#define __struct_logger_entry_defined
struct logger_entry {
uint16_t len; /* length of the payload */
uint16_t __pad; /* no matter what, we get 2 bytes of padding */
@@ -64,13 +62,10 @@
int32_t nsec; /* nanoseconds */
char msg[0]; /* the entry's payload */
};
-#endif
/*
* The userspace structure for version 2 of the logger_entry ABI.
*/
-#ifndef __struct_logger_entry_v2_defined
-#define __struct_logger_entry_v2_defined
struct logger_entry_v2 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v2) */
@@ -81,13 +76,10 @@
uint32_t euid; /* effective UID of logger */
char msg[0]; /* the entry's payload */
} __attribute__((__packed__));
-#endif
/*
* The userspace structure for version 3 of the logger_entry ABI.
*/
-#ifndef __struct_logger_entry_v3_defined
-#define __struct_logger_entry_v3_defined
struct logger_entry_v3 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */
@@ -98,13 +90,10 @@
uint32_t lid; /* log id of the payload */
char msg[0]; /* the entry's payload */
} __attribute__((__packed__));
-#endif
/*
* The userspace structure for version 4 of the logger_entry ABI.
*/
-#ifndef __struct_logger_entry_v4_defined
-#define __struct_logger_entry_v4_defined
struct logger_entry_v4 {
uint16_t len; /* length of the payload */
uint16_t hdr_size; /* sizeof(struct logger_entry_v4) */
@@ -116,7 +105,6 @@
uint32_t uid; /* generating process's uid */
char msg[0]; /* the entry's payload */
};
-#endif
#pragma clang diagnostic pop
/*
@@ -133,8 +121,6 @@
*/
#define LOGGER_ENTRY_MAX_LEN (5 * 1024)
-#ifndef __struct_log_msg_defined
-#define __struct_log_msg_defined
struct log_msg {
union {
unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];
@@ -191,7 +177,6 @@
}
#endif
};
-#endif
struct logger;
diff --git a/liblog/include/log/log_time.h b/liblog/include/log/log_time.h
index 09c9910..6b4458c 100644
--- a/liblog/include/log/log_time.h
+++ b/liblog/include/log/log_time.h
@@ -24,9 +24,6 @@
#define US_PER_SEC 1000000ULL
#define MS_PER_SEC 1000ULL
-#ifndef __struct_log_time_defined
-#define __struct_log_time_defined
-
#define LOG_TIME_SEC(t) ((t)->tv_sec)
/* next power of two after NS_PER_SEC */
#define LOG_TIME_NSEC(t) ((t)->tv_nsec & (UINT32_MAX >> 2))
@@ -35,11 +32,6 @@
extern "C" {
-/*
- * NB: we did NOT define a copy constructor. This will result in structure
- * no longer being compatible with pass-by-value which is desired
- * efficient behavior. Also, pass-by-reference breaks C/C++ ABI.
- */
struct log_time {
public:
uint32_t tv_sec = 0; /* good to Feb 5 2106 */
@@ -169,5 +161,3 @@
} __attribute__((__packed__)) log_time;
#endif /* __cplusplus */
-
-#endif /* __struct_log_time_defined */
diff --git a/liblog/include/log/logprint.h b/liblog/include/log/logprint.h
index 8f4b187..7dfd914 100644
--- a/liblog/include/log/logprint.h
+++ b/liblog/include/log/logprint.h
@@ -16,7 +16,8 @@
#pragma once
-#include <pthread.h>
+#include <stdint.h>
+#include <sys/types.h>
#include <android/log.h>
#include <log/event_tag_map.h>
diff --git a/liblog/pmsg_reader.cpp b/liblog/pmsg_reader.cpp
index 9c5bc95..ce923f3 100644
--- a/liblog/pmsg_reader.cpp
+++ b/liblog/pmsg_reader.cpp
@@ -62,58 +62,9 @@
return -EBADF;
}
-/* Determine the credentials of the caller */
-static bool uid_has_log_permission(uid_t uid) {
- return (uid == AID_SYSTEM) || (uid == AID_LOG) || (uid == AID_ROOT) || (uid == AID_LOGD);
-}
-
-static uid_t get_best_effective_uid() {
- uid_t euid;
- uid_t uid;
- gid_t gid;
- ssize_t i;
- static uid_t last_uid = (uid_t)-1;
-
- if (last_uid != (uid_t)-1) {
- return last_uid;
- }
- uid = __android_log_uid();
- if (uid_has_log_permission(uid)) {
- return last_uid = uid;
- }
- euid = geteuid();
- if (uid_has_log_permission(euid)) {
- return last_uid = euid;
- }
- gid = getgid();
- if (uid_has_log_permission(gid)) {
- return last_uid = gid;
- }
- gid = getegid();
- if (uid_has_log_permission(gid)) {
- return last_uid = gid;
- }
- i = getgroups((size_t)0, NULL);
- if (i > 0) {
- gid_t list[i];
-
- getgroups(i, list);
- while (--i >= 0) {
- if (uid_has_log_permission(list[i])) {
- return last_uid = list[i];
- }
- }
- }
- return last_uid = uid;
-}
-
static int pmsgClear(struct android_log_logger* logger __unused,
struct android_log_transport_context* transp __unused) {
- if (uid_has_log_permission(get_best_effective_uid())) {
- return unlink("/sys/fs/pstore/pmsg-ramoops-0");
- }
- errno = EPERM;
- return -1;
+ return unlink("/sys/fs/pstore/pmsg-ramoops-0");
}
/*
@@ -128,14 +79,12 @@
struct android_log_transport_context* transp, struct log_msg* log_msg) {
ssize_t ret;
off_t current, next;
- uid_t uid;
struct __attribute__((__packed__)) {
android_pmsg_log_header_t p;
android_log_header_t l;
uint8_t prio;
} buf;
static uint8_t preread_count;
- bool is_system;
memset(log_msg, 0, sizeof(*log_msg));
@@ -195,37 +144,30 @@
((logger_list->start.tv_sec != buf.l.realtime.tv_sec) ||
(logger_list->start.tv_nsec <= buf.l.realtime.tv_nsec)))) &&
(!logger_list->pid || (logger_list->pid == buf.p.pid))) {
- uid = get_best_effective_uid();
- is_system = uid_has_log_permission(uid);
- if (is_system || (uid == buf.p.uid)) {
- char* msg = is_system ? log_msg->entry_v4.msg : log_msg->entry_v3.msg;
- *msg = buf.prio;
- fd = atomic_load(&transp->context.fd);
- if (fd <= 0) {
- return -EBADF;
- }
- ret = TEMP_FAILURE_RETRY(read(fd, msg + sizeof(buf.prio), buf.p.len - sizeof(buf)));
- if (ret < 0) {
- return -errno;
- }
- if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {
- return -EIO;
- }
-
- log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
- log_msg->entry_v4.hdr_size =
- is_system ? sizeof(log_msg->entry_v4) : sizeof(log_msg->entry_v3);
- log_msg->entry_v4.pid = buf.p.pid;
- log_msg->entry_v4.tid = buf.l.tid;
- log_msg->entry_v4.sec = buf.l.realtime.tv_sec;
- log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec;
- log_msg->entry_v4.lid = buf.l.id;
- if (is_system) {
- log_msg->entry_v4.uid = buf.p.uid;
- }
-
- return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size;
+ char* msg = log_msg->entry_v4.msg;
+ *msg = buf.prio;
+ fd = atomic_load(&transp->context.fd);
+ if (fd <= 0) {
+ return -EBADF;
}
+ ret = TEMP_FAILURE_RETRY(read(fd, msg + sizeof(buf.prio), buf.p.len - sizeof(buf)));
+ if (ret < 0) {
+ return -errno;
+ }
+ if (ret != (ssize_t)(buf.p.len - sizeof(buf))) {
+ return -EIO;
+ }
+
+ log_msg->entry_v4.len = buf.p.len - sizeof(buf) + sizeof(buf.prio);
+ log_msg->entry_v4.hdr_size = sizeof(log_msg->entry_v4);
+ log_msg->entry_v4.pid = buf.p.pid;
+ log_msg->entry_v4.tid = buf.l.tid;
+ log_msg->entry_v4.sec = buf.l.realtime.tv_sec;
+ log_msg->entry_v4.nsec = buf.l.realtime.tv_nsec;
+ log_msg->entry_v4.lid = buf.l.id;
+ log_msg->entry_v4.uid = buf.p.uid;
+
+ return ret + sizeof(buf.prio) + log_msg->entry_v4.hdr_size;
}
fd = atomic_load(&transp->context.fd);
@@ -273,13 +215,7 @@
struct android_log_transport_context transp;
struct content {
struct listnode node;
- union {
- struct logger_entry_v4 entry;
- struct logger_entry_v4 entry_v4;
- struct logger_entry_v3 entry_v3;
- struct logger_entry_v2 entry_v2;
- struct logger_entry entry_v1;
- };
+ struct logger_entry_v4 entry;
} * content;
struct names {
struct listnode node;
diff --git a/liblog/tests/liblog_benchmark.cpp b/liblog/tests/liblog_benchmark.cpp
index 4642b9b..56892a2 100644
--- a/liblog/tests/liblog_benchmark.cpp
+++ b/liblog/tests/liblog_benchmark.cpp
@@ -17,6 +17,7 @@
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
+#include <sched.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/types.h>
diff --git a/liblog/tests/liblog_test.cpp b/liblog/tests/liblog_test.cpp
index fdb18e4..94c4fbb 100644
--- a/liblog/tests/liblog_test.cpp
+++ b/liblog/tests/liblog_test.cpp
@@ -62,6 +62,12 @@
_rc; \
})
+// std::unique_ptr doesn't let you provide a pointer to a deleter (android_logger_list_close()) if
+// the type (struct logger_list) is an incomplete type, so we create ListCloser instead.
+struct ListCloser {
+ void operator()(struct logger_list* list) { android_logger_list_close(list); }
+};
+
// This function is meant to be used for most log tests, it does the following:
// 1) Open the log_buffer with a blocking reader
// 2) Write the messages via write_messages
@@ -75,11 +81,6 @@
static void RunLogTests(log_id_t log_buffer, FWrite write_messages, FCheck check_message) {
pid_t pid = getpid();
- // std::unique_ptr doesn't let you provide a pointer to a deleter (android_logger_list_close()) if
- // the type (struct logger_list) is an incomplete type, so we create ListCloser instead.
- struct ListCloser {
- void operator()(struct logger_list* list) { android_logger_list_close(list); }
- };
auto logger_list = std::unique_ptr<struct logger_list, ListCloser>{
android_logger_list_open(log_buffer, ANDROID_LOG_RDONLY, 1000, pid)};
ASSERT_TRUE(logger_list);
@@ -142,14 +143,11 @@
long long longBuf = 0xDEADBEEFA55A5AA5;
EXPECT_LT(
0, __android_log_btwrite(0, EVENT_TYPE_LONG, &longBuf, sizeof(longBuf)));
- usleep(1000);
char Buf[] = "\20\0\0\0DeAdBeEfA55a5aA5";
EXPECT_LT(0,
__android_log_btwrite(0, EVENT_TYPE_STRING, Buf, sizeof(Buf) - 1));
- usleep(1000);
}
-#ifdef ENABLE_FLAKY_TESTS
#if defined(__ANDROID__)
static std::string popenToString(const std::string& command) {
std::string ret;
@@ -218,81 +216,63 @@
static bool tested__android_log_close;
#endif
-#endif // ENABLE_FLAKY_TESTS
TEST(liblog, __android_log_btwrite__android_logger_list_read) {
#ifdef __ANDROID__
- struct logger_list* logger_list;
-
- pid_t pid = getpid();
-
- ASSERT_TRUE(NULL !=
- (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- 1000, pid)));
-
log_time ts(CLOCK_MONOTONIC);
- EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
-#ifdef ENABLE_FLAKY_TESTS
- // Check that we can close and reopen the logger
- bool logdwActiveAfter__android_log_btwrite;
- if (getuid() == AID_ROOT) {
- tested__android_log_close = true;
-#ifndef NO_PSTORE
- bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
- EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
-#endif /* NO_PSTORE */
- logdwActiveAfter__android_log_btwrite = isLogdwActive();
- EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
- } else if (!tested__android_log_close) {
- fprintf(stderr, "WARNING: can not test __android_log_close()\n");
- }
- __android_log_close();
- if (getuid() == AID_ROOT) {
-#ifndef NO_PSTORE
- bool pmsgActiveAfter__android_log_close = isPmsgActive();
- EXPECT_FALSE(pmsgActiveAfter__android_log_close);
-#endif /* NO_PSTORE */
- bool logdwActiveAfter__android_log_close = isLogdwActive();
- EXPECT_FALSE(logdwActiveAfter__android_log_close);
- }
-#endif // ENABLE_FLAKY_TESTS
+ log_time ts1(ts);
- log_time ts1(CLOCK_MONOTONIC);
- EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
-#ifdef ENABLE_FLAKY_TESTS
- if (getuid() == AID_ROOT) {
+ auto write_function = [&] {
+ EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts, sizeof(ts)));
+ // Check that we can close and reopen the logger
+ bool logdwActiveAfter__android_log_btwrite;
+ if (getuid() == AID_ROOT) {
+ tested__android_log_close = true;
#ifndef NO_PSTORE
- bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
- EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+ bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
#endif /* NO_PSTORE */
- logdwActiveAfter__android_log_btwrite = isLogdwActive();
- EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
- }
-#endif // ENABLE_FLAKY_TESTS
- usleep(1000000);
+ logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ } else if (!tested__android_log_close) {
+ fprintf(stderr, "WARNING: can not test __android_log_close()\n");
+ }
+ __android_log_close();
+ if (getuid() == AID_ROOT) {
+#ifndef NO_PSTORE
+ bool pmsgActiveAfter__android_log_close = isPmsgActive();
+ EXPECT_FALSE(pmsgActiveAfter__android_log_close);
+#endif /* NO_PSTORE */
+ bool logdwActiveAfter__android_log_close = isLogdwActive();
+ EXPECT_FALSE(logdwActiveAfter__android_log_close);
+ }
+
+ ts1 = log_time(CLOCK_MONOTONIC);
+ EXPECT_LT(0, __android_log_btwrite(0, EVENT_TYPE_LONG, &ts1, sizeof(ts1)));
+ if (getuid() == AID_ROOT) {
+#ifndef NO_PSTORE
+ bool pmsgActiveAfter__android_log_btwrite = isPmsgActive();
+ EXPECT_TRUE(pmsgActiveAfter__android_log_btwrite);
+#endif /* NO_PSTORE */
+ logdwActiveAfter__android_log_btwrite = isLogdwActive();
+ EXPECT_TRUE(logdwActiveAfter__android_log_btwrite);
+ }
+ };
int count = 0;
int second_count = 0;
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- EXPECT_EQ(log_msg.entry.pid, pid);
-
+ auto check_function = [&](log_msg log_msg, bool* found) {
if ((log_msg.entry.len != sizeof(android_log_event_long_t)) ||
(log_msg.id() != LOG_ID_EVENTS)) {
- continue;
+ return;
}
android_log_event_long_t* eventData;
eventData = reinterpret_cast<android_log_event_long_t*>(log_msg.msg());
if (!eventData || (eventData->payload.type != EVENT_TYPE_LONG)) {
- continue;
+ return;
}
log_time tx(reinterpret_cast<char*>(&eventData->payload.data));
@@ -301,12 +281,50 @@
} else if (ts1 == tx) {
++second_count;
}
- }
- EXPECT_EQ(1, count);
- EXPECT_EQ(1, second_count);
+ if (count == 1 && second_count == 1) {
+ count = 0;
+ second_count = 0;
+ *found = true;
+ }
+ };
- android_logger_list_close(logger_list);
+ RunLogTests(LOG_ID_EVENTS, write_function, check_function);
+
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
+
+TEST(liblog, __android_log_write__android_logger_list_read) {
+#ifdef __ANDROID__
+ pid_t pid = getpid();
+
+ struct timespec ts;
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid, ts.tv_sec, ts.tv_nsec);
+ static const char tag[] = "liblog.__android_log_write__android_logger_list_read";
+ static const char prio = ANDROID_LOG_DEBUG;
+
+ std::string expected_message =
+ std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf + std::string("", 1);
+
+ auto write_function = [&] { ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str())); };
+
+ auto check_function = [&](log_msg log_msg, bool* found) {
+ if (log_msg.entry.len != expected_message.length()) {
+ return;
+ }
+
+ if (expected_message != std::string(log_msg.msg(), log_msg.entry.len)) {
+ return;
+ }
+
+ *found = true;
+ };
+
+ RunLogTests(LOG_ID_MAIN, write_function, check_function);
+
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
@@ -314,18 +332,10 @@
static void bswrite_test(const char* message) {
#ifdef __ANDROID__
- struct logger_list* logger_list;
-
pid_t pid = getpid();
- ASSERT_TRUE(NULL !=
- (logger_list = android_logger_list_open(
- LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- 1000, pid)));
-
log_time ts(android_log_clockid());
- EXPECT_LT(0, __android_log_bswrite(0, message));
size_t num_lines = 1, size = 0, length = 0, total = 0;
const char* cp = message;
while (*cp) {
@@ -347,36 +357,25 @@
++cp;
++total;
}
- usleep(1000000);
- int count = 0;
+ auto write_function = [&] { EXPECT_LT(0, __android_log_bswrite(0, message)); };
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
- }
-
- EXPECT_EQ(log_msg.entry.pid, pid);
-
- if ((log_msg.entry.sec < (ts.tv_sec - 1)) ||
- ((ts.tv_sec + 1) < log_msg.entry.sec) ||
- ((size_t)log_msg.entry.len !=
- (sizeof(android_log_event_string_t) + length)) ||
- (log_msg.id() != LOG_ID_EVENTS)) {
- continue;
+ auto check_function = [&](log_msg log_msg, bool* found) {
+ if ((size_t)log_msg.entry.len != (sizeof(android_log_event_string_t) + length) ||
+ log_msg.id() != LOG_ID_EVENTS) {
+ return;
}
android_log_event_string_t* eventData;
eventData = reinterpret_cast<android_log_event_string_t*>(log_msg.msg());
if (!eventData || (eventData->type != EVENT_TYPE_STRING)) {
- continue;
+ return;
}
size_t len = eventData->length;
if (len == total) {
- ++count;
+ *found = true;
AndroidLogFormat* logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
@@ -403,11 +402,10 @@
}
android_log_format_free(logformat);
}
- }
+ };
- EXPECT_EQ(1, count);
+ RunLogTests(LOG_ID_EVENTS, write_function, check_function);
- android_logger_list_close(logger_list);
#else
message = NULL;
GTEST_LOG_(INFO) << "This test does nothing.\n";
@@ -436,20 +434,14 @@
static void buf_write_test(const char* message) {
#ifdef __ANDROID__
- struct logger_list* logger_list;
-
pid_t pid = getpid();
- ASSERT_TRUE(
- NULL !=
- (logger_list = android_logger_list_open(
- LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
static const char tag[] = "TEST__android_log_buf_write";
log_time ts(android_log_clockid());
- EXPECT_LT(
- 0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, tag, message));
+ auto write_function = [&] {
+ EXPECT_LT(0, __android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO, tag, message));
+ };
size_t num_lines = 1, size = 0, length = 0;
const char* cp = message;
while (*cp) {
@@ -466,26 +458,13 @@
}
++cp;
}
- usleep(1000000);
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) {
- break;
+ auto check_function = [&](log_msg log_msg, bool* found) {
+ if ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2) || log_msg.id() != LOG_ID_MAIN) {
+ return;
}
- ASSERT_EQ(log_msg.entry.pid, pid);
-
- if ((log_msg.entry.sec < (ts.tv_sec - 1)) ||
- ((ts.tv_sec + 1) < log_msg.entry.sec) ||
- ((size_t)log_msg.entry.len != (sizeof(tag) + length + 2)) ||
- (log_msg.id() != LOG_ID_MAIN)) {
- continue;
- }
-
- ++count;
+ *found = true;
AndroidLogFormat* logformat = android_log_format_new();
EXPECT_TRUE(NULL != logformat);
@@ -502,11 +481,10 @@
android_log_printLogLine(logformat, fileno(stderr), &entry));
}
android_log_format_free(logformat);
- }
+ };
- EXPECT_EQ(1, count);
+ RunLogTests(LOG_ID_MAIN, write_function, check_function);
- android_logger_list_close(logger_list);
#else
message = NULL;
GTEST_LOG_(INFO) << "This test does nothing.\n";
@@ -969,7 +947,6 @@
when you depart from me, sorrow abides and happiness\n\
takes his leave.";
-#ifdef ENABLE_FLAKY_TESTS
TEST(liblog, max_payload) {
#ifdef __ANDROID__
static const char max_payload_tag[] = "TEST_max_payload_and_longish_tag_XXXX";
@@ -1018,7 +995,6 @@
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
-#endif // ENABLE_FLAKY_TESTS
TEST(liblog, __android_log_buf_print__maxtag) {
#ifdef __ANDROID__
@@ -1112,11 +1088,20 @@
#endif
}
-#ifdef ENABLE_FLAKY_TESTS
TEST(liblog, dual_reader) {
#ifdef __ANDROID__
+ static const int expected_count1 = 25;
+ static const int expected_count2 = 25;
- static const int num = 25;
+ pid_t pid = getpid();
+
+ auto logger_list1 = std::unique_ptr<struct logger_list, ListCloser>{
+ android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_RDONLY, expected_count1, pid)};
+ ASSERT_TRUE(logger_list1);
+
+ auto logger_list2 = std::unique_ptr<struct logger_list, ListCloser>{
+ android_logger_list_open(LOG_ID_MAIN, ANDROID_LOG_RDONLY, expected_count2, pid)};
+ ASSERT_TRUE(logger_list2);
for (int i = 25; i > 0; --i) {
static const char fmt[] = "dual_reader %02d";
@@ -1125,32 +1110,46 @@
LOG_FAILURE_RETRY(__android_log_buf_write(LOG_ID_MAIN, ANDROID_LOG_INFO,
"liblog", buffer));
}
- usleep(1000000);
- struct logger_list* logger_list1;
- ASSERT_TRUE(NULL != (logger_list1 = android_logger_list_open(
- LOG_ID_MAIN,
- ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, num, 0)));
+ alarm(2);
+ auto alarm_guard = android::base::make_scope_guard([] { alarm(0); });
- struct logger_list* logger_list2;
+ // Wait until we see all messages with the blocking reader.
+ int count1 = 0;
+ int count2 = 0;
- if (NULL == (logger_list2 = android_logger_list_open(
- LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK,
- num - 10, 0))) {
- android_logger_list_close(logger_list1);
- ASSERT_TRUE(NULL != logger_list2);
+ while (count1 != expected_count2 || count2 != expected_count2) {
+ log_msg log_msg;
+ if (count1 < expected_count1) {
+ ASSERT_GT(android_logger_list_read(logger_list1.get(), &log_msg), 0);
+ count1++;
+ }
+ if (count2 < expected_count2) {
+ ASSERT_GT(android_logger_list_read(logger_list2.get(), &log_msg), 0);
+ count2++;
+ }
}
- int count1 = 0;
+ // Test again with the nonblocking reader.
+ auto logger_list_non_block1 =
+ std::unique_ptr<struct logger_list, ListCloser>{android_logger_list_open(
+ LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, expected_count1, pid)};
+ ASSERT_TRUE(logger_list_non_block1);
+
+ auto logger_list_non_block2 =
+ std::unique_ptr<struct logger_list, ListCloser>{android_logger_list_open(
+ LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, expected_count2, pid)};
+ ASSERT_TRUE(logger_list_non_block2);
+ count1 = 0;
+ count2 = 0;
bool done1 = false;
- int count2 = 0;
bool done2 = false;
- do {
+ while (!done1 || !done2) {
log_msg log_msg;
if (!done1) {
- if (android_logger_list_read(logger_list1, &log_msg) <= 0) {
+ if (android_logger_list_read(logger_list_non_block1.get(), &log_msg) <= 0) {
done1 = true;
} else {
++count1;
@@ -1158,26 +1157,21 @@
}
if (!done2) {
- if (android_logger_list_read(logger_list2, &log_msg) <= 0) {
+ if (android_logger_list_read(logger_list_non_block2.get(), &log_msg) <= 0) {
done2 = true;
} else {
++count2;
}
}
- } while ((!done1) || (!done2));
+ }
- android_logger_list_close(logger_list1);
- android_logger_list_close(logger_list2);
-
- EXPECT_EQ(num, count1);
- EXPECT_EQ(num - 10, count2);
+ EXPECT_EQ(expected_count1, count1);
+ EXPECT_EQ(expected_count2, count2);
#else
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
-#endif // ENABLE_FLAKY_TESTS
-#ifdef ENABLE_FLAKY_TESTS
static bool checkPriForTag(AndroidLogFormat* p_format, const char* tag,
android_LogPriority pri) {
return android_log_shouldPrintLine(p_format, tag, pri) &&
@@ -1253,7 +1247,6 @@
android_log_format_free(p_format);
}
-#endif // ENABLE_FLAKY_TESTS
#ifdef ENABLE_FLAKY_TESTS
TEST(liblog, is_loggable) {
@@ -2632,7 +2625,6 @@
#endif
}
-#ifdef ENABLE_FLAKY_TESTS
TEST(liblog, create_android_logger_overflow) {
android_log_context ctx;
@@ -2659,7 +2651,6 @@
EXPECT_LE(0, android_log_destroy(&ctx));
ASSERT_TRUE(NULL == ctx);
}
-#endif // ENABLE_FLAKY_TESTS
#ifdef ENABLE_FLAKY_TESTS
#ifdef __ANDROID__
@@ -2800,7 +2791,6 @@
}
#endif // ENABLE_FLAKY_TESTS
-#ifdef ENABLE_FLAKY_TESTS
TEST(liblog, android_lookupEventTagNum) {
#ifdef __ANDROID__
EventTagMap* map = android_openEventTagMap(NULL);
@@ -2817,4 +2807,3 @@
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif
}
-#endif // ENABLE_FLAKY_TESTS
diff --git a/liblog/tests/log_read_test.cpp b/liblog/tests/log_read_test.cpp
index 443c3ea..1be99aa 100644
--- a/liblog/tests/log_read_test.cpp
+++ b/liblog/tests/log_read_test.cpp
@@ -29,54 +29,6 @@
// Do not use anything in log/log_time.h despite side effects of the above.
#include <private/android_logger.h>
-TEST(liblog, __android_log_write__android_logger_list_read) {
-#ifdef __ANDROID__
- pid_t pid = getpid();
-
- struct logger_list* logger_list;
- ASSERT_TRUE(
- NULL !=
- (logger_list = android_logger_list_open(
- LOG_ID_MAIN, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 1000, pid)));
-
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- std::string buf = android::base::StringPrintf("pid=%u ts=%ld.%09ld", pid,
- ts.tv_sec, ts.tv_nsec);
- static const char tag[] =
- "liblog.__android_log_write__android_logger_list_read";
- static const char prio = ANDROID_LOG_DEBUG;
- ASSERT_LT(0, __android_log_write(prio, tag, buf.c_str()));
- usleep(1000000);
-
- buf = std::string(&prio, sizeof(prio)) + tag + std::string("", 1) + buf +
- std::string("", 1);
-
- int count = 0;
-
- for (;;) {
- log_msg log_msg;
- if (android_logger_list_read(logger_list, &log_msg) <= 0) break;
-
- EXPECT_EQ(log_msg.entry.pid, pid);
- // There may be a future where we leak "liblog" tagged LOG_ID_EVENT
- // binary messages through so that logger losses can be correlated?
- EXPECT_EQ(log_msg.id(), LOG_ID_MAIN);
-
- if (log_msg.entry.len != buf.length()) continue;
-
- if (buf != std::string(log_msg.msg(), log_msg.entry.len)) continue;
-
- ++count;
- }
- android_logger_list_close(logger_list);
-
- EXPECT_EQ(1, count);
-#else
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-}
-
TEST(liblog, android_logger_get_) {
#ifdef __ANDROID__
// This test assumes the log buffers are filled with noise from
diff --git a/libprocessgroup/include/processgroup/sched_policy.h b/libprocessgroup/include/processgroup/sched_policy.h
index 3c498da..945d90c 100644
--- a/libprocessgroup/include/processgroup/sched_policy.h
+++ b/libprocessgroup/include/processgroup/sched_policy.h
@@ -70,11 +70,22 @@
extern int get_sched_policy(int tid, SchedPolicy* policy);
/* Return a displayable string corresponding to policy.
- * Return value: non-NULL NUL-terminated name of unspecified length;
+ * Return value: NUL-terminated name of unspecified length, nullptr if invalid;
* the caller is responsible for displaying the useful part of the string.
*/
extern const char* get_sched_policy_name(SchedPolicy policy);
+/* Return the aggregated task profile name corresponding to cpuset policy.
+ * Return value: NUL-terminated name of unspecified length, nullptr if invalid;
+ * the caller could use it to call SetTaskProfiles.
+ */
+extern const char* get_cpuset_policy_profile_name(SchedPolicy policy);
+
+/* Return the aggregated task profile name corresponding to sched policy.
+ * Return value: NUL-terminated name of unspecified length, nullptr if invalid;
+ * the caller could use it to call SetTaskProfiles.
+ */
+extern const char* get_sched_policy_profile_name(SchedPolicy policy);
#ifdef __cplusplus
}
#endif
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp
index 6b0ab87..16339d3 100644
--- a/libprocessgroup/sched_policy.cpp
+++ b/libprocessgroup/sched_policy.cpp
@@ -212,7 +212,45 @@
};
static_assert(arraysize(kSchedPolicyNames) == SP_CNT, "missing name");
if (policy < SP_BACKGROUND || policy >= SP_CNT) {
- return "error";
+ return nullptr;
}
return kSchedPolicyNames[policy];
}
+
+const char* get_cpuset_policy_profile_name(SchedPolicy policy) {
+ /*
+ * cpuset profile array for:
+ * SP_DEFAULT(-1), SP_BACKGROUND(0), SP_FOREGROUND(1),
+ * SP_SYSTEM(2), SP_AUDIO_APP(3), SP_AUDIO_SYS(4),
+ * SP_TOP_APP(5), SP_RT_APP(6), SP_RESTRICTED(7)
+ * index is policy + 1
+ * this need keep in sync with SchedPolicy enum
+ */
+ static constexpr const char* kCpusetProfiles[SP_CNT + 1] = {
+ "CPUSET_SP_DEFAULT", "CPUSET_SP_BACKGROUND", "CPUSET_SP_FOREGROUND",
+ "CPUSET_SP_SYSTEM", "CPUSET_SP_FOREGROUND", "CPUSET_SP_FOREGROUND",
+ "CPUSET_SP_TOP_APP", "CPUSET_SP_DEFAULT", "CPUSET_SP_RESTRICTED"};
+ if (policy < SP_DEFAULT || policy >= SP_CNT) {
+ return nullptr;
+ }
+ return kCpusetProfiles[policy + 1];
+}
+
+const char* get_sched_policy_profile_name(SchedPolicy policy) {
+ /*
+ * sched profile array for:
+ * SP_DEFAULT(-1), SP_BACKGROUND(0), SP_FOREGROUND(1),
+ * SP_SYSTEM(2), SP_AUDIO_APP(3), SP_AUDIO_SYS(4),
+ * SP_TOP_APP(5), SP_RT_APP(6), SP_RESTRICTED(7)
+ * index is policy + 1
+ * this need keep in sync with SchedPolicy enum
+ */
+ static constexpr const char* kSchedProfiles[SP_CNT + 1] = {
+ "SCHED_SP_DEFAULT", "SCHED_SP_BACKGROUND", "SCHED_SP_FOREGROUND",
+ "SCHED_SP_DEFAULT", "SCHED_SP_FOREGROUND", "SCHED_SP_FOREGROUND",
+ "SCHED_SP_TOP_APP", "SCHED_SP_RT_APP", "SCHED_SP_DEFAULT"};
+ if (policy < SP_DEFAULT || policy >= SP_CNT) {
+ return nullptr;
+ }
+ return kSchedProfiles[policy + 1];
+}
diff --git a/libunwindstack/AndroidVersions.md b/libunwindstack/AndroidVersions.md
new file mode 100644
index 0000000..234f639
--- /dev/null
+++ b/libunwindstack/AndroidVersions.md
@@ -0,0 +1,116 @@
+# Unwinder Support Per Android Release
+This document describes the changes in the way the libunwindstack
+unwinder works on different Android versions. It does not describe
+every change in the code made between different versions, but is
+meant to allow an app developer to know what might be supported
+on different versions. It also describes the different way an unwind
+will display on different versions of Android.
+
+## Android P
+libunwindstack was first introduced in Android P.
+
+* Supports up to and including Dwarf 4 unwinding information.
+ See http://dwarfstd.org/ for Dwarf standards.
+* Supports Arm exidx unwinding.
+* Supports the gdb JIT unwinding interface, which is how ART creates unwinding
+ information for the JIT'd Java frames.
+* Supports special frames added to represent an ART Java interpreter frame.
+ ART has marked the dex pc using cfi information that the unwinder
+ understands and handles by adding a new frame in the stacktrace.
+
+## Note
+By default, lld creates two separate maps of the elf in memory, one read-only
+and one read/executable. The libunwindstack on P and the unwinder on older
+versions of Android will not unwind properly in this case. For apps that
+target Android P or older, make sure that `-Wl,--no-rosegment` is
+included in linker arguments when using lld.
+
+## Android Q
+* Fix bug (b/109824792) that handled load bias data incorrectly when
+ FDEs use pc relative addressing in the eh\_frame\_hdr.
+ Unfortunately, this wasn't fixed correctly in Q since it assumes
+ that the bias is coming from the program header for the executable
+ load. The real fix was to use the bias from the actual section data and
+ is not completely fixed until Android R. For apps targeting Android Q,
+ if it is being compiled with the llvm linker lld, it might be necessary
+ to add the linker option `-Wl,-zseparate-code` to avoid creating an elf
+ created this way.
+* Change the way the exidx section offset is found (b/110704153). Before
+ the p\_vaddr value from the program header minus the load bias was used
+ to find the start of the exidx data. Changed to use the p\_offset since
+ it doesn't require any load bias manipulations.
+* Fix bug handling of dwarf sections without any header (b/110235461).
+ Previously, the code assumed that FDEs are non-overlapping, and the FDEs
+ are always in sorted order from low pc to high pc. Thus the code would
+ read the entire set of CIEs/FDEs and then do a binary search to find
+ the appropriate FDE for a given pc. Now the code does a sequential read
+ and stops when it finds the FDE for a pc. It also understands the
+ overlapping FDEs, so find the first FDE that matches a pc. In practice,
+ elf files with this format only ever occurs if the file was generated
+ without an eh\_frame/eh\_frame\_hdr section and only a debug\_frame. The
+ other way this has been observed is when running simpleperf to unwind since
+ sometimes there is not enough information in the eh\_frame for all points
+ in the executable. On Android P, this would result in some incorrect
+ unwinds coming from simpleperf. Nearly all crashes from Android P should
+ be correct since the eh\_frame information was enough to do the unwind
+ properly.
+* Be permissive of badly formed elf files. Previously, any detected error
+ would result in unwinds stopping even if there is enough valid information
+ to do an unwind.
+ * The code now allows program header/section header offsets to point
+ to unreadable memory. As long as the code can find the unwind tables,
+ that is good enough.
+ * The code allows program headers/section headers to be missing.
+ * Allow a symbol table section header to point to invalid symbol table
+ values.
+* Support for the linker read-only segment option (b/109657296).
+ This is a feature of lld whereby there are two sections that
+ contain elf data. The first is read-only and contains the elf header data,
+ and the second is read-execute or execute only that
+ contains the executable code from the elf. Before this, the unwinder
+ always assumed that there was only a single read-execute section that
+ contained the elf header data and the executable code.
+* Build ID information for elf objects added. This will display the
+ NT\_GNU\_BUILD\_ID note found in elf files. This information can be used
+ to identify the exact version of a shared library to help get symbol
+ information when looking at a crash.
+* Add support for displaying the soname from an apk frame. Previously,
+ a frame map name would be only the apk, but now if the shared library
+ in the apk has set a soname, the map name will be `app.apk!libexample.so`
+ instead of only `app.apk`.
+* Minimal support for Dwarf 5. This merely treats a Dwarf 5 version
+ elf file as Dwarf 4. It does not support the new dwarf ops in Dwarf 5.
+ Since the new ops are not likely to be used very often, this allows
+ continuing to unwind even when encountering Dwarf 5 elf files.
+* Fix bug in pc handling of signal frames (b/130302288). In the previous
+ version, the pc would be wrong in the signal frame. The rest of the
+ unwind was correct, only the frame in the signal handler was incorrect
+ in Android P.
+* Detect when an elf file is not readable so that a message can be
+ displayed indicating that. This can happen when an app puts the shared
+ libraries in non-standard locations that are not readable due to
+ security restrictions (selinux rules).
+
+## Android R
+* Display the offsets for Java interpreter frames. If this frame came
+ from a non-zero offset map, no offset is printed. Previously, the
+ line would look like:
+
+ #17 pc 00500d7a GoogleCamera.apk (com.google.camera.AndroidPriorityThread.run+10)
+
+ to:
+
+ #17 pc 00500d7a GoogleCamera.apk (offset 0x11d0000) (com.google.camera.AndroidPriorityThread.run+10)
+* Fix bug where the load bias was set from the first PT\_LOAD program
+ header that has a zero p\_offset value. Now it is set from the first
+ executable PT\_LOAD program header. This has only ever been a problem
+ for host executables compiled for the x86\_64 architecture.
+* Switched to the libc++ demangler for function names. Previously, the
+ demangler used was not complete, so some less common demangled function
+ names would not be properly demangled or the function name would not be
+ demangled at all.
+* Fix bug in load bias handling. If the unwind information in the eh\_frame
+ or eh\_frame\_hdr does not have the same bias as the executable section,
+ and uses pc relative FDEs, the unwind will be incorrect. This tends
+ to truncate unwinds since the unwinder could not find the correct unwind
+ information for a given pc.
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 9cbc7c4..ba05a06 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -1185,7 +1185,7 @@
unlock();
// range locking in LastLogTimes looks after us
- curr = element->flushTo(reader, this, privileged, sameTid);
+ curr = element->flushTo(reader, this, sameTid);
if (curr == element->FLUSH_ERROR) {
return curr;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 82c4fb9..5c43e18 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -244,14 +244,10 @@
return retval;
}
-log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
- bool privileged, bool lastSame) {
- struct logger_entry_v4 entry;
+log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent, bool lastSame) {
+ struct logger_entry_v4 entry = {};
- memset(&entry, 0, sizeof(struct logger_entry_v4));
-
- entry.hdr_size = privileged ? sizeof(struct logger_entry_v4)
- : sizeof(struct logger_entry_v3);
+ entry.hdr_size = sizeof(struct logger_entry_v4);
entry.lid = mLogId;
entry.pid = mPid;
entry.tid = mTid;
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index da4991b..fd790e4 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _LOGD_LOG_BUFFER_ELEMENT_H__
-#define _LOGD_LOG_BUFFER_ELEMENT_H__
+#pragma once
#include <stdatomic.h>
#include <stdint.h>
@@ -96,8 +95,5 @@
}
static const log_time FLUSH_ERROR;
- log_time flushTo(SocketClient* writer, LogBuffer* parent, bool privileged,
- bool lastSame);
+ log_time flushTo(SocketClient* writer, LogBuffer* parent, bool lastSame);
};
-
-#endif
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index 27e855f..405f5a9 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -17,7 +17,7 @@
libmediandk.so
libm.so
libnativewindow.so
-libneuralnetworks.so
+libneuralnetworks.so nopreload
libOpenMAXAL.so
libOpenSLES.so
libRS.so