Merge "adb: Recognize rescue mode."
diff --git a/CleanSpec.mk b/CleanSpec.mk index ebe5f4a..6f6481f 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk
@@ -80,3 +80,5 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/sbin/charger) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin/charger) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/sbin) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin)
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp index 8c33ca5..3b29ab5 100644 --- a/adb/daemon/usb.cpp +++ b/adb/daemon/usb.cpp
@@ -57,11 +57,12 @@ // We can't find out whether we have support for AIO on ffs endpoints until we submit a read. static std::optional<bool> gFfsAioSupported; +// Not all USB controllers support operations larger than 16k, so don't go above that. static constexpr size_t kUsbReadQueueDepth = 32; -static constexpr size_t kUsbReadSize = 8 * PAGE_SIZE; +static constexpr size_t kUsbReadSize = 4 * PAGE_SIZE; static constexpr size_t kUsbWriteQueueDepth = 32; -static constexpr size_t kUsbWriteSize = 8 * PAGE_SIZE; +static constexpr size_t kUsbWriteSize = 4 * PAGE_SIZE; static const char* to_string(enum usb_functionfs_event_type type) { switch (type) {
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp index 82ba0a1..c608a8c 100644 --- a/debuggerd/crash_dump.cpp +++ b/debuggerd/crash_dump.cpp
@@ -363,6 +363,12 @@ DefuseSignalHandlers(); InstallSigPipeHandler(); + // There appears to be a bug in the kernel where our death causes SIGHUP to + // be sent to our process group if we exit while it has stopped jobs (e.g. + // because of wait_for_gdb). Use setsid to create a new process group to + // avoid hitting this. + setsid(); + atrace_begin(ATRACE_TAG, "before reparent"); pid_t target_process = getppid();
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp index f0bdfbf..3041664 100644 --- a/debuggerd/crasher/crasher.cpp +++ b/debuggerd/crasher/crasher.cpp
@@ -193,6 +193,7 @@ fprintf(stderr, " kuser_memory_barrier call kuser_memory_barrier\n"); fprintf(stderr, " kuser_cmpxchg64 call kuser_cmpxchg64\n"); #endif + fprintf(stderr, " xom read execute-only memory\n"); fprintf(stderr, "\n"); fprintf(stderr, " LOG_ALWAYS_FATAL call liblog LOG_ALWAYS_FATAL\n"); fprintf(stderr, " LOG_ALWAYS_FATAL_IF call liblog LOG_ALWAYS_FATAL_IF\n"); @@ -314,6 +315,11 @@ } else if (!strcasecmp(arg, "seccomp")) { set_system_seccomp_filter(); syscall(99999); +#if defined(__LP64__) + } else if (!strcasecmp(arg, "xom")) { + // Try to read part of our code, which will fail if XOM is active. + printf("*%lx = %lx\n", reinterpret_cast<long>(usage), *reinterpret_cast<long*>(usage)); +#endif #if defined(__arm__) } else if (!strcasecmp(arg, "kuser_helper_version")) { return __kuser_helper_version;
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index bca5e36..598ea85 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -268,8 +268,15 @@ _exit(errno); } - // Exit immediately on both sides of the fork. - // crash_dump is ptracing us, so it'll get to do whatever it wants in between. + // crash_dump is ptracing both sides of the fork; it'll let the parent exit, + // but keep the orphan stopped to peek at its memory. + + // There appears to be a bug in the kernel where our death causes SIGHUP to + // be sent to our process group if we exit while it has stopped jobs (e.g. + // because of wait_for_gdb). Use setsid to create a new process group to + // avoid hitting this. + setsid(); + _exit(0); }
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp index fb51a90..511bd5c 100644 --- a/fastboot/device/usb_client.cpp +++ b/fastboot/device/usb_client.cpp
@@ -257,7 +257,7 @@ auto bytes_to_read = std::min(len - bytes_read_total, kFbFfsNumBufs * kFbFfsBufSize); auto bytes_read_now = handle_->read(handle_.get(), char_data, bytes_to_read); if (bytes_read_now < 0) { - return bytes_read_total; + return bytes_read_total == 0 ? -1 : bytes_read_total; } bytes_read_total += bytes_read_now; char_data += bytes_read_now; @@ -278,7 +278,7 @@ auto bytes_to_write = std::min(len - bytes_written_total, kFbFfsNumBufs * kFbFfsBufSize); auto bytes_written_now = handle_->write(handle_.get(), data, bytes_to_write); if (bytes_written_now < 0) { - return bytes_written_total; + return bytes_written_total == 0 ? -1 : bytes_written_total; } bytes_written_total += bytes_written_now; char_data += bytes_written_now;
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 045bb48..5114f55 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp
@@ -1268,6 +1268,46 @@ } } +int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab) { + AvbUniquePtr avb_handle(nullptr); + int ret = FsMgrUmountStatus::SUCCESS; + for (auto& current_entry : *fstab) { + if (!IsMountPointMounted(current_entry.mount_point)) { + continue; + } + + if (umount(current_entry.mount_point.c_str()) == -1) { + PERROR << "Failed to umount " << current_entry.mount_point; + ret |= FsMgrUmountStatus::ERROR_UMOUNT; + continue; + } + + if (current_entry.fs_mgr_flags.logical) { + if (!fs_mgr_update_logical_partition(¤t_entry)) { + LERROR << "Could not get logical partition blk_device, skipping!"; + ret |= FsMgrUmountStatus::ERROR_DEVICE_MAPPER; + continue; + } + } + + if (current_entry.fs_mgr_flags.avb || !current_entry.avb_keys.empty()) { + if (!AvbHandle::TearDownAvbHashtree(¤t_entry, true /* wait */)) { + LERROR << "Failed to tear down AVB on mount point: " << current_entry.mount_point; + ret |= FsMgrUmountStatus::ERROR_VERITY; + continue; + } + } else if ((current_entry.fs_mgr_flags.verify)) { + if (!fs_mgr_teardown_verity(¤t_entry, true /* wait */)) { + LERROR << "Failed to tear down verified partition on mount point: " + << current_entry.mount_point; + ret |= FsMgrUmountStatus::ERROR_VERITY; + continue; + } + } + } + return ret; +} + // wrapper to __mount() and expects a fully prepared fstab_rec, // unlike fs_mgr_do_mount which does more things with avb / verity etc. int fs_mgr_do_mount_one(const FstabEntry& entry, const std::string& mount_point) {
diff --git a/fs_mgr/fs_mgr_dm_linear.cpp b/fs_mgr/fs_mgr_dm_linear.cpp index 45cbff3..ee6ffdb 100644 --- a/fs_mgr/fs_mgr_dm_linear.cpp +++ b/fs_mgr/fs_mgr_dm_linear.cpp
@@ -193,7 +193,7 @@ timeout_ms, path); } -bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) { +bool UnmapDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms) { DeviceMapper& dm = DeviceMapper::Instance(); std::string path; if (timeout_ms > std::chrono::milliseconds::zero()) { @@ -206,6 +206,13 @@ LERROR << "Timed out waiting for device path to unlink: " << path; return false; } + return true; +} + +bool DestroyLogicalPartition(const std::string& name, const std::chrono::milliseconds& timeout_ms) { + if (!UnmapDevice(name, timeout_ms)) { + return false; + } LINFO << "Unmapped logical partition " << name; return true; }
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 11602ea..70abf5b 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h
@@ -103,3 +103,11 @@ bool fs_mgr_is_ext4(const std::string& blk_device); bool fs_mgr_is_f2fs(const std::string& blk_device); + +bool fs_mgr_teardown_verity(android::fs_mgr::FstabEntry* fstab, bool wait); + +namespace android { +namespace fs_mgr { +bool UnmapDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms); +} // namespace fs_mgr +} // namespace android
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index c53e866..3f09157 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp
@@ -44,6 +44,7 @@ #include "fec/io.h" #include "fs_mgr.h" +#include "fs_mgr_dm_linear.h" #include "fs_mgr_priv.h" // Realistically, this file should be part of the android::fs_mgr namespace; @@ -882,3 +883,12 @@ return retval; } + +bool fs_mgr_teardown_verity(FstabEntry* entry, bool wait) { + const std::string mount_point(basename(entry->mount_point.c_str())); + if (!android::fs_mgr::UnmapDevice(mount_point, wait ? 1000ms : 0ms)) { + return false; + } + LINFO << "Unmapped verity device " << mount_point; + return true; +}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h index 8abe609..88b2f8f 100644 --- a/fs_mgr/include/fs_mgr.h +++ b/fs_mgr/include/fs_mgr.h
@@ -93,3 +93,14 @@ // specified, the super partition for the corresponding metadata slot will be // returned. Otherwise, it will use the current slot. std::string fs_mgr_get_super_partition_name(int slot = -1); + +enum FsMgrUmountStatus : int { + SUCCESS = 0, + ERROR_UNKNOWN = 1 << 0, + ERROR_UMOUNT = 1 << 1, + ERROR_VERITY = 1 << 2, + ERROR_DEVICE_MAPPER = 1 << 3, +}; +// fs_mgr_umount_all() is the reverse of fs_mgr_mount_all. In particular, +// it destroys verity devices from device mapper after the device is unmounted. +int fs_mgr_umount_all(android::fs_mgr::Fstab* fstab);
diff --git a/fs_mgr/libfs_avb/fs_avb.cpp b/fs_mgr/libfs_avb/fs_avb.cpp index f0767dc..04776ed 100644 --- a/fs_mgr/libfs_avb/fs_avb.cpp +++ b/fs_mgr/libfs_avb/fs_avb.cpp
@@ -449,6 +449,29 @@ return AvbHashtreeResult::kSuccess; } +bool AvbHandle::TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait) { + if (!fstab_entry) { + return false; + } + + const std::string device_name(GetVerityDeviceName(*fstab_entry)); + + // TODO: remove duplicated code with UnmapDevice() + android::dm::DeviceMapper& dm = android::dm::DeviceMapper::Instance(); + std::string path; + if (wait) { + dm.GetDmDevicePathByName(device_name, &path); + } + if (!dm.DeleteDevice(device_name)) { + return false; + } + if (!path.empty() && !WaitForFile(path, 1000ms, FileWaitMode::DoesNotExist)) { + return false; + } + + return true; +} + std::string AvbHandle::GetSecurityPatchLevel(const FstabEntry& fstab_entry) const { if (vbmeta_images_.size() < 1) { return "";
diff --git a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h index 7127fa6..521f2d5 100644 --- a/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h +++ b/fs_mgr/libfs_avb/include/fs_avb/fs_avb.h
@@ -110,6 +110,11 @@ static AvbHashtreeResult SetUpStandaloneAvbHashtree(FstabEntry* fstab_entry, bool wait_for_verity_dev = true); + // Tear down dm devices created by SetUp[Standalone]AvbHashtree + // The 'wait' parameter makes this function wait for the verity device to get destroyed + // before return. + static bool TearDownAvbHashtree(FstabEntry* fstab_entry, bool wait); + static bool IsDeviceUnlocked(); std::string GetSecurityPatchLevel(const FstabEntry& fstab_entry) const;
diff --git a/fs_mgr/libfs_avb/tests/util_test.cpp b/fs_mgr/libfs_avb/tests/util_test.cpp index 9e37d22..12b5acb 100644 --- a/fs_mgr/libfs_avb/tests/util_test.cpp +++ b/fs_mgr/libfs_avb/tests/util_test.cpp
@@ -27,6 +27,7 @@ // Target functions to test: using android::fs_mgr::BytesToHex; +using android::fs_mgr::FileWaitMode; using android::fs_mgr::HexToBytes; using android::fs_mgr::NibbleValue; using android::fs_mgr::WaitForFile; @@ -175,7 +176,7 @@ // Waits this path. base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir"); ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */)); - auto wait_file = std::async(WaitForFile, wait_path.value(), 500ms); + auto wait_file = std::async(WaitForFile, wait_path.value(), 500ms, FileWaitMode::Exists); // Sleeps 100ms before creating the wait_path. std::this_thread::sleep_for(100ms); @@ -196,7 +197,7 @@ // Waits this path. base::FilePath wait_path = tmp_dir.Append("libfs_avb-test-exist-dir"); ASSERT_TRUE(base::DeleteFile(wait_path, false /* resursive */)); - auto wait_file = std::async(WaitForFile, wait_path.value(), 50ms); + auto wait_file = std::async(WaitForFile, wait_path.value(), 50ms, FileWaitMode::Exists); // Sleeps 100ms before creating the wait_path. std::this_thread::sleep_for(100ms);
diff --git a/fs_mgr/libfs_avb/util.cpp b/fs_mgr/libfs_avb/util.cpp index 9d4f05f..d214b5b 100644 --- a/fs_mgr/libfs_avb/util.cpp +++ b/fs_mgr/libfs_avb/util.cpp
@@ -82,12 +82,17 @@ return hex; } -bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout) { +// TODO: remove duplicate code with fs_mgr_wait_for_file +bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout, + FileWaitMode file_wait_mode) { auto start_time = std::chrono::steady_clock::now(); while (true) { - if (0 == access(filename.c_str(), F_OK) || errno != ENOENT) { - return true; + int rv = access(filename.c_str(), F_OK); + if (file_wait_mode == FileWaitMode::Exists) { + if (!rv || errno != ENOENT) return true; + } else if (file_wait_mode == FileWaitMode::DoesNotExist) { + if (rv && errno == ENOENT) return true; } std::this_thread::sleep_for(50ms);
diff --git a/fs_mgr/libfs_avb/util.h b/fs_mgr/libfs_avb/util.h index cb861f4..7763da5 100644 --- a/fs_mgr/libfs_avb/util.h +++ b/fs_mgr/libfs_avb/util.h
@@ -52,7 +52,9 @@ std::string BytesToHex(const uint8_t* bytes, size_t bytes_len); -bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout); +enum class FileWaitMode { Exists, DoesNotExist }; +bool WaitForFile(const std::string& filename, const std::chrono::milliseconds relative_timeout, + FileWaitMode wait_mode = FileWaitMode::Exists); bool IsDeviceUnlocked();
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 27222af..41c01da 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp
@@ -1057,7 +1057,7 @@ if (sABOverrideSet) { return sABOverrideValue; } - return android::base::GetBoolProperty("ro.build.ab_update", false); + return !android::base::GetProperty("ro.boot.slot_suffix", "").empty(); } bool MetadataBuilder::IsRetrofitDevice() const {
diff --git a/fs_mgr/liblp/partition_opener.cpp b/fs_mgr/liblp/partition_opener.cpp index bb8ec9c..3b12213 100644 --- a/fs_mgr/liblp/partition_opener.cpp +++ b/fs_mgr/liblp/partition_opener.cpp
@@ -26,6 +26,7 @@ #include <unistd.h> #include <android-base/file.h> +#include <android-base/strings.h> #include "utility.h" @@ -37,7 +38,7 @@ namespace { std::string GetPartitionAbsolutePath(const std::string& path) { - if (path[0] == '/') { + if (android::base::StartsWith(path, "/")) { return path; } return "/dev/block/by-name/" + path;
diff --git a/init/README.md b/init/README.md index aadf11d..51deb5a 100644 --- a/init/README.md +++ b/init/README.md
@@ -488,7 +488,11 @@ This is included in the default init.rc. `loglevel <level>` -> Sets the kernel log level to level. Properties are expanded within _level_. +> Sets init's log level to the integer level, from 7 (all logging) to 0 + (fatal logging only). The numeric values correspond to the kernel log + levels, but this command does not affect the kernel log level. Use the + `write` command to write to `/proc/sys/kernel/printk` to change that. + Properties are expanded within _level_. `mkdir <path> [mode] [owner] [group]` > Create a directory at _path_, optionally with the given mode, owner, and
diff --git a/init/builtins.cpp b/init/builtins.cpp index 8437e37..06da4be 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp
@@ -451,52 +451,6 @@ if (false) DumpState(); } -/* mount_fstab - * - * Call fs_mgr_mount_all() to mount the given fstab - */ -static Result<int> mount_fstab(const char* fstabfile, int mount_mode) { - /* - * Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and - * do the call in the child to provide protection to the main init - * process if anything goes wrong (crash or memory leak), and wait for - * the child to finish in the parent. - */ - pid_t pid = fork(); - if (pid > 0) { - /* Parent. Wait for the child to return */ - int status; - int wp_ret = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0)); - if (wp_ret == -1) { - // Unexpected error code. We will continue anyway. - PLOG(WARNING) << "waitpid failed"; - } - - if (WIFEXITED(status)) { - return WEXITSTATUS(status); - } else { - return Error() << "child aborted"; - } - } else if (pid == 0) { - /* child, call fs_mgr_mount_all() */ - - // So we can always see what fs_mgr_mount_all() does. - // Only needed if someone explicitly changes the default log level in their init.rc. - android::base::ScopedLogSeverity info(android::base::INFO); - - Fstab fstab; - ReadFstabFromFile(fstabfile, &fstab); - - int child_ret = fs_mgr_mount_all(&fstab, mount_mode); - if (child_ret == -1) { - PLOG(ERROR) << "fs_mgr_mount_all returned an error"; - } - _exit(child_ret); - } else { - return Error() << "fork() failed"; - } -} - /* Queue event based on fs_mgr return code. * * code: return code of fs_mgr_mount_all @@ -583,7 +537,7 @@ bool import_rc = true; bool queue_event = true; int mount_mode = MOUNT_MODE_DEFAULT; - const char* fstabfile = args[1].c_str(); + const auto& fstab_file = args[1]; std::size_t path_arg_end = args.size(); const char* prop_post_fix = "default"; @@ -603,10 +557,12 @@ std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix; android::base::Timer t; - auto mount_fstab_return_code = mount_fstab(fstabfile, mount_mode); - if (!mount_fstab_return_code) { - return Error() << "mount_fstab() failed " << mount_fstab_return_code.error(); + + Fstab fstab; + if (!ReadFstabFromFile(fstab_file, &fstab)) { + return Error() << "Could not read fstab"; } + auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode); property_set(prop_name, std::to_string(t.duration().count())); if (import_rc) { @@ -617,7 +573,7 @@ if (queue_event) { /* queue_fs_event will queue event based on mount_fstab return code * and return processed return code*/ - auto queue_fs_result = queue_fs_event(*mount_fstab_return_code); + auto queue_fs_result = queue_fs_event(mount_fstab_return_code); if (!queue_fs_result) { return Error() << "queue_fs_event() failed: " << queue_fs_result.error(); } @@ -626,6 +582,19 @@ return Success(); } +/* umount_all <fstab> */ +static Result<Success> do_umount_all(const BuiltinArguments& args) { + Fstab fstab; + if (!ReadFstabFromFile(args[1], &fstab)) { + return Error() << "Could not read fstab"; + } + + if (auto result = fs_mgr_umount_all(&fstab); result != 0) { + return Error() << "umount_fstab() failed " << result; + } + return Success(); +} + static Result<Success> do_swapon_all(const BuiltinArguments& args) { Fstab fstab; if (!ReadFstabFromFile(args[1], &fstab)) { @@ -1165,6 +1134,7 @@ {"mount", {3, kMax, {false, do_mount}}}, {"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}}, {"umount", {1, 1, {false, do_umount}}}, + {"umount_all", {1, 1, {false, do_umount_all}}}, {"readahead", {1, 2, {true, do_readahead}}}, {"restart", {1, 1, {false, do_restart}}}, {"restorecon", {1, kMax, {true, do_restorecon}}},
diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp index 6bec63c..71980d7 100644 --- a/libbacktrace/Backtrace.cpp +++ b/libbacktrace/Backtrace.cpp
@@ -170,5 +170,7 @@ return "Failed to unwind due to invalid unwind information"; case BACKTRACE_UNWIND_ERROR_REPEATED_FRAME: return "Failed to unwind due to same sp/pc repeating"; + case BACKTRACE_UNWIND_ERROR_INVALID_ELF: + return "Failed to unwind due to invalid elf"; } }
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp index f5f9b2a..36640cd 100644 --- a/libbacktrace/UnwindStack.cpp +++ b/libbacktrace/UnwindStack.cpp
@@ -89,6 +89,10 @@ case unwindstack::ERROR_REPEATED_FRAME: error->error_code = BACKTRACE_UNWIND_ERROR_REPEATED_FRAME; break; + + case unwindstack::ERROR_INVALID_ELF: + error->error_code = BACKTRACE_UNWIND_ERROR_INVALID_ELF; + break; } }
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h index 10e790b..404e7e8 100644 --- a/libbacktrace/include/backtrace/Backtrace.h +++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -64,6 +64,8 @@ BACKTRACE_UNWIND_ERROR_UNWIND_INFO, // Unwind information stopped due to sp/pc repeating. BACKTRACE_UNWIND_ERROR_REPEATED_FRAME, + // Unwind information stopped due to invalid elf. + BACKTRACE_UNWIND_ERROR_INVALID_ELF, }; struct BacktraceUnwindError {
diff --git a/libkeyutils/mini_keyctl_utils.cpp b/libkeyutils/mini_keyctl_utils.cpp index b012a33..79b4680 100644 --- a/libkeyutils/mini_keyctl_utils.cpp +++ b/libkeyutils/mini_keyctl_utils.cpp
@@ -67,7 +67,7 @@ if (tokens.size() < 9) { continue; } - std::string key_id = tokens[0]; + std::string key_id = "0x" + tokens[0]; std::string key_type = tokens[7]; // The key description may contain space. std::string key_desc_prefix = tokens[8]; @@ -77,7 +77,7 @@ continue; } if (!android::base::ParseInt(key_id.c_str(), &keyring_id)) { - error(1, 0, "Unexpected key format in /proc/keys"); + error(1, 0, "Unexpected key format in /proc/keys: %s", key_id.c_str()); return -1; } return keyring_id;
diff --git a/libmeminfo/tools/procrank.cpp b/libmeminfo/tools/procrank.cpp index 5e89254..cb3757d 100644 --- a/libmeminfo/tools/procrank.cpp +++ b/libmeminfo/tools/procrank.cpp
@@ -42,7 +42,6 @@ public: ProcessRecord(pid_t pid, bool get_wss = false, uint64_t pgflags = 0, uint64_t pgflags_mask = 0) : pid_(-1), - procmem_(nullptr), oomadj_(OOM_SCORE_ADJ_MAX + 1), cmdline_(""), proportional_swap_(0), @@ -79,15 +78,15 @@ // The .c_str() assignment below then takes care of trimming the cmdline at the first // 0x00. This is how original procrank worked (luckily) cmdline_.resize(strlen(cmdline_.c_str())); - procmem_ = std::move(procmem); + usage_or_wss_ = get_wss ? procmem->Wss() : procmem->Usage(); + swap_offsets_ = procmem->SwapOffsets(); pid_ = pid; } bool valid() const { return pid_ != -1; } void CalculateSwap(const uint16_t* swap_offset_array, float zram_compression_ratio) { - const std::vector<uint16_t>& swp_offs = procmem_->SwapOffsets(); - for (auto& off : swp_offs) { + for (auto& off : swap_offsets_) { proportional_swap_ += getpagesize() / swap_offset_array[off]; unique_swap_ += swap_offset_array[off] == 1 ? getpagesize() : 0; zswap_ = proportional_swap_ * zram_compression_ratio; @@ -103,18 +102,19 @@ uint64_t zswap() const { return zswap_; } // Wrappers to ProcMemInfo - const std::vector<uint16_t>& SwapOffsets() const { return procmem_->SwapOffsets(); } - const MemUsage& Usage() const { return procmem_->Usage(); } - const MemUsage& Wss() const { return procmem_->Wss(); } + const std::vector<uint16_t>& SwapOffsets() const { return swap_offsets_; } + const MemUsage& Usage() const { return usage_or_wss_; } + const MemUsage& Wss() const { return usage_or_wss_; } private: pid_t pid_; - std::unique_ptr<ProcMemInfo> procmem_; int32_t oomadj_; std::string cmdline_; uint64_t proportional_swap_; uint64_t unique_swap_; uint64_t zswap_; + MemUsage usage_or_wss_; + std::vector<uint16_t> swap_offsets_; }; // Show working set instead of memory consumption @@ -171,7 +171,7 @@ while ((dir = readdir(procdir.get()))) { if (!::android::base::ParseInt(dir->d_name, &pid)) continue; if (!for_each_pid(pid)) return false; - pids->push_back(pid); + pids->emplace_back(pid); } return true; @@ -471,7 +471,7 @@ } // Skip processes with no memory mappings - uint64_t vss = proc.Usage().vss; + uint64_t vss = show_wss ? proc.Wss().vss : proc.Usage().vss; if (vss == 0) return true; // collect swap_offset counts from all processes in 1st pass @@ -481,7 +481,7 @@ return false; } - procs.push_back(std::move(proc)); + procs.emplace_back(std::move(proc)); return true; };
diff --git a/libprocessgroup/sched_policy.cpp b/libprocessgroup/sched_policy.cpp index c7d0cca..ab0f1ca 100644 --- a/libprocessgroup/sched_policy.cpp +++ b/libprocessgroup/sched_policy.cpp
@@ -126,24 +126,15 @@ switch (policy) { case SP_BACKGROUND: - return SetTaskProfiles(tid, {"HighEnergySaving", "LowIoPriority", "TimerSlackHigh"}) - ? 0 - : -1; + return SetTaskProfiles(tid, {"HighEnergySaving", "TimerSlackHigh"}) ? 0 : -1; case SP_FOREGROUND: case SP_AUDIO_APP: case SP_AUDIO_SYS: - return SetTaskProfiles(tid, {"HighPerformance", "HighIoPriority", "TimerSlackNormal"}) - ? 0 - : -1; + return SetTaskProfiles(tid, {"HighPerformance", "TimerSlackNormal"}) ? 0 : -1; case SP_TOP_APP: - return SetTaskProfiles(tid, {"MaxPerformance", "MaxIoPriority", "TimerSlackNormal"}) - ? 0 - : -1; + return SetTaskProfiles(tid, {"MaxPerformance", "TimerSlackNormal"}) ? 0 : -1; case SP_RT_APP: - return SetTaskProfiles(tid, - {"RealtimePerformance", "MaxIoPriority", "TimerSlackNormal"}) - ? 0 - : -1; + return SetTaskProfiles(tid, {"RealtimePerformance", "TimerSlackNormal"}) ? 0 : -1; default: return SetTaskProfiles(tid, {"TimerSlackNormal"}) ? 0 : -1; }
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp index 4b93abb..3454913 100644 --- a/libunwindstack/Elf.cpp +++ b/libunwindstack/Elf.cpp
@@ -160,7 +160,7 @@ if (valid_) { return interface_->LastErrorCode(); } - return ERROR_NONE; + return ERROR_INVALID_ELF; } uint64_t Elf::GetLastErrorAddress() { @@ -170,22 +170,23 @@ return 0; } +// The relative pc expectd by this function is relative to the start of the elf. +bool Elf::StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory) { + if (!valid_) { + return false; + } + return regs->StepIfSignalHandler(rel_pc, this, process_memory); +} + // The relative pc is always relative to the start of the map from which it comes. -bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory, - bool* finished) { +bool Elf::Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished) { if (!valid_) { return false; } - // The relative pc expectd by StepIfSignalHandler is relative to the start of the elf. - if (regs->StepIfSignalHandler(rel_pc, this, process_memory)) { - *finished = false; - return true; - } - // Lock during the step which can update information in the object. std::lock_guard<std::mutex> guard(lock_); - return interface_->Step(adjusted_rel_pc, regs, process_memory, finished); + return interface_->Step(rel_pc, regs, process_memory, finished); } bool Elf::IsValidElf(Memory* memory) {
diff --git a/libunwindstack/LocalUnwinder.cpp b/libunwindstack/LocalUnwinder.cpp index 5b2fadf..5d81200 100644 --- a/libunwindstack/LocalUnwinder.cpp +++ b/libunwindstack/LocalUnwinder.cpp
@@ -111,6 +111,14 @@ pc_adjustment = 0; } step_pc -= pc_adjustment; + + bool finished = false; + if (elf->StepIfSignalHandler(rel_pc, regs.get(), process_memory_.get())) { + step_pc = rel_pc; + } else if (!elf->Step(step_pc, regs.get(), process_memory_.get(), &finished)) { + finished = true; + } + // Skip any locations that are within this library. if (num_frames != 0 || !ShouldSkipLibrary(map_info->name)) { // Add frame information. @@ -124,22 +132,12 @@ } num_frames++; } - if (!elf->valid()) { - break; - } - if (frame_info->size() == max_frames) { - break; - } + if (finished || frame_info->size() == max_frames || + (cur_pc == regs->pc() && cur_sp == regs->sp())) { + break; + } adjust_pc = true; - bool finished; - if (!elf->Step(rel_pc, step_pc, regs.get(), process_memory_.get(), &finished) || finished) { - break; - } - // pc and sp are the same, terminate the unwind. - if (cur_pc == regs->pc() && cur_sp == regs->sp()) { - break; - } } return num_frames != 0; }
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp index 3f2e1c1..f3d2b5e 100644 --- a/libunwindstack/Unwinder.cpp +++ b/libunwindstack/Unwinder.cpp
@@ -89,8 +89,8 @@ #endif } -void Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc, - uint64_t pc_adjustment) { +FrameData* Unwinder::FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, + uint64_t pc_adjustment) { size_t frame_num = frames_.size(); frames_.resize(frame_num + 1); FrameData* frame = &frames_.at(frame_num); @@ -100,7 +100,8 @@ frame->pc = regs_->pc() - pc_adjustment; if (map_info == nullptr) { - return; + // Nothing else to update. + return nullptr; } if (resolve_names_) { @@ -118,12 +119,7 @@ frame->map_end = map_info->end; frame->map_flags = map_info->flags; frame->map_load_bias = elf->GetLoadBias(); - - if (!resolve_names_ || - !elf->GetFunctionName(func_pc, &frame->function_name, &frame->function_offset)) { - frame->function_name = ""; - frame->function_offset = 0; - } + return frame; } static bool ShouldStop(const std::vector<std::string>* map_suffixes_to_ignore, @@ -194,6 +190,7 @@ } } + FrameData* frame = nullptr; if (map_info == nullptr || initial_map_names_to_skip == nullptr || std::find(initial_map_names_to_skip->begin(), initial_map_names_to_skip->end(), basename(map_info->name.c_str())) == initial_map_names_to_skip->end()) { @@ -210,23 +207,21 @@ } } - FillInFrame(map_info, elf, rel_pc, step_pc, pc_adjustment); + frame = FillInFrame(map_info, elf, rel_pc, pc_adjustment); // Once a frame is added, stop skipping frames. initial_map_names_to_skip = nullptr; } adjust_pc = true; - bool stepped; + bool stepped = false; bool in_device_map = false; - if (map_info == nullptr) { - stepped = false; - } else { + bool finished = false; + if (map_info != nullptr) { if (map_info->flags & MAPS_FLAGS_DEVICE_MAP) { // Do not stop here, fall through in case we are // in the speculative unwind path and need to remove // some of the speculative frames. - stepped = false; in_device_map = true; } else { MapInfo* sp_info = maps_->Find(regs_->sp()); @@ -234,19 +229,37 @@ // Do not stop here, fall through in case we are // in the speculative unwind path and need to remove // some of the speculative frames. - stepped = false; in_device_map = true; } else { - bool finished; - stepped = elf->Step(rel_pc, step_pc, regs_, process_memory_.get(), &finished); - elf->GetLastError(&last_error_); - if (stepped && finished) { - break; + if (elf->StepIfSignalHandler(rel_pc, regs_, process_memory_.get())) { + stepped = true; + if (frame != nullptr) { + // Need to adjust the relative pc because the signal handler + // pc should not be adjusted. + frame->rel_pc = rel_pc; + frame->pc += pc_adjustment; + step_pc = rel_pc; + } + } else if (elf->Step(step_pc, regs_, process_memory_.get(), &finished)) { + stepped = true; } + elf->GetLastError(&last_error_); } } } + if (frame != nullptr) { + if (!resolve_names_ || + !elf->GetFunctionName(step_pc, &frame->function_name, &frame->function_offset)) { + frame->function_name = ""; + frame->function_offset = 0; + } + } + + if (finished) { + break; + } + if (!stepped) { if (return_address_attempt) { // Only remove the speculative frame if there are more than two frames
diff --git a/libunwindstack/include/unwindstack/Elf.h b/libunwindstack/include/unwindstack/Elf.h index ac94f10..56bf318 100644 --- a/libunwindstack/include/unwindstack/Elf.h +++ b/libunwindstack/include/unwindstack/Elf.h
@@ -67,8 +67,9 @@ uint64_t GetRelPc(uint64_t pc, const MapInfo* map_info); - bool Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, Regs* regs, Memory* process_memory, - bool* finished); + bool StepIfSignalHandler(uint64_t rel_pc, Regs* regs, Memory* process_memory); + + bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory, bool* finished); ElfInterface* CreateInterfaceFromMemory(Memory* memory);
diff --git a/libunwindstack/include/unwindstack/Error.h b/libunwindstack/include/unwindstack/Error.h index 6ed0e0f..72ec454 100644 --- a/libunwindstack/include/unwindstack/Error.h +++ b/libunwindstack/include/unwindstack/Error.h
@@ -29,6 +29,7 @@ ERROR_INVALID_MAP, // Unwind in an invalid map. ERROR_MAX_FRAMES_EXCEEDED, // The number of frames exceed the total allowed. ERROR_REPEATED_FRAME, // The last frame has the same pc/sp as the next. + ERROR_INVALID_ELF, // Unwind in an invalid elf. }; struct ErrorData {
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h index 8b01654..75be209 100644 --- a/libunwindstack/include/unwindstack/Unwinder.h +++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -118,8 +118,7 @@ Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } void FillInDexFrame(); - void FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc, - uint64_t pc_adjustment); + FrameData* FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t pc_adjustment); size_t max_frames_; Maps* maps_;
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp index 23c9cf8..c432d6d 100644 --- a/libunwindstack/tests/ElfTest.cpp +++ b/libunwindstack/tests/ElfTest.cpp
@@ -132,8 +132,12 @@ uint64_t func_offset; ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset)); + ASSERT_FALSE(elf.StepIfSignalHandler(0, nullptr, nullptr)); + EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode()); + bool finished; - ASSERT_FALSE(elf.Step(0, 0, nullptr, nullptr, &finished)); + ASSERT_FALSE(elf.Step(0, nullptr, nullptr, &finished)); + EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode()); } TEST_F(ElfTest, elf32_invalid_machine) { @@ -295,9 +299,8 @@ } elf.FakeSetValid(true); - bool finished; - ASSERT_TRUE(elf.Step(0x3000, 0x1000, ®s, &process_memory, &finished)); - EXPECT_FALSE(finished); + ASSERT_TRUE(elf.StepIfSignalHandler(0x3000, ®s, &process_memory)); + EXPECT_EQ(ERROR_NONE, elf.GetLastErrorCode()); EXPECT_EQ(15U, regs.pc()); EXPECT_EQ(13U, regs.sp()); } @@ -336,7 +339,7 @@ EXPECT_CALL(*interface, Step(0x1000, ®s, &process_memory, &finished)) .WillOnce(::testing::Return(true)); - ASSERT_TRUE(elf.Step(0x1004, 0x1000, ®s, &process_memory, &finished)); + ASSERT_TRUE(elf.Step(0x1000, ®s, &process_memory, &finished)); } TEST_F(ElfTest, get_global_invalid_elf) {
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp index 02ba9c8..6c64c40 100644 --- a/libunwindstack/tests/UnwindOfflineTest.cpp +++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -1215,7 +1215,7 @@ " #02 pc 0032bff3 libunwindstack_test (SignalOuterFunction+2)\n" " #03 pc 0032fed3 libunwindstack_test " "(unwindstack::SignalCallerHandler(int, siginfo*, void*)+26)\n" - " #04 pc 00026528 libc.so\n" + " #04 pc 0002652c libc.so (__restore)\n" " #05 pc 00000000 <unknown>\n" " #06 pc 0032c2d9 libunwindstack_test (InnerFunction+736)\n" " #07 pc 0032cc4f libunwindstack_test (MiddleFunction+42)\n" @@ -1243,7 +1243,7 @@ EXPECT_EQ(0xf43d2ce8U, unwinder.frames()[2].sp); EXPECT_EQ(0x2e59ed3U, unwinder.frames()[3].pc); EXPECT_EQ(0xf43d2cf0U, unwinder.frames()[3].sp); - EXPECT_EQ(0xf4136528U, unwinder.frames()[4].pc); + EXPECT_EQ(0xf413652cU, unwinder.frames()[4].pc); EXPECT_EQ(0xf43d2d10U, unwinder.frames()[4].sp); EXPECT_EQ(0U, unwinder.frames()[5].pc); EXPECT_EQ(0xffcc0ee0U, unwinder.frames()[5].sp); @@ -1326,7 +1326,7 @@ " #00 pc 000000000014ccbc linker64 (__dl_syscall+28)\n" " #01 pc 000000000005426c linker64 " "(__dl__ZL24debuggerd_signal_handleriP7siginfoPv+1128)\n" - " #02 pc 00000000000008bc vdso.so\n" + " #02 pc 00000000000008c0 vdso.so (__kernel_rt_sigreturn)\n" " #03 pc 00000000000846f4 libc.so (abort+172)\n" " #04 pc 0000000000084ad4 libc.so (__assert2+36)\n" " #05 pc 000000000003d5b4 ANGLEPrebuilt.apk!libfeature_support_angle.so (offset 0x4000) " @@ -1338,7 +1338,7 @@ EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[0].sp); EXPECT_EQ(0x7e82b5726cULL, unwinder.frames()[1].pc); EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[1].sp); - EXPECT_EQ(0x7e82b018bcULL, unwinder.frames()[2].pc); + EXPECT_EQ(0x7e82b018c0ULL, unwinder.frames()[2].pc); EXPECT_EQ(0x7df8ca3da0ULL, unwinder.frames()[2].sp); EXPECT_EQ(0x7e7eecc6f4ULL, unwinder.frames()[3].pc); EXPECT_EQ(0x7dabf3db60ULL, unwinder.frames()[3].sp); @@ -1366,7 +1366,7 @@ " #00 pc 000000000014ccbc linker64 (__dl_syscall+28)\n" " #01 pc 000000000005426c linker64 " "(__dl__ZL24debuggerd_signal_handleriP7siginfoPv+1128)\n" - " #02 pc 00000000000008bc vdso.so\n" + " #02 pc 00000000000008c0 vdso.so (__kernel_rt_sigreturn)\n" " #03 pc 00000000000846f4 libc.so (abort+172)\n" " #04 pc 0000000000084ad4 libc.so (__assert2+36)\n" " #05 pc 000000000003d5b4 ANGLEPrebuilt.apk (offset 0x21d5000)\n" @@ -1377,7 +1377,7 @@ EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[0].sp); EXPECT_EQ(0x7e82b5726cULL, unwinder.frames()[1].pc); EXPECT_EQ(0x7df8ca3bf0ULL, unwinder.frames()[1].sp); - EXPECT_EQ(0x7e82b018bcULL, unwinder.frames()[2].pc); + EXPECT_EQ(0x7e82b018c0ULL, unwinder.frames()[2].pc); EXPECT_EQ(0x7df8ca3da0ULL, unwinder.frames()[2].sp); EXPECT_EQ(0x7e7eecc6f4ULL, unwinder.frames()[3].pc); EXPECT_EQ(0x7dabf3db60ULL, unwinder.frames()[3].sp);
diff --git a/rootdir/Android.mk b/rootdir/Android.mk index 462ae8b..0044534 100644 --- a/rootdir/Android.mk +++ b/rootdir/Android.mk
@@ -97,7 +97,7 @@ # # create some directories (some are mount points) and symlinks LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \ - sbin dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \ + dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \ ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \ ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \ ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \
diff --git a/rootdir/etc/ld.config.legacy.txt b/rootdir/etc/ld.config.legacy.txt index 8792671..e081bdf 100644 --- a/rootdir/etc/ld.config.legacy.txt +++ b/rootdir/etc/ld.config.legacy.txt
@@ -99,7 +99,6 @@ namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors namespace.media.links = default -namespace.media.link.default.shared_libs = libandroid.so namespace.media.link.default.shared_libs += libbinder_ndk.so namespace.media.link.default.shared_libs += libc.so namespace.media.link.default.shared_libs += libcgrouprc.so
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt index b486411..3f9882a 100644 --- a/rootdir/etc/ld.config.txt +++ b/rootdir/etc/ld.config.txt
@@ -179,7 +179,6 @@ namespace.media.links = default namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES% -namespace.media.link.default.shared_libs += libandroid.so namespace.media.link.default.shared_libs += libbinder_ndk.so namespace.media.link.default.shared_libs += libmediametrics.so namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES% @@ -622,7 +621,6 @@ namespace.media.links = default namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES% -namespace.media.link.default.shared_libs += libandroid.so namespace.media.link.default.shared_libs += libbinder_ndk.so namespace.media.link.default.shared_libs += libmediametrics.so namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt index 12007dc..6d89886 100644 --- a/rootdir/etc/ld.config.vndk_lite.txt +++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -121,7 +121,6 @@ namespace.media.links = default namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES% -namespace.media.link.default.shared_libs += libandroid.so namespace.media.link.default.shared_libs += libbinder_ndk.so namespace.media.link.default.shared_libs += libmediametrics.so namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES% @@ -445,7 +444,6 @@ namespace.media.links = default namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES% -namespace.media.link.default.shared_libs += libandroid.so namespace.media.link.default.shared_libs += libbinder_ndk.so namespace.media.link.default.shared_libs += libmediametrics.so namespace.media.link.default.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%