From c6d23c19b261eafb480fc8e92861383a54ba65cf Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Thu, 16 Nov 2017 16:19:44 +0000 Subject: [sanitizer] Use runtime checks instead of API level for Android logging Summary: Recent Bionic have a slew of `async_safe_*` logging functions that are basically the liblog ones but included within the libc. They have the advantage of not allocating memory. `async_safe_write_log` does no formatting and is likely the best candidate for logging. Use a weak definition to try and use it. Also, avoid API level checks (as the toolchain is compiled at a rather low API level) for `__android_log_write` in favor of a weak definition as well. Keep the fallback to `syslog` if nothing else was found. I tried to overhaul the code block to only have a single #if SANITIZER_ANDROID but I am not particularly attached to the form. LMKWYT. Reviewers: eugenis Reviewed By: eugenis Subscribers: srhines, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D40100 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318410 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_linux_libcdep.cc | 65 +++++++++++++++---------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 0dc437585..3e64e90b5 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -48,10 +48,6 @@ #include #endif -#if SANITIZER_ANDROID && __ANDROID_API__ < 21 -#include -#endif - #if !SANITIZER_ANDROID #include #include @@ -538,12 +534,9 @@ uptr GetRSS() { return rss * GetPageSizeCached(); } -// 64-bit Android targets don't provide the deprecated __android_log_write. -// Starting with the L release, syslog() works and is preferable to -// __android_log_write. #if SANITIZER_LINUX -#if SANITIZER_ANDROID +# if SANITIZER_ANDROID static atomic_uint8_t android_log_initialized; void AndroidLogInit() { @@ -554,35 +547,53 @@ void AndroidLogInit() { static bool ShouldLogAfterPrintf() { return atomic_load(&android_log_initialized, memory_order_acquire); } -#else -void AndroidLogInit() {} -static bool ShouldLogAfterPrintf() { return true; } -#endif // SANITIZER_ANDROID +extern "C" SANITIZER_WEAK_ATTRIBUTE +int async_safe_write_log(int pri, const char* tag, const char* msg); +extern "C" SANITIZER_WEAK_ATTRIBUTE +int __android_log_write(int prio, const char* tag, const char* msg); + +// ANDROID_LOG_INFO is 4, but can't be resolved at runtime. +#define SANITIZER_ANDROID_LOG_INFO 4 +// async_safe_write_log is basically __android_log_write but is only available +// in recent versions of Bionic. __android_log_write was deprecated along the +// way, so fallback to syslog if neither exists. The non-syslog alternatives +// do not allocate memory and are preferable. Also syslog is broken pre-L, this +// is another reason why we prefer __android_log_write if available. void WriteOneLineToSyslog(const char *s) { -#if SANITIZER_ANDROID &&__ANDROID_API__ < 21 - __android_log_write(ANDROID_LOG_INFO, NULL, s); -#else - syslog(LOG_INFO, "%s", s); -#endif + if (&async_safe_write_log) { + async_safe_write_log(SANITIZER_ANDROID_LOG_INFO, GetProcessName(), s); + } else if (&__android_log_write) { + __android_log_write(SANITIZER_ANDROID_LOG_INFO, nullptr, s); + } else { + syslog(LOG_INFO, "%s", s); + } } -void LogMessageOnPrintf(const char *str) { - if (common_flags()->log_to_syslog && ShouldLogAfterPrintf()) - WriteToSyslog(str); -} +extern "C" SANITIZER_WEAK_ATTRIBUTE +void android_set_abort_message(const char *); -#if SANITIZER_ANDROID -extern "C" __attribute__((weak)) void android_set_abort_message(const char *); void SetAbortMessage(const char *str) { - if (&android_set_abort_message) android_set_abort_message(str); + if (&android_set_abort_message) + android_set_abort_message(str); } -#else +# else +void AndroidLogInit() {} + +static bool ShouldLogAfterPrintf() { return true; } + +void WriteOneLineToSyslog(const char *s) { syslog(LOG_INFO, "%s", s); } + void SetAbortMessage(const char *str) {} -#endif +# endif // SANITIZER_ANDROID + +void LogMessageOnPrintf(const char *str) { + if (common_flags()->log_to_syslog && ShouldLogAfterPrintf()) + WriteToSyslog(str); +} -#endif // SANITIZER_LINUX +#endif // SANITIZER_LINUX } // namespace __sanitizer -- cgit v1.2.3