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.
This commit is contained in:
JingMatrix 2024-12-08 23:38:20 +01:00
parent fd3f76324e
commit 8dff17c1f9
1 changed files with 28 additions and 15 deletions

View File

@ -7,8 +7,6 @@
#include <array>
#include <atomic>
#include <chrono>
#include <cinttypes>
#include <functional>
#include <string>
#include <thread>
@ -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<char, ANDROID_LOG_SILENT + 1> kLogChar = {
@ -32,7 +30,7 @@ constexpr std::array<char, ANDROID_LOG_SILENT + 1> 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<size_t>(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<char, PROP_VALUE_MAX> 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, decltype(&android_logger_list_free)> logger_list{
android_logger_list_alloc(0, tail, 0), &android_logger_list_free};