From 8dff17c1f979147b8091c8bee1f9f000cb266c77 Mon Sep 17 00:00:00 2001 From: JingMatrix Date: Sun, 8 Dec 2024 23:38:20 +0100 Subject: [PATCH] Fix log watchdog logic Log watchdog is meant to revert changes to the system prop `persist.log.tag`, which sets global log level, see docs at https://cs.android.com/android/platform/superproject/main/+/main:system/logging/logd/README.property Current commit fixes the following: 1. avoid recast size value `-1` to unsigned integer type size_t; 2. allow the `Enable log watchdog` to removed added system prop and restart the watchdog forcely. --- daemon/src/main/jni/logcat.cpp | 43 ++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/daemon/src/main/jni/logcat.cpp b/daemon/src/main/jni/logcat.cpp index 12f0ca9b503..0b95be6f27c 100644 --- a/daemon/src/main/jni/logcat.cpp +++ b/daemon/src/main/jni/logcat.cpp @@ -7,8 +7,6 @@ #include #include -#include -#include #include #include #include @@ -17,7 +15,7 @@ using namespace std::string_view_literals; using namespace std::chrono_literals; constexpr size_t kMaxLogSize = 4 * 1024 * 1024; -constexpr size_t kLogBufferSize = 64 * 1024; +constexpr long kLogBufferSize = 64 * 1024; namespace { constexpr std::array kLogChar = { @@ -32,7 +30,7 @@ constexpr std::array kLogChar = { /*ANDROID_LOG_SILENT*/ 'S', }; -size_t ParseUint(const char *s) { +long ParseUint(const char *s) { if (s[0] == '\0') return -1; while (isspace(*s)) { @@ -63,7 +61,7 @@ size_t ParseUint(const char *s) { return static_cast(result); } -inline size_t GetByteProp(std::string_view prop, size_t def = -1) { +inline long GetByteProp(std::string_view prop, long def = -1) { std::array buf{}; if (__system_property_get(prop.data(), buf.data()) < 0) return def; return ParseUint(buf.data()); @@ -247,9 +245,17 @@ void Logcat::ProcessBuffer(struct log_msg *buf) { } else if (msg == "!!start_watchdog!!"sv) { enable_watchdog = true; enable_watchdog.notify_one(); + EnsureLogWatchDog(); } else if (msg == "!!stop_watchdog!!"sv) { enable_watchdog = false; enable_watchdog.notify_one(); + std::system("resetprop -p --delete persist.logd.size"); + std::system("resetprop -p --delete persist.logd.size.main"); + std::system("resetprop -p --delete persist.logd.size.crash"); + + // Terminate the watchdog thread by exiting __system_property_wait firs firstt + std::system("setprop persist.log.tag V"); + std::system("resetprop -p --delete persist.log.tag"); } } } @@ -259,14 +265,17 @@ void Logcat::EnsureLogWatchDog() { constexpr static auto kLogdTagProp = "persist.log.tag"sv; constexpr static auto kLogdMainSizeProp = "persist.logd.size.main"sv; constexpr static auto kLogdCrashSizeProp = "persist.logd.size.crash"sv; - constexpr static size_t kErr = -1; - std::thread watch_dog([this] { + constexpr static long kErr = -1; + std::thread watchdog([this] { while (true) { - enable_watchdog.wait(false); + enable_watchdog.wait(false); // Blocking current thread until enable_watchdog is true; auto logd_size = GetByteProp(kLogdSizeProp); auto logd_tag = GetStrProp(kLogdTagProp); auto logd_main_size = GetByteProp(kLogdMainSizeProp); auto logd_crash_size = GetByteProp(kLogdCrashSizeProp); + Log("[LogWatchDog started] log.tag: " + logd_tag + + "; logd.[default, main, crash].size: [" + std::to_string(logd_size) + "," + + std::to_string(logd_main_size) + "," + std::to_string(logd_crash_size) + "]\n"); if (!logd_tag.empty() || !((logd_main_size == kErr && logd_crash_size == kErr && logd_size != kErr && logd_size >= kLogBufferSize) || @@ -287,14 +296,20 @@ void Logcat::EnsureLogWatchDog() { } if (!__system_property_wait(pi, serial, &serial, nullptr)) break; if (pi != nullptr) { - if (enable_watchdog) Log("\nResetting log settings\n"); - } else + if (enable_watchdog) { + Log("\nProp persist.log.tag changed, resetting log settings\n"); + } else { + break; // End current thread as expected + } + } else { + // log tag prop was not found; to avoid frequently trigger wait, sleep for a while std::this_thread::sleep_for(1s); - // log tag prop was not found; to avoid frequently trigger wait, sleep for a while + } } + Log("[LogWatchDog stopped]\n"); }); - pthread_setname_np(watch_dog.native_handle(), "watchdog"); - watch_dog.detach(); + pthread_setname_np(watchdog.native_handle(), "watchdog"); + watchdog.detach(); } void Logcat::Run() { @@ -303,8 +318,6 @@ void Logcat::Run() { RefreshFd(true); RefreshFd(false); - EnsureLogWatchDog(); - while (true) { std::unique_ptr logger_list{ android_logger_list_alloc(0, tail, 0), &android_logger_list_free};