From 47d88050d38fc18ff4c7d067d754dc24a2bc86bb Mon Sep 17 00:00:00 2001 From: LoveSy Date: Sat, 15 Jan 2022 23:17:20 +0800 Subject: [PATCH] Add log configuration ensure watchdog (#1535) --- daemon/src/main/cpp/logcat.cpp | 134 +++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 15 deletions(-) diff --git a/daemon/src/main/cpp/logcat.cpp b/daemon/src/main/cpp/logcat.cpp index 15813d59..527fba42 100644 --- a/daemon/src/main/cpp/logcat.cpp +++ b/daemon/src/main/cpp/logcat.cpp @@ -1,28 +1,91 @@ +#include "logcat.h" + #include #include #include #include #include #include -#include "logcat.h" +#include +#include #include using namespace std::string_view_literals; +using namespace std::chrono_literals; constexpr size_t kMaxLogSize = 4 * 1024 * 1024; +#ifdef NDEBUG constexpr size_t kLogBufferSize = 256 * 1024; +#else +constexpr size_t kLogBufferSize = 4 * 1024 * 1024; +#endif -constexpr std::array kLogChar = { - /*ANDROID_LOG_UNKNOWN*/'?', - /*ANDROID_LOG_DEFAULT*/ '?', - /*ANDROID_LOG_VERBOSE*/ 'V', - /*ANDROID_LOG_DEBUG*/ 'D', - /*ANDROID_LOG_INFO*/'I', - /*ANDROID_LOG_WARN*/'W', - /*ANDROID_LOG_ERROR*/ 'E', - /*ANDROID_LOG_FATAL*/ 'F', - /*ANDROID_LOG_SILENT*/ 'S', -}; +namespace { + constexpr std::array kLogChar = { + /*ANDROID_LOG_UNKNOWN*/'?', + /*ANDROID_LOG_DEFAULT*/ '?', + /*ANDROID_LOG_VERBOSE*/ 'V', + /*ANDROID_LOG_DEBUG*/ 'D', + /*ANDROID_LOG_INFO*/'I', + /*ANDROID_LOG_WARN*/'W', + /*ANDROID_LOG_ERROR*/ 'E', + /*ANDROID_LOG_FATAL*/ 'F', + /*ANDROID_LOG_SILENT*/ 'S', + }; + + size_t ParseUint(const char *s) { + if (s[0] == '\0') return -1; + + while (isspace(*s)) { + s++; + } + + if (s[0] == '-') { + return -1; + } + + int base = (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) ? 16 : 10; + char *end; + auto result = strtoull(s, &end, base); + if (end == s) { + return -1; + } + if (*end != '\0') { + const char *suffixes = "bkmgtpe"; + const char *suffix; + if ((suffix = strchr(suffixes, tolower(*end))) == nullptr || + __builtin_mul_overflow(result, 1ULL << (10 * (suffix - suffixes)), &result)) { + return -1; + } + } + if (std::numeric_limits::max() < result) { + return -1; + } + return static_cast(result); + } + + inline size_t GetByteProp(std::string_view prop, size_t def = -1) { + std::array buf{}; + if (__system_property_get(prop.data(), buf.data()) < 0) return def; + return ParseUint(buf.data()); + } + + inline std::string GetStrProp(std::string_view prop, std::string def = {}) { + std::array buf{}; + if (__system_property_get(prop.data(), buf.data()) < 0) return def; + return {buf.data()}; + } + + inline bool SetIntProp(std::string_view prop, int val) { + auto buf = std::to_string(val); + return __system_property_set(prop.data(), buf.data()) >= 0; + } + + inline bool SetStrProp(std::string_view prop, std::string_view val) { + return __system_property_set(prop.data(), val.data()) >= 0; + } + +} // namespace class UniqueFile : public std::unique_ptr> { inline static deleter_type deleter = [](auto f) { f && f != stdout && fclose(f); }; @@ -52,6 +115,8 @@ private: static size_t PrintLogLine(const AndroidLogEntry &entry, FILE *out); + void EnsureLogWatchDog(); + JNIEnv *env_; jobject thiz_; jmethodID refresh_fd_method_; @@ -73,7 +138,7 @@ size_t Logcat::PrintLogLine(const AndroidLogEntry &entry, FILE *out) { if (!out) return 0; constexpr static size_t kMaxTimeBuff = 64; struct tm tm{}; - std::array time_buff; + std::array time_buff{}; auto now = entry.tv_sec; auto nsec = entry.tv_nsec; @@ -122,8 +187,12 @@ void Logcat::RefreshFd(bool is_verbose) { } inline void Logcat::Log(std::string_view str) { - if (verbose_) fprintf(verbose_file_.get(), "%.*s", static_cast(str.size()), str.data()); + if (verbose_) { + fprintf(verbose_file_.get(), "%.*s", static_cast(str.size()), str.data()); + fflush(verbose_file_.get()); + } fprintf(modules_file_.get(), "%.*s", static_cast(str.size()), str.data()); + fflush(modules_file_.get()); } void Logcat::OnCrash() { @@ -142,7 +211,7 @@ void Logcat::OnCrash() { Log("\nLogd maybe crashed, retrying in 1s...\n"); } - sleep(1); + std::this_thread::sleep_for(1s); } void Logcat::ProcessBuffer(struct log_msg *buf) { @@ -178,11 +247,46 @@ void Logcat::ProcessBuffer(struct log_msg *buf) { } } +void Logcat::EnsureLogWatchDog() { + constexpr static auto kLogdSizeProp = "persist.logd.size"sv; + 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([this] { + while (true) { + auto logd_size = GetByteProp(kLogdSizeProp); + auto logd_tag = GetStrProp(kLogdTagProp); + auto logd_main_size = GetByteProp(kLogdMainSizeProp); + auto logd_crash_size = GetByteProp(kLogdCrashSizeProp); + if (!logd_tag.empty() || + !((logd_main_size == kErr && logd_crash_size == kErr && logd_size != kErr && + logd_size >= kLogBufferSize) || + (logd_main_size != kErr && logd_main_size >= kLogBufferSize && + logd_crash_size != kErr && + logd_crash_size >= kLogBufferSize))) { + SetIntProp(kLogdSizeProp, kLogBufferSize); + SetIntProp(kLogdMainSizeProp, kLogBufferSize); + SetIntProp(kLogdCrashSizeProp, kLogBufferSize); + SetStrProp(kLogdTagProp, ""); + SetStrProp("ctl.start", "logd-reinit"); + Log("Reset log settings\n"); + } + const auto *pi = __system_property_find(kLogdTagProp.data()); + uint32_t serial; + if (!__system_property_wait(pi, 0, &serial, nullptr)) break; + } + }).detach(); +} + void Logcat::Run() { constexpr size_t tail_after_crash = 10U; size_t tail = 0; RefreshFd(true); RefreshFd(false); + + EnsureLogWatchDog(); + while (true) { std::unique_ptr logger_list{ android_logger_list_alloc(0, tail, 0), &android_logger_list_free};