From 7a3681e5b6c39bc2b3b62031ca5941dbf7bc4e63 Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Mon, 24 Apr 2017 17:48:32 -0700 Subject: [PATCH] Move libc_log code into libasync_safe. This library is used by a number of different libraries in the system. Make it easy for platform libraries to use this library and create an actual exported include file. Change the names of the functions to reflect the new name of the library. Run clang_format on the async_safe_log.cpp file since the formatting is all over the place. Bug: 31919199 Test: Compiled for angler/bullhead, and booted. Test: Ran bionic unit tests. Test: Ran the malloc debug tests. Change-Id: I8071bf690c17b0ea3bc8dc5749cdd5b6ad58478a --- libc/Android.bp | 29 +- libc/arch-arm/bionic/atexit_legacy.c | 4 +- libc/arch-mips/bionic/cacheflush.cpp | 5 +- libc/async_safe/Android.bp | 15 + .../async_safe_log.cpp} | 426 ++++++++++----------- .../include/async_safe/log.h} | 42 +- libc/bionic/NetdClient.cpp | 5 +- libc/bionic/__cxa_pure_virtual.cpp | 4 +- libc/bionic/__stack_chk_fail.cpp | 5 +- libc/bionic/assert.cpp | 8 +- libc/bionic/bionic_arc4random.cpp | 7 +- libc/bionic/bionic_systrace.cpp | 1 - libc/bionic/grp_pwd.cpp | 1 - libc/bionic/icu.cpp | 10 +- libc/bionic/libc_init_common.cpp | 11 +- libc/bionic/malloc_common.cpp | 6 +- libc/bionic/ndk_cruft.cpp | 1 - libc/bionic/new.cpp | 6 +- libc/bionic/open.cpp | 2 +- libc/bionic/pthread_attr.cpp | 13 +- libc/bionic/pthread_create.cpp | 22 +- libc/bionic/pthread_internal.cpp | 7 +- libc/bionic/setjmp_cookie.cpp | 9 +- libc/bionic/strerror_r.cpp | 5 +- libc/bionic/syslog.cpp | 6 +- libc/bionic/system_properties.cpp | 102 ++--- libc/dns/resolv/res_cache.c | 4 +- libc/dns/resolv/res_send.c | 28 +- libc/dns/resolv/res_state.c | 4 +- libc/dns/resolv/res_stats.c | 16 +- libc/malloc_debug/Android.bp | 10 +- libc/malloc_debug/backtrace.cpp | 8 +- libc/malloc_debug/debug_log.h | 10 +- libc/malloc_debug/tests/log_fake.cpp | 2 +- libc/private/WriteProtected.h | 13 +- libc/private/bionic_fortify.h | 14 +- libc/stdio/stdio_ext.cpp | 5 +- libc/upstream-openbsd/android/include/arc4random.h | 5 +- linker/Android.bp | 2 + linker/linker.cpp | 14 +- linker/linker.h | 1 - linker/linker_allocator.cpp | 18 +- linker/linker_allocator.h | 5 +- linker/linker_config.cpp | 6 +- linker/linker_debug.h | 7 +- linker/linker_globals.h | 12 +- linker/linker_libcxx_support.cpp | 4 +- linker/linker_logger.cpp | 13 +- linker/linker_main.cpp | 22 +- linker/linker_memory.cpp | 6 +- linker/linker_sleb128.h | 4 +- linker/linker_soinfo.cpp | 4 +- linker/tests/Android.mk | 5 +- tests/Android.bp | 8 +- .../{libc_logging_test.cpp => async_safe_test.cpp} | 87 +++-- 55 files changed, 569 insertions(+), 520 deletions(-) create mode 100644 libc/async_safe/Android.bp rename libc/{bionic/libc_logging.cpp => async_safe/async_safe_log.cpp} (54%) rename libc/{private/libc_logging.h => async_safe/include/async_safe/log.h} (62%) rename tests/{libc_logging_test.cpp => async_safe_test.cpp} (55%) diff --git a/libc/Android.bp b/libc/Android.bp index 590fd283c..b2ebe0934 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -1,6 +1,7 @@ // Define the common source files for all the libc instances // ========================================================= libc_common_src_files = [ + "async_safe/async_safe_log.cpp", "bionic/ether_aton.c", "bionic/ether_ntoa.c", "bionic/fts.c", @@ -58,7 +59,10 @@ cc_defaults { asflags: libc_common_flags, conlyflags: ["-std=gnu99"], cppflags: [], - include_dirs: ["external/jemalloc/include"], + include_dirs: [ + "bionic/libc/async_safe/include", + "external/jemalloc/include", + ], stl: "none", system_shared_libs: [], @@ -1346,7 +1350,6 @@ cc_library_static { "bionic/__libc_current_sigrtmax.cpp", "bionic/__libc_current_sigrtmin.cpp", "bionic/libc_init_common.cpp", - "bionic/libc_logging.cpp", "bionic/libgen.cpp", "bionic/link.cpp", "bionic/locale.cpp", @@ -1705,7 +1708,7 @@ cc_library { "bionic/libc_init_static.cpp", ], cflags: ["-DLIBC_STATIC"], - whole_static_libs: ["libc_init_static", "libjemalloc"], + whole_static_libs: ["libc_init_static"], }, shared: { srcs: [ @@ -1717,7 +1720,6 @@ cc_library { "bionic/NetdClient.cpp", "arch-common/bionic/crtend_so.S", ], - whole_static_libs: ["libjemalloc"], }, required: ["tzdata"], @@ -1740,7 +1742,7 @@ cc_library { // you wanted! shared_libs: ["libdl"], - whole_static_libs: ["libc_common"], + whole_static_libs: ["libc_common", "libjemalloc"], nocrt: true, @@ -1793,19 +1795,6 @@ cc_library { } // ======================================================== -// libc_logging.a -// ======================================================== -cc_library_static { - defaults: ["libc_defaults"], - - srcs: [ - "bionic/libc_logging.cpp", - ], - - name: "libc_logging", -} - -// ======================================================== // libstdc++.so + libstdc++.a // ======================================================== cc_library { @@ -1818,9 +1807,7 @@ cc_library { ], name: "libstdc++", system_shared_libs: ["libc"], - shared: { - static_libs: ["libc_logging"], - }, + static_libs: ["libasync_safe"], //TODO (dimitry): This is to work around b/24465209. Remove after root cause is fixed arch: { diff --git a/libc/arch-arm/bionic/atexit_legacy.c b/libc/arch-arm/bionic/atexit_legacy.c index c0d704db1..7254017cc 100644 --- a/libc/arch-arm/bionic/atexit_legacy.c +++ b/libc/arch-arm/bionic/atexit_legacy.c @@ -29,7 +29,7 @@ #include #include -#include "private/libc_logging.h" +#include /* * This source file should only be included by libc.so, its purpose is @@ -53,7 +53,7 @@ atexit(void (*func)(void)) */ static char const warning[] = "WARNING: generic atexit() called from legacy shared library\n"; - __libc_format_log(ANDROID_LOG_WARN, "libc", warning); + async_safe_format_log(ANDROID_LOG_WARN, "libc", warning); fprintf(stderr, warning); return (__cxa_atexit((void (*)(void *))func, NULL, NULL)); diff --git a/libc/arch-mips/bionic/cacheflush.cpp b/libc/arch-mips/bionic/cacheflush.cpp index 98c0bd453..380ad906a 100644 --- a/libc/arch-mips/bionic/cacheflush.cpp +++ b/libc/arch-mips/bionic/cacheflush.cpp @@ -29,7 +29,7 @@ #include #include -#include "private/libc_logging.h" +#include // Linux historically defines a cacheflush(3) routine for MIPS // with this signature: @@ -50,7 +50,8 @@ int cacheflush(long start, long end, long /*flags*/) { // It looks like this is really a MIPS-style cacheflush call. static bool warned = false; if (!warned) { - __libc_format_log(ANDROID_LOG_WARN, "libc", "cacheflush called with (start,len) instead of (start,end)"); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "cacheflush called with (start,len) instead of (start,end)"); warned = true; } end += start; diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp new file mode 100644 index 000000000..9e36d97d4 --- /dev/null +++ b/libc/async_safe/Android.bp @@ -0,0 +1,15 @@ +// ======================================================== +// libasync_safe.a +// ======================================================== +cc_library_static { + defaults: ["libc_defaults"], + srcs: [ + "async_safe_log.cpp", + ], + + name: "libasync_safe", + + include_dirs: ["bionic/libc"], + + export_include_dirs: ["include"], +} diff --git a/libc/bionic/libc_logging.cpp b/libc/async_safe/async_safe_log.cpp similarity index 54% rename from libc/bionic/libc_logging.cpp rename to libc/async_safe/async_safe_log.cpp index 54664d9fb..372f385b2 100644 --- a/libc/bionic/libc_logging.cpp +++ b/libc/async_safe/async_safe_log.cpp @@ -26,12 +26,6 @@ * SUCH DAMAGE. */ -// Relative paths so we can #include this .cpp file for testing. -#include "../private/CachedProperty.h" -#include "../private/libc_logging.h" -#include "../private/ScopedPthreadMutexLocker.h" - -#include #include #include #include @@ -49,13 +43,19 @@ #include #include +#include +#include + +#include "private/CachedProperty.h" +#include "private/ScopedPthreadMutexLocker.h" + // Must be kept in sync with frameworks/base/core/java/android/util/EventLog.java. enum AndroidEventLogType { - EVENT_TYPE_INT = 0, - EVENT_TYPE_LONG = 1, - EVENT_TYPE_STRING = 2, - EVENT_TYPE_LIST = 3, - EVENT_TYPE_FLOAT = 4, + EVENT_TYPE_INT = 0, + EVENT_TYPE_LONG = 1, + EVENT_TYPE_STRING = 2, + EVENT_TYPE_LIST = 3, + EVENT_TYPE_FLOAT = 4, }; struct BufferOutputStream { @@ -67,8 +67,7 @@ struct BufferOutputStream { pos_[0] = '\0'; } - ~BufferOutputStream() { - } + ~BufferOutputStream() {} void Send(const char* data, int len) { if (len < 0) { @@ -102,8 +101,7 @@ struct BufferOutputStream { struct FdOutputStream { public: - explicit FdOutputStream(int fd) : total(0), fd_(fd) { - } + explicit FdOutputStream(int fd) : total(0), fd_(fd) {} void Send(const char* data, int len) { if (len < 0) { @@ -137,23 +135,23 @@ struct FdOutputStream { * * NOTE: Does *not* handle a sign prefix. */ -static unsigned parse_decimal(const char *format, int *ppos) { - const char* p = format + *ppos; - unsigned result = 0; - - for (;;) { - int ch = *p; - unsigned d = static_cast(ch - '0'); +static unsigned parse_decimal(const char* format, int* ppos) { + const char* p = format + *ppos; + unsigned result = 0; - if (d >= 10U) { - break; - } + for (;;) { + int ch = *p; + unsigned d = static_cast(ch - '0'); - result = result*10 + d; - p++; + if (d >= 10U) { + break; } - *ppos = p - format; - return result; + + result = result * 10 + d; + p++; + } + *ppos = p - format; + return result; } // Writes number 'value' in base 'base' into buffer 'buf' of size 'buf_size' bytes. @@ -233,182 +231,185 @@ static void SendRepeat(Out& o, char ch, int count) { /* Perform formatted output to an output target 'o' */ template static void out_vformat(Out& o, const char* format, va_list args) { - int nn = 0; + int nn = 0; + + for (;;) { + int mm; + int padZero = 0; + int padLeft = 0; + char sign = '\0'; + int width = -1; + int prec = -1; + size_t bytelen = sizeof(int); + int slen; + char buffer[32]; /* temporary buffer used to format numbers */ + + char c; + + /* first, find all characters that are not 0 or '%' */ + /* then send them to the output directly */ + mm = nn; + do { + c = format[mm]; + if (c == '\0' || c == '%') break; + mm++; + } while (1); + + if (mm > nn) { + o.Send(format + nn, mm - nn); + nn = mm; + } + + /* is this it ? then exit */ + if (c == '\0') break; + /* nope, we are at a '%' modifier */ + nn++; // skip it + + /* parse flags */ for (;;) { - int mm; - int padZero = 0; - int padLeft = 0; - char sign = '\0'; - int width = -1; - int prec = -1; - size_t bytelen = sizeof(int); - int slen; - char buffer[32]; /* temporary buffer used to format numbers */ - - char c; - - /* first, find all characters that are not 0 or '%' */ - /* then send them to the output directly */ - mm = nn; - do { - c = format[mm]; - if (c == '\0' || c == '%') - break; - mm++; - } while (1); - - if (mm > nn) { - o.Send(format+nn, mm-nn); - nn = mm; - } + c = format[nn++]; + if (c == '\0') { /* single trailing '%' ? */ + c = '%'; + o.Send(&c, 1); + return; + } else if (c == '0') { + padZero = 1; + continue; + } else if (c == '-') { + padLeft = 1; + continue; + } else if (c == ' ' || c == '+') { + sign = c; + continue; + } + break; + } - /* is this it ? then exit */ - if (c == '\0') - break; - - /* nope, we are at a '%' modifier */ - nn++; // skip it - - /* parse flags */ - for (;;) { - c = format[nn++]; - if (c == '\0') { /* single trailing '%' ? */ - c = '%'; - o.Send(&c, 1); - return; - } - else if (c == '0') { - padZero = 1; - continue; - } - else if (c == '-') { - padLeft = 1; - continue; - } - else if (c == ' ' || c == '+') { - sign = c; - continue; - } - break; - } + /* parse field width */ + if ((c >= '0' && c <= '9')) { + nn--; + width = static_cast(parse_decimal(format, &nn)); + c = format[nn++]; + } - /* parse field width */ - if ((c >= '0' && c <= '9')) { - nn --; - width = static_cast(parse_decimal(format, &nn)); - c = format[nn++]; - } + /* parse precision */ + if (c == '.') { + prec = static_cast(parse_decimal(format, &nn)); + c = format[nn++]; + } - /* parse precision */ - if (c == '.') { - prec = static_cast(parse_decimal(format, &nn)); - c = format[nn++]; + /* length modifier */ + switch (c) { + case 'h': + bytelen = sizeof(short); + if (format[nn] == 'h') { + bytelen = sizeof(char); + nn += 1; + } + c = format[nn++]; + break; + case 'l': + bytelen = sizeof(long); + if (format[nn] == 'l') { + bytelen = sizeof(long long); + nn += 1; } + c = format[nn++]; + break; + case 'z': + bytelen = sizeof(size_t); + c = format[nn++]; + break; + case 't': + bytelen = sizeof(ptrdiff_t); + c = format[nn++]; + break; + default:; + } - /* length modifier */ - switch (c) { - case 'h': - bytelen = sizeof(short); - if (format[nn] == 'h') { - bytelen = sizeof(char); - nn += 1; - } - c = format[nn++]; - break; - case 'l': - bytelen = sizeof(long); - if (format[nn] == 'l') { - bytelen = sizeof(long long); - nn += 1; - } - c = format[nn++]; - break; - case 'z': - bytelen = sizeof(size_t); - c = format[nn++]; - break; - case 't': - bytelen = sizeof(ptrdiff_t); - c = format[nn++]; - break; + /* conversion specifier */ + const char* str = buffer; + if (c == 's') { + /* string */ + str = va_arg(args, const char*); + if (str == NULL) { + str = "(null)"; + } + } else if (c == 'c') { + /* character */ + /* NOTE: char is promoted to int when passed through the stack */ + buffer[0] = static_cast(va_arg(args, int)); + buffer[1] = '\0'; + } else if (c == 'p') { + uint64_t value = reinterpret_cast(va_arg(args, void*)); + buffer[0] = '0'; + buffer[1] = 'x'; + format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x'); + } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') { + /* integers - first read value from stack */ + uint64_t value; + int is_signed = (c == 'd' || c == 'i' || c == 'o'); + + /* NOTE: int8_t and int16_t are promoted to int when passed + * through the stack + */ + switch (bytelen) { + case 1: + value = static_cast(va_arg(args, int)); + break; + case 2: + value = static_cast(va_arg(args, int)); + break; + case 4: + value = va_arg(args, uint32_t); + break; + case 8: + value = va_arg(args, uint64_t); + break; default: - ; - } + return; /* should not happen */ + } - /* conversion specifier */ - const char* str = buffer; - if (c == 's') { - /* string */ - str = va_arg(args, const char*); - if (str == NULL) { - str = "(null)"; - } - } else if (c == 'c') { - /* character */ - /* NOTE: char is promoted to int when passed through the stack */ - buffer[0] = static_cast(va_arg(args, int)); - buffer[1] = '\0'; - } else if (c == 'p') { - uint64_t value = reinterpret_cast(va_arg(args, void*)); - buffer[0] = '0'; - buffer[1] = 'x'; - format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x'); - } else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') { - /* integers - first read value from stack */ - uint64_t value; - int is_signed = (c == 'd' || c == 'i' || c == 'o'); - - /* NOTE: int8_t and int16_t are promoted to int when passed - * through the stack - */ - switch (bytelen) { - case 1: value = static_cast(va_arg(args, int)); break; - case 2: value = static_cast(va_arg(args, int)); break; - case 4: value = va_arg(args, uint32_t); break; - case 8: value = va_arg(args, uint64_t); break; - default: return; /* should not happen */ - } - - /* sign extension, if needed */ - if (is_signed) { - int shift = 64 - 8*bytelen; - value = static_cast((static_cast(value << shift)) >> shift); - } - - /* format the number properly into our buffer */ - format_integer(buffer, sizeof(buffer), value, c); - } else if (c == '%') { - buffer[0] = '%'; - buffer[1] = '\0'; - } else { - __assert(__FILE__, __LINE__, "conversion specifier unsupported"); - } + /* sign extension, if needed */ + if (is_signed) { + int shift = 64 - 8 * bytelen; + value = static_cast((static_cast(value << shift)) >> shift); + } - /* if we are here, 'str' points to the content that must be - * outputted. handle padding and alignment now */ + /* format the number properly into our buffer */ + format_integer(buffer, sizeof(buffer), value, c); + } else if (c == '%') { + buffer[0] = '%'; + buffer[1] = '\0'; + } else { + __assert(__FILE__, __LINE__, "conversion specifier unsupported"); + } - slen = strlen(str); + /* if we are here, 'str' points to the content that must be + * outputted. handle padding and alignment now */ - if (sign != '\0' || prec != -1) { - __assert(__FILE__, __LINE__, "sign/precision unsupported"); - } + slen = strlen(str); - if (slen < width && !padLeft) { - char padChar = padZero ? '0' : ' '; - SendRepeat(o, padChar, width - slen); - } + if (sign != '\0' || prec != -1) { + __assert(__FILE__, __LINE__, "sign/precision unsupported"); + } - o.Send(str, slen); + if (slen < width && !padLeft) { + char padChar = padZero ? '0' : ' '; + SendRepeat(o, padChar, width - slen); + } - if (slen < width && padLeft) { - char padChar = padZero ? '0' : ' '; - SendRepeat(o, padChar, width - slen); - } + o.Send(str, slen); + + if (slen < width && padLeft) { + char padChar = padZero ? '0' : ' '; + SendRepeat(o, padChar, width - slen); } + } } -int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) { +int async_safe_format_buffer(char* buffer, size_t buffer_size, const char* format, ...) { BufferOutputStream os(buffer, buffer_size); va_list args; va_start(args, format); @@ -417,14 +418,14 @@ int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, . return os.total; } -int __libc_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format, - va_list args) { +int async_safe_format_buffer_va_list(char* buffer, size_t buffer_size, const char* format, + va_list args) { BufferOutputStream os(buffer, buffer_size); out_vformat(os, format, args); return os.total; } -int __libc_format_fd(int fd, const char* format, ...) { +int async_safe_format_fd(int fd, const char* format, ...) { FdOutputStream os(fd); va_list args; va_start(args, format); @@ -433,7 +434,7 @@ int __libc_format_fd(int fd, const char* format, ...) { return os.total; } -static int __libc_write_stderr(const char* tag, const char* msg) { +static int write_stderr(const char* tag, const char* msg) { iovec vec[4]; vec[0].iov_base = const_cast(tag); vec[0].iov_len = strlen(tag); @@ -448,7 +449,7 @@ static int __libc_write_stderr(const char* tag, const char* msg) { return result; } -static int __libc_open_log_socket() { +static int open_log_socket() { // ToDo: Ideally we want this to fail if the gid of the current // process is AID_LOGD, but will have to wait until we have // registered this in private/android_filesystem_config.h. We have @@ -461,7 +462,7 @@ static int __libc_open_log_socket() { } union { - struct sockaddr addr; + struct sockaddr addr; struct sockaddr_un addrUn; } u; memset(&u, 0, sizeof(u)); @@ -476,7 +477,7 @@ static int __libc_open_log_socket() { return log_fd; } -static clockid_t __android_log_clockid() { +static clockid_t log_clockid() { static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ScopedPthreadMutexLocker locker(&mutex); @@ -489,16 +490,16 @@ static clockid_t __android_log_clockid() { return (tolower(ch) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME; } -struct log_time { // Wire format +struct log_time { // Wire format uint32_t tv_sec; uint32_t tv_nsec; }; -int __libc_write_log(int priority, const char* tag, const char* msg) { - int main_log_fd = __libc_open_log_socket(); +int async_safe_write_log(int priority, const char* tag, const char* msg) { + int main_log_fd = open_log_socket(); if (main_log_fd == -1) { // Try stderr instead. - return __libc_write_stderr(tag, msg); + return write_stderr(tag, msg); } iovec vec[6]; @@ -509,7 +510,7 @@ int __libc_write_log(int priority, const char* tag, const char* msg) { vec[1].iov_base = &tid; vec[1].iov_len = sizeof(tid); timespec ts; - clock_gettime(__android_log_clockid(), &ts); + clock_gettime(log_clockid(), &ts); log_time realtime_ts; realtime_ts.tv_sec = ts.tv_sec; realtime_ts.tv_nsec = ts.tv_nsec; @@ -528,22 +529,22 @@ int __libc_write_log(int priority, const char* tag, const char* msg) { return result; } -int __libc_format_log_va_list(int priority, const char* tag, const char* format, va_list args) { +int async_safe_format_log_va_list(int priority, const char* tag, const char* format, va_list args) { char buffer[1024]; BufferOutputStream os(buffer, sizeof(buffer)); out_vformat(os, format, args); - return __libc_write_log(priority, tag, buffer); + return async_safe_write_log(priority, tag, buffer); } -int __libc_format_log(int priority, const char* tag, const char* format, ...) { +int async_safe_format_log(int priority, const char* tag, const char* format, ...) { va_list args; va_start(args, format); - int result = __libc_format_log_va_list(priority, tag, format, args); + int result = async_safe_format_log_va_list(priority, tag, format, args); va_end(args); return result; } -static void __libc_fatal_va_list(const char* prefix, const char* format, va_list args) { +void async_safe_fatal_va_list(const char* prefix, const char* format, va_list args) { char msg[1024]; BufferOutputStream os(msg, sizeof(msg)); @@ -556,29 +557,20 @@ static void __libc_fatal_va_list(const char* prefix, const char* format, va_list // Log to stderr for the benefit of "adb shell" users and gtests. struct iovec iov[2] = { - { msg, os.total }, - { const_cast("\n"), 1 }, + {msg, os.total}, {const_cast("\n"), 1}, }; TEMP_FAILURE_RETRY(writev(2, iov, 2)); // Log to the log for the benefit of regular app developers (whose stdout and stderr are closed). - __libc_write_log(ANDROID_LOG_FATAL, "libc", msg); + async_safe_write_log(ANDROID_LOG_FATAL, "libc", msg); android_set_abort_message(msg); } -void __libc_fatal(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - __libc_fatal_va_list(nullptr, fmt, args); - va_end(args); - abort(); -} - -void __fortify_fatal(const char* fmt, ...) { +void async_safe_fatal(const char* fmt, ...) { va_list args; va_start(args, fmt); - __libc_fatal_va_list("FORTIFY", fmt, args); + async_safe_fatal_va_list(nullptr, fmt, args); va_end(args); abort(); } diff --git a/libc/private/libc_logging.h b/libc/async_safe/include/async_safe/log.h similarity index 62% rename from libc/private/libc_logging.h rename to libc/async_safe/include/async_safe/log.h index 73bc9a515..f93f67265 100644 --- a/libc/private/libc_logging.h +++ b/libc/async_safe/include/async_safe/log.h @@ -26,14 +26,16 @@ * SUCH DAMAGE. */ -#ifndef _LIBC_LOGGING_H -#define _LIBC_LOGGING_H +#ifndef _ASYNC_SAFE_LOG_LOG_H +#define _ASYNC_SAFE_LOG_LOG_H #include #include #include #include +// These functions do not allocate memory to send data to the log. + __BEGIN_DECLS enum { @@ -63,10 +65,16 @@ enum { }; // Formats a message to the log (priority 'fatal'), then aborts. -__noreturn void __libc_fatal(const char* _Nonnull, ...) __printflike(1, 2); +__noreturn void async_safe_fatal(const char* _Nonnull fmt, ...) __printflike(1, 2); -// Formats a message to the log (priority 'fatal'), prefixed by "FORTIFY: ", then aborts. -__noreturn void __fortify_fatal(const char* _Nonnull, ...) __printflike(1, 2); +// This function does return, so callers that want to abort, must do so themselves. +#if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) +void async_safe_fatal_va_list( + const char* _Nullable prefix, const char* _Nonnull fmt, va_list); +#else // defined(__mips__) || defined(__i386__) +void async_safe_fatal_va_list( + const char* _Nullable prefix, const char* _Nonnull fmt, va_list _Nonnull); +#endif // // Formatting routines for the C library's internal debugging. @@ -74,29 +82,31 @@ __noreturn void __fortify_fatal(const char* _Nonnull, ...) __printflike(1, 2); // These are async signal safe, so they can be called from signal handlers. // -int __libc_format_buffer(char* _Nonnull buf, size_t size, const char* _Nonnull fmt, ...) __printflike(3, 4); +int async_safe_format_buffer(char* _Nonnull buf, size_t size, const char* _Nonnull fmt, ...) __printflike(3, 4); #if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) -int __libc_format_buffer_va_list(char* _Nonnull buffer, size_t buffer_size, - const char* _Nonnull format, va_list args); +int async_safe_format_buffer_va_list( + char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list args); #else // defined(__mips__) || defined(__i386__) -int __libc_format_buffer_va_list(char* _Nonnull buffer, size_t buffer_size, - const char* _Nonnull format, va_list _Nonnull args); +int async_safe_format_buffer_va_list( + char* _Nonnull buffer, size_t buffer_size, const char* _Nonnull format, va_list _Nonnull args); #endif -int __libc_format_fd(int fd, const char* _Nonnull format , ...) __printflike(2, 3); -int __libc_format_log(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, ...) __printflike(3, 4); +int async_safe_format_fd(int fd, const char* _Nonnull format , ...) __printflike(2, 3); +int async_safe_format_log(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, ...) __printflike(3, 4); #if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) -int __libc_format_log_va_list(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list ap); +int async_safe_format_log_va_list( + int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list ap); #else // defined(__mips__) || defined(__i386__) -int __libc_format_log_va_list(int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list _Nonnull ap); +int async_safe_format_log_va_list( + int pri, const char* _Nonnull tag, const char* _Nonnull fmt, va_list _Nonnull ap); #endif -int __libc_write_log(int pri, const char* _Nonnull tag, const char* _Nonnull msg); +int async_safe_write_log(int pri, const char* _Nonnull tag, const char* _Nonnull msg); #define CHECK(predicate) \ do { \ if (!(predicate)) { \ - __libc_fatal("%s:%d: %s CHECK '" #predicate "' failed", \ + async_safe_fatal("%s:%d: %s CHECK '" #predicate "' failed", \ __FILE__, __LINE__, __FUNCTION__); \ } \ } while(0) diff --git a/libc/bionic/NetdClient.cpp b/libc/bionic/NetdClient.cpp index b117d72a9..a1071d2f4 100644 --- a/libc/bionic/NetdClient.cpp +++ b/libc/bionic/NetdClient.cpp @@ -18,7 +18,8 @@ #error NetdClient.cpp should NOT be included in static libc builds. #endif -#include "private/libc_logging.h" +#include + #include "private/NetdClientDispatch.h" #include @@ -53,6 +54,6 @@ static pthread_once_t netdClientInitOnce = PTHREAD_ONCE_INIT; extern "C" __LIBC_HIDDEN__ void netdClientInit() { if (pthread_once(&netdClientInitOnce, netdClientInitImpl)) { - __libc_format_log(ANDROID_LOG_ERROR, "netdClient", "Failed to initialize netd_client"); + async_safe_format_log(ANDROID_LOG_ERROR, "netdClient", "Failed to initialize netd_client"); } } diff --git a/libc/bionic/__cxa_pure_virtual.cpp b/libc/bionic/__cxa_pure_virtual.cpp index 30b581f6b..00a4d9001 100644 --- a/libc/bionic/__cxa_pure_virtual.cpp +++ b/libc/bionic/__cxa_pure_virtual.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include +#include extern "C" void __cxa_pure_virtual() { - __libc_fatal("Pure virtual function called. Are you calling virtual methods from a destructor?"); + async_safe_fatal("Pure virtual function called. Are you calling virtual methods from a destructor?"); } diff --git a/libc/bionic/__stack_chk_fail.cpp b/libc/bionic/__stack_chk_fail.cpp index cb039cfcd..5f5a5f69a 100644 --- a/libc/bionic/__stack_chk_fail.cpp +++ b/libc/bionic/__stack_chk_fail.cpp @@ -28,9 +28,10 @@ #include +#include + #include "private/bionic_ssp.h" -#include "private/libc_logging.h" void __stack_chk_fail() { - __libc_fatal("stack corruption detected (-fstack-protector)"); + async_safe_fatal("stack corruption detected (-fstack-protector)"); } diff --git a/libc/bionic/assert.cpp b/libc/bionic/assert.cpp index 985fc384b..41831cbbc 100644 --- a/libc/bionic/assert.cpp +++ b/libc/bionic/assert.cpp @@ -30,16 +30,16 @@ #include -#include "private/libc_logging.h" +#include void __assert(const char* file, int line, const char* failed_expression) { - __libc_fatal("%s:%d: assertion \"%s\" failed", file, line, failed_expression); + async_safe_fatal("%s:%d: assertion \"%s\" failed", file, line, failed_expression); } void __assert2(const char* file, int line, const char* function, const char* failed_expression) { - __libc_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression); + async_safe_fatal("%s:%d: %s: assertion \"%s\" failed", file, line, function, failed_expression); } extern "C" __LIBC_HIDDEN__ void longjmperror() { - __libc_fatal("longjmp botch"); + async_safe_fatal("longjmp botch"); } diff --git a/libc/bionic/bionic_arc4random.cpp b/libc/bionic/bionic_arc4random.cpp index ba3b4e113..a4842f6f5 100644 --- a/libc/bionic/bionic_arc4random.cpp +++ b/libc/bionic/bionic_arc4random.cpp @@ -35,8 +35,9 @@ #include #include +#include + #include "private/KernelArgumentBlock.h" -#include "private/libc_logging.h" bool __libc_arc4random_has_unlimited_entropy() { static bool have_urandom = access("/dev/urandom", R_OK) == 0; @@ -53,8 +54,8 @@ void __libc_safe_arc4random_buf(void* buf, size_t n, KernelArgumentBlock& args) static size_t at_random_bytes_consumed = 0; if (at_random_bytes_consumed + n > 16) { - __libc_fatal("ran out of AT_RANDOM bytes, have %zu, requested %zu", - 16 - at_random_bytes_consumed, n); + async_safe_fatal("ran out of AT_RANDOM bytes, have %zu, requested %zu", + 16 - at_random_bytes_consumed, n); } memcpy(buf, reinterpret_cast(args.getauxval(AT_RANDOM)) + at_random_bytes_consumed, n); diff --git a/libc/bionic/bionic_systrace.cpp b/libc/bionic/bionic_systrace.cpp index 5699f6e7f..970a92ba1 100644 --- a/libc/bionic/bionic_systrace.cpp +++ b/libc/bionic/bionic_systrace.cpp @@ -23,7 +23,6 @@ #include "private/bionic_lock.h" #include "private/bionic_systrace.h" #include "private/CachedProperty.h" -#include "private/libc_logging.h" #include // For ATRACE_TAG_BIONIC. diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp index 5d565c4eb..078a0b311 100644 --- a/libc/bionic/grp_pwd.cpp +++ b/libc/bionic/grp_pwd.cpp @@ -41,7 +41,6 @@ #include "private/bionic_macros.h" #include "private/grp_pwd.h" #include "private/ErrnoRestorer.h" -#include "private/libc_logging.h" // Generated android_ids array #include "generated_android_ids.h" diff --git a/libc/bionic/icu.cpp b/libc/bionic/icu.cpp index abc0eec0f..944a3f82d 100644 --- a/libc/bionic/icu.cpp +++ b/libc/bionic/icu.cpp @@ -33,7 +33,7 @@ #include #include -#include "private/libc_logging.h" +#include // Allowed icu4c version numbers are in the range [44, 999]. // Gingerbread's icu4c 4.4 is the minimum supported ICU version. @@ -68,7 +68,7 @@ static bool __find_icu() { free(namelist); if (max_version == -1 || max_version < ICUDATA_VERSION_MIN) { - __libc_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find an ICU .dat file"); + async_safe_write_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find an ICU .dat file"); return false; } @@ -76,7 +76,8 @@ static bool __find_icu() { g_libicuuc_handle = dlopen("libicuuc.so", RTLD_LOCAL); if (g_libicuuc_handle == nullptr) { - __libc_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't open libicuuc.so: %s", dlerror()); + async_safe_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't open libicuuc.so: %s", + dlerror()); return false; } @@ -93,7 +94,8 @@ void* __find_icu_symbol(const char* symbol_name) { void* symbol = dlsym(g_libicuuc_handle, versioned_symbol_name); if (symbol == nullptr) { - __libc_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find %s", versioned_symbol_name); + async_safe_format_log(ANDROID_LOG_ERROR, "bionic-icu", "couldn't find %s", + versioned_symbol_name); } return symbol; } diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 970a49ca3..d267b6876 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -41,12 +41,13 @@ #include #include +#include + #include "private/KernelArgumentBlock.h" #include "private/WriteProtected.h" #include "private/bionic_auxv.h" #include "private/bionic_globals.h" #include "private/bionic_tls.h" -#include "private/libc_logging.h" #include "private/thread_private.h" #include "pthread_internal.h" @@ -96,8 +97,8 @@ void __libc_init_globals(KernelArgumentBlock& args) { #if !defined(__LP64__) static void __check_max_thread_id() { if (gettid() > 65535) { - __libc_fatal("Limited by the size of pthread_mutex_t, 32 bit bionic libc only accepts " - "pid <= 65535, but current pid is %d", gettid()); + async_safe_fatal("Limited by the size of pthread_mutex_t, 32 bit bionic libc only accepts " + "pid <= 65535, but current pid is %d", gettid()); } } #endif @@ -303,11 +304,11 @@ static void __initialize_personality() { #if !defined(__LP64__) int old_value = personality(0xffffffff); if (old_value == -1) { - __libc_fatal("error getting old personality value: %s", strerror(errno)); + async_safe_fatal("error getting old personality value: %s", strerror(errno)); } if (personality((static_cast(old_value) & ~PER_MASK) | PER_LINUX32) == -1) { - __libc_fatal("error setting PER_LINUX32 personality: %s", strerror(errno)); + async_safe_fatal("error setting PER_LINUX32 personality: %s", strerror(errno)); } #endif } diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp index 3fceb71ee..18c998d08 100644 --- a/libc/bionic/malloc_common.cpp +++ b/libc/bionic/malloc_common.cpp @@ -167,7 +167,7 @@ extern "C" void* valloc(size_t bytes) { #include #include -#include +#include #include extern "C" int __cxa_atexit(void (*func)(void *), void *arg, void *dso); @@ -188,9 +188,9 @@ static ssize_t (*g_debug_malloc_backtrace_func)(void*, uintptr_t*, size_t); // Log functions // ============================================================================= #define error_log(format, ...) \ - __libc_format_log(ANDROID_LOG_ERROR, "libc", (format), ##__VA_ARGS__ ) + async_safe_format_log(ANDROID_LOG_ERROR, "libc", (format), ##__VA_ARGS__ ) #define info_log(format, ...) \ - __libc_format_log(ANDROID_LOG_INFO, "libc", (format), ##__VA_ARGS__ ) + async_safe_format_log(ANDROID_LOG_INFO, "libc", (format), ##__VA_ARGS__ ) // ============================================================================= // ============================================================================= diff --git a/libc/bionic/ndk_cruft.cpp b/libc/bionic/ndk_cruft.cpp index 29565a269..016b47694 100644 --- a/libc/bionic/ndk_cruft.cpp +++ b/libc/bionic/ndk_cruft.cpp @@ -46,7 +46,6 @@ #include #include "private/bionic_macros.h" -#include "private/libc_logging.h" extern "C" { diff --git a/libc/bionic/new.cpp b/libc/bionic/new.cpp index 76c46ee03..9499ff546 100644 --- a/libc/bionic/new.cpp +++ b/libc/bionic/new.cpp @@ -19,14 +19,14 @@ #include #include -#include "private/libc_logging.h" +#include const std::nothrow_t std::nothrow = {}; void* operator new(std::size_t size) { void* p = malloc(size); if (p == NULL) { - __libc_fatal("new failed to allocate %zu bytes", size); + async_safe_fatal("new failed to allocate %zu bytes", size); } return p; } @@ -34,7 +34,7 @@ void* operator new(std::size_t size) { void* operator new[](std::size_t size) { void* p = malloc(size); if (p == NULL) { - __libc_fatal("new[] failed to allocate %zu bytes", size); + async_safe_fatal("new[] failed to allocate %zu bytes", size); } return p; } diff --git a/libc/bionic/open.cpp b/libc/bionic/open.cpp index 2daa21f1b..6d179c44b 100644 --- a/libc/bionic/open.cpp +++ b/libc/bionic/open.cpp @@ -31,7 +31,7 @@ #include #include -#include "private/libc_logging.h" +#include "private/bionic_fortify.h" extern "C" int __openat(int, const char*, int, int); diff --git a/libc/bionic/pthread_attr.cpp b/libc/bionic/pthread_attr.cpp index cfa58fc88..4b6a8f2ae 100644 --- a/libc/bionic/pthread_attr.cpp +++ b/libc/bionic/pthread_attr.cpp @@ -33,9 +33,10 @@ #include #include +#include + #include "private/bionic_string_utils.h" #include "private/ErrnoRestorer.h" -#include "private/libc_logging.h" #include "pthread_internal.h" int pthread_attr_init(pthread_attr_t* attr) { @@ -117,12 +118,12 @@ int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_s static uintptr_t __get_main_stack_startstack() { FILE* fp = fopen("/proc/self/stat", "re"); if (fp == nullptr) { - __libc_fatal("couldn't open /proc/self/stat: %s", strerror(errno)); + async_safe_fatal("couldn't open /proc/self/stat: %s", strerror(errno)); } char line[BUFSIZ]; if (fgets(line, sizeof(line), fp) == nullptr) { - __libc_fatal("couldn't read /proc/self/stat: %s", strerror(errno)); + async_safe_fatal("couldn't read /proc/self/stat: %s", strerror(errno)); } fclose(fp); @@ -138,7 +139,7 @@ static uintptr_t __get_main_stack_startstack() { "%*u %*u %*u %*u %*u %*u %*u " "%*d %*d %*d %*d %*d %*d " "%*u %*u %*d %*u %*u %*u %" SCNuPTR, &startstack) != 1) { - __libc_fatal("couldn't parse /proc/self/stat"); + async_safe_fatal("couldn't parse /proc/self/stat"); } return startstack; @@ -163,7 +164,7 @@ static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_ // Hunt for the region that contains that address. FILE* fp = fopen("/proc/self/maps", "re"); if (fp == nullptr) { - __libc_fatal("couldn't open /proc/self/maps"); + async_safe_fatal("couldn't open /proc/self/maps"); } char line[BUFSIZ]; while (fgets(line, sizeof(line), fp) != NULL) { @@ -177,7 +178,7 @@ static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_ } } } - __libc_fatal("Stack not found in /proc/self/maps"); + async_safe_fatal("Stack not found in /proc/self/maps"); } int pthread_attr_getstack(const pthread_attr_t* attr, void** stack_base, size_t* stack_size) { diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index 6b3e14808..9f4481fd2 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -35,11 +35,12 @@ #include "pthread_internal.h" +#include + #include "private/bionic_macros.h" #include "private/bionic_prctl.h" #include "private/bionic_ssp.h" #include "private/bionic_tls.h" -#include "private/libc_logging.h" #include "private/ErrnoRestorer.h" // x86 uses segment descriptors rather than a direct pointer to TLS. @@ -60,13 +61,13 @@ void __init_tls(pthread_internal_t* thread) { size_t allocation_size = BIONIC_TLS_SIZE + 2 * PAGE_SIZE; void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (allocation == MAP_FAILED) { - __libc_fatal("failed to allocate TLS"); + async_safe_fatal("failed to allocate TLS"); } prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, allocation, allocation_size, "bionic TLS guard page"); thread->bionic_tls = reinterpret_cast(static_cast(allocation) + PAGE_SIZE); if (mprotect(thread->bionic_tls, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) { - __libc_fatal("failed to mprotect TLS"); + async_safe_fatal("failed to mprotect TLS"); } prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->bionic_tls, BIONIC_TLS_SIZE, "bionic TLS"); } @@ -118,8 +119,8 @@ int __init_thread(pthread_internal_t* thread) { // For backwards compatibility reasons, we only report failures on 64-bit devices. error = errno; #endif - __libc_format_log(ANDROID_LOG_WARN, "libc", - "pthread_create sched_setscheduler call failed: %s", strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create sched_setscheduler call failed: %s", strerror(errno)); } } @@ -134,7 +135,7 @@ static void* __create_thread_mapped_space(size_t mmap_size, size_t stack_guard_s int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; void* space = mmap(NULL, mmap_size, prot, flags, -1, 0); if (space == MAP_FAILED) { - __libc_format_log(ANDROID_LOG_WARN, + async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: couldn't allocate %zu-bytes mapped space: %s", mmap_size, strerror(errno)); @@ -144,9 +145,9 @@ static void* __create_thread_mapped_space(size_t mmap_size, size_t stack_guard_s // Stack is at the lower end of mapped space, stack guard region is at the lower end of stack. // Set the stack guard region to PROT_NONE, so we can detect thread stack overflow. if (mprotect(space, stack_guard_size, PROT_NONE) == -1) { - __libc_format_log(ANDROID_LOG_WARN, "libc", - "pthread_create failed: couldn't mprotect PROT_NONE %zu-byte stack guard region: %s", - stack_guard_size, strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "pthread_create failed: couldn't mprotect PROT_NONE %zu-byte stack guard region: %s", + stack_guard_size, strerror(errno)); munmap(space, mmap_size); return NULL; } @@ -281,7 +282,8 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, if (thread->mmap_size != 0) { munmap(thread->attr.stack_base, thread->mmap_size); } - __libc_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s", strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, "libc", "pthread_create failed: clone failed: %s", + strerror(errno)); return clone_errno; } diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp index 5819bc114..abd403bd4 100644 --- a/libc/bionic/pthread_internal.cpp +++ b/libc/bionic/pthread_internal.cpp @@ -33,10 +33,11 @@ #include #include +#include + #include "private/bionic_futex.h" #include "private/bionic_sdk_version.h" #include "private/bionic_tls.h" -#include "private/libc_logging.h" static pthread_internal_t* g_thread_list = nullptr; static pthread_rwlock_t g_thread_list_lock = PTHREAD_RWLOCK_INITIALIZER; @@ -116,9 +117,9 @@ pthread_internal_t* __pthread_internal_find(pthread_t thread_id) { // addresses might sometimes contain threads or things that look enough like // threads for us to do some real damage by continuing. // TODO: try getting rid of this when Treble lets us keep vendor blobs on an old API level. - __libc_format_log(ANDROID_LOG_WARN, "libc", "invalid pthread_t (0) passed to libc"); + async_safe_format_log(ANDROID_LOG_WARN, "libc", "invalid pthread_t (0) passed to libc"); } else { - __libc_fatal("invalid pthread_t %p passed to libc", thread); + async_safe_fatal("invalid pthread_t %p passed to libc", thread); } } return nullptr; diff --git a/libc/bionic/setjmp_cookie.cpp b/libc/bionic/setjmp_cookie.cpp index 4fa68c2bd..41a439feb 100644 --- a/libc/bionic/setjmp_cookie.cpp +++ b/libc/bionic/setjmp_cookie.cpp @@ -34,9 +34,10 @@ #include #include +#include + #include "private/bionic_arc4random.h" #include "private/bionic_globals.h" -#include "private/libc_logging.h" #include "private/KernelArgumentBlock.h" void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args) { @@ -49,7 +50,7 @@ void __libc_init_setjmp_cookie(libc_globals* globals, KernelArgumentBlock& args) extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_cookie_get(long sigflag) { if (sigflag & ~1) { - __libc_fatal("unexpected sigflag value: %ld", sigflag); + async_safe_fatal("unexpected sigflag value: %ld", sigflag); } return __libc_globals->setjmp_cookie | sigflag; @@ -58,12 +59,12 @@ extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_cookie_get(long sigflag) { // Aborts if cookie doesn't match, returns the signal flag otherwise. extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_cookie_check(long cookie) { if (__libc_globals->setjmp_cookie != (cookie & ~1)) { - __libc_fatal("setjmp cookie mismatch"); + async_safe_fatal("setjmp cookie mismatch"); } return cookie & 1; } extern "C" __LIBC_HIDDEN__ long __bionic_setjmp_checksum_mismatch() { - __libc_fatal("setjmp checksum mismatch"); + async_safe_fatal("setjmp checksum mismatch"); } diff --git a/libc/bionic/strerror_r.cpp b/libc/bionic/strerror_r.cpp index a0a0809ad..dad3fb35b 100644 --- a/libc/bionic/strerror_r.cpp +++ b/libc/bionic/strerror_r.cpp @@ -12,8 +12,9 @@ #include #include +#include + #include "private/ErrnoRestorer.h" -#include "private/libc_logging.h" struct Pair { int code; @@ -57,7 +58,7 @@ int strerror_r(int error_number, char* buf, size_t buf_len) { if (error_name != NULL) { length = strlcpy(buf, error_name, buf_len); } else { - length = __libc_format_buffer(buf, buf_len, "Unknown error %d", error_number); + length = async_safe_format_buffer(buf, buf_len, "Unknown error %d", error_number); } if (length >= buf_len) { errno_restorer.override(ERANGE); diff --git a/libc/bionic/syslog.cpp b/libc/bionic/syslog.cpp index 8e3f34f9a..9424573b8 100644 --- a/libc/bionic/syslog.cpp +++ b/libc/bionic/syslog.cpp @@ -19,7 +19,7 @@ #include #include -#include "private/libc_logging.h" +#include static const char* syslog_log_tag = NULL; static int syslog_priority_mask = 0xff; @@ -109,7 +109,7 @@ void vsyslog(int priority, const char* fmt, va_list args) { *dst = '\0'; } - // We can't let __libc_format_log do the formatting because it doesn't support + // We can't let async_safe_format_log do the formatting because it doesn't support // all the printf functionality. char log_line[1024]; vsnprintf(log_line, sizeof(log_line), log_fmt, args); @@ -118,5 +118,5 @@ void vsyslog(int priority, const char* fmt, va_list args) { free(const_cast(log_fmt)); } - __libc_format_log(android_log_priority, log_tag, "%s", log_line); + async_safe_format_log(android_log_priority, log_tag, "%s", log_line); } diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp index 9fb03acce..a9586994b 100644 --- a/libc/bionic/system_properties.cpp +++ b/libc/bionic/system_properties.cpp @@ -54,12 +54,13 @@ #include #include +#include + #include "private/ErrnoRestorer.h" #include "private/bionic_futex.h" #include "private/bionic_lock.h" #include "private/bionic_macros.h" #include "private/bionic_sdk_version.h" -#include "private/libc_logging.h" static constexpr int PROP_FILENAME_MAX = 1024; @@ -227,8 +228,8 @@ static prop_area* map_prop_area_rw(const char* filename, const char* context, if (context) { if (fsetxattr(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1, 0) != 0) { - __libc_format_log(ANDROID_LOG_ERROR, "libc", - "fsetxattr failed to set context (%s) for \"%s\"", context, filename); + async_safe_format_log(ANDROID_LOG_ERROR, "libc", + "fsetxattr failed to set context (%s) for \"%s\"", context, filename); /* * fsetxattr() will fail during system properties tests due to selinux policy. * We do not want to create a custom policy for the tester, so we will continue in @@ -640,9 +641,9 @@ static int send_prop_msg(const prop_msg* msg) { // ms so callers who do read-after-write can reliably see // what they've written. Most of the time. // TODO: fix the system properties design. - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Property service has timed out while trying to set \"%s\" to \"%s\"", - msg->name, msg->value); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "Property service has timed out while trying to set \"%s\" to \"%s\"", + msg->name, msg->value); result = 0; } } @@ -806,7 +807,8 @@ bool context_node::open(bool access_rw, bool* fsetxattr_failed) { } char filename[PROP_FILENAME_MAX]; - int len = __libc_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_); + int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, + context_); if (len < 0 || len > PROP_FILENAME_MAX) { lock_.unlock(); return false; @@ -841,7 +843,8 @@ void context_node::reset_access() { bool context_node::check_access() { char filename[PROP_FILENAME_MAX]; - int len = __libc_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, context_); + int len = async_safe_format_buffer(filename, sizeof(filename), "%s/%s", property_filename, + context_); if (len < 0 || len > PROP_FILENAME_MAX) { return false; } @@ -864,7 +867,8 @@ void context_node::unmap() { static bool map_system_property_area(bool access_rw, bool* fsetxattr_failed) { char filename[PROP_FILENAME_MAX]; int len = - __libc_format_buffer(filename, sizeof(filename), "%s/properties_serial", property_filename); + async_safe_format_buffer(filename, sizeof(filename), "%s/properties_serial", + property_filename); if (len < 0 || len > PROP_FILENAME_MAX) { __system_property_area__ = nullptr; return false; @@ -1152,7 +1156,7 @@ const prop_info* __system_property_find(const char* name) { prop_area* pa = get_prop_area_for_name(name); if (!pa) { - __libc_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name); + async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied finding property \"%s\"", name); return nullptr; } @@ -1184,11 +1188,11 @@ int __system_property_read(const prop_info* pi, char* name, char* value) { if (name != nullptr) { size_t namelen = strlcpy(name, pi->name, PROP_NAME_MAX); if (namelen >= PROP_NAME_MAX) { - __libc_format_log(ANDROID_LOG_ERROR, "libc", - "The property name length for \"%s\" is >= %d;" - " please use __system_property_read_callback" - " to read this property. (the name is truncated to \"%s\")", - pi->name, PROP_NAME_MAX - 1, name); + async_safe_format_log(ANDROID_LOG_ERROR, "libc", + "The property name length for \"%s\" is >= %d;" + " please use __system_property_read_callback" + " to read this property. (the name is truncated to \"%s\")", + pi->name, PROP_NAME_MAX - 1, name); } } return len; @@ -1239,17 +1243,17 @@ static void detect_protocol_version() { char value[PROP_VALUE_MAX]; if (__system_property_get(kServiceVersionPropertyName, value) == 0) { g_propservice_protocol_version = kProtocolVersion1; - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Using old property service protocol (\"%s\" is not set)", - kServiceVersionPropertyName); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "Using old property service protocol (\"%s\" is not set)", + kServiceVersionPropertyName); } else { uint32_t version = static_cast(atoll(value)); if (version >= kProtocolVersion2) { g_propservice_protocol_version = kProtocolVersion2; } else { - __libc_format_log(ANDROID_LOG_WARN, "libc", - "Using old property service protocol (\"%s\"=\"%s\")", - kServiceVersionPropertyName, value); + async_safe_format_log(ANDROID_LOG_WARN, "libc", + "Using old property service protocol (\"%s\"=\"%s\")", + kServiceVersionPropertyName, value); g_propservice_protocol_version = kProtocolVersion1; } } @@ -1280,49 +1284,49 @@ int __system_property_set(const char* key, const char* value) { PropertyServiceConnection connection; if (!connection.IsValid()) { errno = connection.GetLastError(); - __libc_format_log(ANDROID_LOG_WARN, - "libc", - "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", - key, - value, - errno, - strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, + "libc", + "Unable to set property \"%s\" to \"%s\": connection failed; errno=%d (%s)", + key, + value, + errno, + strerror(errno)); return -1; } SocketWriter writer(&connection); if (!writer.WriteUint32(PROP_MSG_SETPROP2).WriteString(key).WriteString(value).Send()) { errno = connection.GetLastError(); - __libc_format_log(ANDROID_LOG_WARN, - "libc", - "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)", - key, - value, - errno, - strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, + "libc", + "Unable to set property \"%s\" to \"%s\": write failed; errno=%d (%s)", + key, + value, + errno, + strerror(errno)); return -1; } int result = -1; if (!connection.RecvInt32(&result)) { errno = connection.GetLastError(); - __libc_format_log(ANDROID_LOG_WARN, - "libc", - "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)", - key, - value, - errno, - strerror(errno)); + async_safe_format_log(ANDROID_LOG_WARN, + "libc", + "Unable to set property \"%s\" to \"%s\": recv failed; errno=%d (%s)", + key, + value, + errno, + strerror(errno)); return -1; } if (result != PROP_SUCCESS) { - __libc_format_log(ANDROID_LOG_WARN, - "libc", - "Unable to set property \"%s\" to \"%s\": error code: 0x%x", - key, - value, - result); + async_safe_format_log(ANDROID_LOG_WARN, + "libc", + "Unable to set property \"%s\" to \"%s\": error code: 0x%x", + key, + value, + result); return -1; } @@ -1377,7 +1381,7 @@ int __system_property_add(const char* name, unsigned int namelen, const char* va prop_area* pa = get_prop_area_for_name(name); if (!pa) { - __libc_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name); + async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Access denied adding property \"%s\"", name); return -1; } diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c index 82e0ddfd8..9c6557090 100644 --- a/libc/dns/resolv/res_cache.c +++ b/libc/dns/resolv/res_cache.c @@ -47,7 +47,7 @@ #include "resolv_netid.h" #include "res_private.h" -#include "private/libc_logging.h" +#include /* This code implements a small and *simple* DNS resolver cache. * @@ -155,7 +155,7 @@ #define XLOG(...) ({ \ if (DEBUG) { \ - __libc_format_log(ANDROID_LOG_DEBUG,"libc",__VA_ARGS__); \ + async_safe_format_log(ANDROID_LOG_DEBUG,"libc",__VA_ARGS__); \ } else { \ ((void)0); \ } \ diff --git a/libc/dns/resolv/res_send.c b/libc/dns/resolv/res_send.c index f53da5f72..586bb8f1a 100644 --- a/libc/dns/resolv/res_send.c +++ b/libc/dns/resolv/res_send.c @@ -114,7 +114,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); #include -#include "private/libc_logging.h" +#include #ifndef DE_CONST #define DE_CONST(c,v) v = ((c) ? \ @@ -564,7 +564,7 @@ res_nsend(res_state statp, } if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "used send_vc %d\n", n); } @@ -576,7 +576,7 @@ res_nsend(res_state statp, } else { /* Use datagrams. */ if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_dg\n"); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using send_dg\n"); } n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, @@ -591,7 +591,7 @@ res_nsend(res_state statp, } if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n",n); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "used send_dg %d\n",n); } if (n < 0) @@ -599,7 +599,7 @@ res_nsend(res_state statp, if (n == 0) goto next_ns; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "time=%ld\n", time(NULL)); } if (v_circuit) @@ -739,7 +739,7 @@ static int get_timeout(const res_state statp, const int ns) timeout = 1; } if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using timeout of %d sec\n", timeout); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using timeout of %d sec\n", timeout); } return timeout; @@ -764,7 +764,7 @@ send_vc(res_state statp, void *tmp; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); } nsap = get_nsaddr(statp, (size_t)ns); @@ -993,7 +993,7 @@ connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int timeout = evConsTime((long)sec, 0L); finish = evAddTime(now, timeout); if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d send_vc\n", sock); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d send_vc\n", sock); } res = retrying_select(sock, &rset, &wset, &finish); @@ -1004,7 +1004,7 @@ connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int done: fcntl(sock, F_SETFL, origflags); if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d connect_with_timeout returning %d\n", sock, res); } return res; @@ -1020,7 +1020,7 @@ retrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct retry: if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select\n", sock); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select\n", sock); } now = evNowTime(); @@ -1040,7 +1040,7 @@ retry: n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); if (n == 0) { if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, " libc", + async_safe_format_log(ANDROID_LOG_DEBUG, " libc", " %d retrying_select timeout\n", sock); } errno = ETIMEDOUT; @@ -1050,7 +1050,7 @@ retry: if (errno == EINTR) goto retry; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select got error %d\n",sock, n); } return n; @@ -1060,7 +1060,7 @@ retry: if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { errno = error; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select dot error2 %d\n", sock, errno); } @@ -1068,7 +1068,7 @@ retry: } } if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", " %d retrying_select returning %d\n",sock, n); } diff --git a/libc/dns/resolv/res_state.c b/libc/dns/resolv/res_state.c index 4ed168c32..94124ff9b 100644 --- a/libc/dns/resolv/res_state.c +++ b/libc/dns/resolv/res_state.c @@ -41,9 +41,9 @@ #define DEBUG 0 #if DEBUG -# include "private/libc_logging.h" +# include # include /* for gettid() */ -# define D(...) __libc_format_log(ANDROID_LOG_DEBUG,"libc", __VA_ARGS__) +# define D(...) async_safe_format_log(ANDROID_LOG_DEBUG,"libc", __VA_ARGS__) #else # define D(...) do{}while(0) #endif diff --git a/libc/dns/resolv/res_stats.c b/libc/dns/resolv/res_stats.c index 99c79e465..97d54d204 100644 --- a/libc/dns/resolv/res_stats.c +++ b/libc/dns/resolv/res_stats.c @@ -18,9 +18,10 @@ #include #include -#include "resolv_stats.h" -#include "private/libc_logging.h" +#include + #include "isc/eventlib.h" +#include "resolv_stats.h" #define DBG 0 @@ -38,7 +39,7 @@ void _res_stats_set_sample(struct __res_sample* sample, time_t now, int rcode, int rtt) { if (DBG) { - __libc_format_log(ANDROID_LOG_INFO, "libc", "rcode = %d, sec = %d", rcode, rtt); + async_safe_format_log(ANDROID_LOG_INFO, "libc", "rcode = %d, sec = %d", rcode, rtt); } sample->at = now; sample->rcode = rcode; @@ -128,14 +129,15 @@ _res_stats_usable_server(const struct __res_params* params, struct __res_stats* if (successes >= 0 && errors >= 0 && timeouts >= 0) { int total = successes + errors + timeouts; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "NS stats: S %d + E %d + T %d + I %d " + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "NS stats: S %d + E %d + T %d + I %d " "= %d, rtt = %d, min_samples = %d\n", successes, errors, timeouts, internal_errors, total, rtt_avg, params->min_samples); } if (total >= params->min_samples && (errors > 0 || timeouts > 0)) { int success_rate = successes * 100 / total; if (DBG) { - __libc_format_log(ANDROID_LOG_DEBUG, "libc", "success rate %d%%\n", success_rate); + async_safe_format_log(ANDROID_LOG_DEBUG, "libc", "success rate %d%%\n", + success_rate); } if (success_rate < params->success_threshold) { // evNowTime() is used here instead of time() to stay consistent with the rest of @@ -146,13 +148,13 @@ _res_stats_usable_server(const struct __res_params* params, struct __res_stats* // date has been reached, however the code for returning the ring buffer to its // previous non-circular state would induce additional complexity. if (DBG) { - __libc_format_log(ANDROID_LOG_INFO, "libc", + async_safe_format_log(ANDROID_LOG_INFO, "libc", "samples stale, retrying server\n"); } _res_stats_clear_samples(stats); } else { if (DBG) { - __libc_format_log(ANDROID_LOG_INFO, "libc", + async_safe_format_log(ANDROID_LOG_INFO, "libc", "too many resolution errors, ignoring server\n"); } return 0; diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp index 708c10151..b071b90ae 100644 --- a/libc/malloc_debug/Android.bp +++ b/libc/malloc_debug/Android.bp @@ -13,9 +13,10 @@ cc_library_static { stl: "libc++_static", - static_libs: ["libc_logging"], + whole_static_libs: ["libasync_safe"], include_dirs: ["bionic/libc"], + export_include_dirs: ["."], sanitize: { @@ -29,7 +30,6 @@ cc_library_static { "-Werror", "-Wno-error=format-zero-length", ], - } // ============================================================== @@ -61,9 +61,9 @@ cc_library { }, static_libs: [ + "libasync_safe", "libbase", "libc_malloc_debug_backtrace", - "libc_logging", ], multilib: { @@ -89,7 +89,6 @@ cc_library { "-fno-stack-protector", "-Wno-error=format-zero-length", ], - } // ============================================================== @@ -118,7 +117,7 @@ cc_test { whole_static_libs: ["libc_malloc_debug"], local_include_dirs: ["tests"], - include_dirs: ["bionic/libc"], + include_dirs: ["bionic/libc", "bionic/libc/async_safe/include"], shared_libs: ["libbase"], @@ -127,5 +126,4 @@ cc_test { "-Werror", "-Wno-error=format-zero-length", ], - } diff --git a/libc/malloc_debug/backtrace.cpp b/libc/malloc_debug/backtrace.cpp index 75a255c0e..88f5a1de4 100644 --- a/libc/malloc_debug/backtrace.cpp +++ b/libc/malloc_debug/backtrace.cpp @@ -158,13 +158,13 @@ std::string backtrace_string(const uintptr_t* frames, size_t frame_count) { char* demangled_symbol = __cxa_demangle(symbol, nullptr, nullptr, nullptr); const char* best_name = (demangled_symbol != nullptr) ? demangled_symbol : symbol; - __libc_format_buffer(buf, sizeof(buf), - " #%02zd pc %" PAD_PTR " %s (%s+%" PRIuPTR ")\n", frame_num, + async_safe_format_buffer( + buf, sizeof(buf), " #%02zd pc %" PAD_PTR " %s (%s+%" PRIuPTR ")\n", frame_num, rel_pc, soname, best_name, frames[frame_num] - offset); free(demangled_symbol); } else { - __libc_format_buffer(buf, sizeof(buf), - " #%02zd pc %" PAD_PTR " %s\n", frame_num, rel_pc, soname); + async_safe_format_buffer( + buf, sizeof(buf), " #%02zd pc %" PAD_PTR " %s\n", frame_num, rel_pc, soname); } str += buf; } diff --git a/libc/malloc_debug/debug_log.h b/libc/malloc_debug/debug_log.h index 4df040805..ed4b54169 100644 --- a/libc/malloc_debug/debug_log.h +++ b/libc/malloc_debug/debug_log.h @@ -29,18 +29,18 @@ #ifndef MALLOC_DEBUG_LOG_H #define MALLOC_DEBUG_LOG_H -#include +#include // ============================================================================= // log functions // ============================================================================= #define debug_log(format, ...) \ - __libc_format_log(ANDROID_LOG_DEBUG, "malloc_debug", (format), ##__VA_ARGS__ ) + async_safe_format_log(ANDROID_LOG_DEBUG, "malloc_debug", (format), ##__VA_ARGS__ ) #define error_log(format, ...) \ - __libc_format_log(ANDROID_LOG_ERROR, "malloc_debug", (format), ##__VA_ARGS__ ) + async_safe_format_log(ANDROID_LOG_ERROR, "malloc_debug", (format), ##__VA_ARGS__ ) #define error_log_string(str) \ - __libc_write_log(ANDROID_LOG_ERROR, "malloc_debug", (str)) + async_safe_write_log(ANDROID_LOG_ERROR, "malloc_debug", (str)) #define info_log(format, ...) \ - __libc_format_log(ANDROID_LOG_INFO, "malloc_debug", (format), ##__VA_ARGS__ ) + async_safe_format_log(ANDROID_LOG_INFO, "malloc_debug", (format), ##__VA_ARGS__ ) #endif // MALLOC_DEBUG_LOG_H diff --git a/libc/malloc_debug/tests/log_fake.cpp b/libc/malloc_debug/tests/log_fake.cpp index 194d42be4..fb64e3eb7 100644 --- a/libc/malloc_debug/tests/log_fake.cpp +++ b/libc/malloc_debug/tests/log_fake.cpp @@ -44,7 +44,7 @@ std::string getFakeLogPrint() { return g_fake_log_print; } -extern "C" int __libc_format_log(int priority, const char* tag, const char* format, ...) { +extern "C" int async_safe_format_log(int priority, const char* tag, const char* format, ...) { g_fake_log_print += std::to_string(priority) + ' '; g_fake_log_print += tag; g_fake_log_print += ' '; diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h index 1133e2a9b..20afdecf6 100644 --- a/libc/private/WriteProtected.h +++ b/libc/private/WriteProtected.h @@ -23,9 +23,10 @@ #include #include +#include + #include "private/bionic_macros.h" #include "private/bionic_prctl.h" -#include "private/libc_logging.h" template union WriteProtectedContents { @@ -57,7 +58,7 @@ class WriteProtected { memset(&contents, 0, sizeof(contents)); if (mprotect(&contents, PAGE_SIZE, PROT_READ)) { - __libc_fatal("failed to make WriteProtected nonwritable in initialize"); + async_safe_fatal("failed to make WriteProtected nonwritable in initialize"); } } @@ -72,13 +73,13 @@ class WriteProtected { template void mutate(Mutator mutator) { if (mprotect(&contents, PAGE_SIZE, PROT_READ | PROT_WRITE) != 0) { - __libc_fatal("failed to make WriteProtected writable in mutate: %s", - strerror(errno)); + async_safe_fatal("failed to make WriteProtected writable in mutate: %s", + strerror(errno)); } mutator(&contents.value); if (mprotect(&contents, PAGE_SIZE, PROT_READ) != 0) { - __libc_fatal("failed to make WriteProtected nonwritable in mutate: %s", - strerror(errno)); + async_safe_fatal("failed to make WriteProtected nonwritable in mutate: %s", + strerror(errno)); } } }; diff --git a/libc/private/bionic_fortify.h b/libc/private/bionic_fortify.h index df810cabf..8591117be 100644 --- a/libc/private/bionic_fortify.h +++ b/libc/private/bionic_fortify.h @@ -26,11 +26,21 @@ * SUCH DAMAGE. */ -#include "private/libc_logging.h" - #include // For struct pollfd. +#include +#include #include // For struct fd_set. +#include + +static inline __noreturn void __fortify_fatal(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + async_safe_fatal_va_list("FORTIFY", fmt, args); + va_end(args); + abort(); +} + // // Common helpers. // diff --git a/libc/stdio/stdio_ext.cpp b/libc/stdio/stdio_ext.cpp index f2f58c61f..ebc705c87 100644 --- a/libc/stdio/stdio_ext.cpp +++ b/libc/stdio/stdio_ext.cpp @@ -31,8 +31,9 @@ #include #include +#include + #include "local.h" -#include "private/libc_logging.h" size_t __fbufsize(FILE* fp) { return fp->_bf._size; @@ -83,7 +84,7 @@ int __fsetlocking(FILE* fp, int type) { if (type != FSETLOCKING_INTERNAL && type != FSETLOCKING_BYCALLER) { // The API doesn't let us report an error, so blow up. - __libc_fatal("Bad type (%d) passed to __fsetlocking", type); + async_safe_fatal("Bad type (%d) passed to __fsetlocking", type); } _EXT(fp)->_caller_handles_locking = (type == FSETLOCKING_BYCALLER); diff --git a/libc/upstream-openbsd/android/include/arc4random.h b/libc/upstream-openbsd/android/include/arc4random.h index 0d70c815d..d006045f6 100644 --- a/libc/upstream-openbsd/android/include/arc4random.h +++ b/libc/upstream-openbsd/android/include/arc4random.h @@ -27,8 +27,9 @@ #include #include +#include + #include "private/bionic_prctl.h" -#include "private/libc_logging.h" // Android gets these from "thread_private.h". #include "thread_private.h" @@ -47,7 +48,7 @@ extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void static inline void _getentropy_fail(void) { - __libc_fatal("getentropy failed"); + async_safe_fatal("getentropy failed"); } volatile sig_atomic_t _rs_forked; diff --git a/linker/Android.bp b/linker/Android.bp index d6171890e..efd91ac88 100644 --- a/linker/Android.bp +++ b/linker/Android.bp @@ -9,6 +9,8 @@ cc_library_static { // We need to access Bionic private headers in the linker. include_dirs: ["bionic/libc"], + + static_libs: ["libasync_safe"], } cc_binary { diff --git a/linker/linker.cpp b/linker/linker.cpp index afd990a53..0b4490dbe 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -46,6 +46,8 @@ #include +#include + // Private C library headers. #include "linker.h" @@ -344,7 +346,7 @@ static void parse_LD_LIBRARY_PATH(const char* path) { static bool realpath_fd(int fd, std::string* realpath) { std::vector buf(PATH_MAX), proc_self_fd(PATH_MAX); - __libc_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd); + async_safe_format_buffer(&proc_self_fd[0], proc_self_fd.size(), "/proc/self/fd/%d", fd); if (readlink(&proc_self_fd[0], &buf[0], buf.size()) == -1) { PRINT("readlink(\"%s\") failed: %s [fd=%d]", &proc_self_fd[0], strerror(errno), fd); return false; @@ -493,7 +495,7 @@ ProtectedDataGuard::ProtectedDataGuard() { } if (ref_count_ == 0) { // overflow - __libc_fatal("Too many nested calls to dlopen()"); + async_safe_fatal("Too many nested calls to dlopen()"); } } @@ -992,7 +994,7 @@ static int open_library_in_zipfile(ZipArchiveCache* zip_archive_cache, } static bool format_path(char* buf, size_t buf_size, const char* path, const char* name) { - int n = __libc_format_buffer(buf, buf_size, "%s/%s", path, name); + int n = async_safe_format_buffer(buf, buf_size, "%s/%s", path, name); if (n < 0 || n >= static_cast(buf_size)) { PRINT("Warning: ignoring very long library path: %s/%s", path, name); return false; @@ -1781,7 +1783,7 @@ static void soinfo_unload(soinfo* soinfos[], size_t count) { } } else { #if !defined(__work_around_b_24465209__) - __libc_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si); + async_safe_fatal("soinfo for \"%s\"@%p has no version", si->get_realpath(), si); #else PRINT("warning: soinfo for \"%s\"@%p has no version", si->get_realpath(), si); for_each_dt_needed(si, [&] (const char* library_name) { @@ -1855,8 +1857,8 @@ void do_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) { } if (buffer_size < required_size) { - __libc_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: " - "buffer len %zu, required len %zu", buffer_size, required_size); + async_safe_fatal("android_get_LD_LIBRARY_PATH failed, buffer too small: " + "buffer len %zu, required len %zu", buffer_size, required_size); } char* end = buffer; diff --git a/linker/linker.h b/linker/linker.h index 53dac6c85..fdd7b6679 100644 --- a/linker/linker.h +++ b/linker/linker.h @@ -38,7 +38,6 @@ #include #include "private/bionic_page.h" -#include "private/libc_logging.h" #include "linked_list.h" #include "linker_common_types.h" #include "linker_logger.h" diff --git a/linker/linker_allocator.cpp b/linker/linker_allocator.cpp index 723ea2ba9..fd6f4964b 100644 --- a/linker/linker_allocator.cpp +++ b/linker/linker_allocator.cpp @@ -37,6 +37,8 @@ #include #include +#include + #include "private/bionic_prctl.h" // @@ -149,7 +151,7 @@ void LinkerSmallObjectAllocator::free(void* ptr) { ssize_t offset = reinterpret_cast(ptr) - sizeof(page_info); if (offset % block_size_ != 0) { - __libc_fatal("invalid pointer: %p (block_size=%zd)", ptr, block_size_); + async_safe_fatal("invalid pointer: %p (block_size=%zd)", ptr, block_size_); } memset(ptr, 0, block_size_); @@ -180,7 +182,7 @@ linker_vector_t::iterator LinkerSmallObjectAllocator::find_page_record(void* ptr if (it == page_records_.end() || it->page_addr != addr) { // not found... - __libc_fatal("page record for %p was not found (block_size=%zd)", ptr, block_size_); + async_safe_fatal("page record for %p was not found (block_size=%zd)", ptr, block_size_); } return it; @@ -203,7 +205,7 @@ void LinkerSmallObjectAllocator::alloc_page() { void* map_ptr = mmap(nullptr, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (map_ptr == MAP_FAILED) { - __libc_fatal("mmap failed"); + async_safe_fatal("mmap failed"); } prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, PAGE_SIZE, "linker_alloc_small_objects"); @@ -248,7 +250,7 @@ void* LinkerMemoryAllocator::alloc_mmap(size_t size) { PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); if (map_ptr == MAP_FAILED) { - __libc_fatal("mmap failed"); + async_safe_fatal("mmap failed"); } prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, map_ptr, allocated_size, "linker_alloc_lob"); @@ -283,7 +285,7 @@ void* LinkerMemoryAllocator::alloc(size_t size) { page_info* LinkerMemoryAllocator::get_page_info(void* ptr) { page_info* info = reinterpret_cast(PAGE_START(reinterpret_cast(ptr))); if (memcmp(info->signature, kSignature, sizeof(kSignature)) != 0) { - __libc_fatal("invalid pointer %p (page signature mismatch)", ptr); + async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr); } return info; @@ -308,7 +310,7 @@ void* LinkerMemoryAllocator::realloc(void* ptr, size_t size) { } else { LinkerSmallObjectAllocator* allocator = get_small_object_allocator(info->type); if (allocator != info->allocator_addr) { - __libc_fatal("invalid pointer %p (page signature mismatch)", ptr); + async_safe_fatal("invalid pointer %p (page signature mismatch)", ptr); } old_size = allocator->get_block_size(); @@ -336,7 +338,7 @@ void LinkerMemoryAllocator::free(void* ptr) { } else { LinkerSmallObjectAllocator* allocator = get_small_object_allocator(info->type); if (allocator != info->allocator_addr) { - __libc_fatal("invalid pointer %p (invalid allocator address for the page)", ptr); + async_safe_fatal("invalid pointer %p (invalid allocator address for the page)", ptr); } allocator->free(ptr); @@ -345,7 +347,7 @@ void LinkerMemoryAllocator::free(void* ptr) { LinkerSmallObjectAllocator* LinkerMemoryAllocator::get_small_object_allocator(uint32_t type) { if (type < kSmallObjectMinSizeLog2 || type > kSmallObjectMaxSizeLog2) { - __libc_fatal("invalid type: %u", type); + async_safe_fatal("invalid type: %u", type); } initialize_allocators(); diff --git a/linker/linker_allocator.h b/linker/linker_allocator.h index beffc52db..80ae5080c 100644 --- a/linker/linker_allocator.h +++ b/linker/linker_allocator.h @@ -37,8 +37,9 @@ #include +#include + #include "private/bionic_prctl.h" -#include "private/libc_logging.h" const uint32_t kSmallObjectMaxSizeLog2 = 10; const uint32_t kSmallObjectMinSizeLog2 = 4; @@ -92,7 +93,7 @@ class linker_vector_allocator { if (ptr == MAP_FAILED) { // Spec says we need to throw std::bad_alloc here but because our // code does not support exception handling anyways - we are going to abort. - __libc_fatal("mmap failed"); + async_safe_fatal("mmap failed"); } prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, ptr, size, "linker_alloc_vector"); diff --git a/linker/linker_config.cpp b/linker/linker_config.cpp index f614ba066..0a9aeab2a 100644 --- a/linker/linker_config.cpp +++ b/linker/linker_config.cpp @@ -36,6 +36,8 @@ #include #include +#include + #include #include @@ -149,7 +151,7 @@ static std::string create_error_msg(const char* file, size_t lineno, const std::string& msg) { char buf[1024]; - __libc_format_buffer(buf, sizeof(buf), "%s:%zu: error: %s", file, lineno, msg.c_str()); + async_safe_format_buffer(buf, sizeof(buf), "%s:%zu: error: %s", file, lineno, msg.c_str()); return std::string(buf); } @@ -328,7 +330,7 @@ class Properties { params.push_back({ "LIB", kLibParamValue }); if (target_sdk_version_ != 0) { char buf[16]; - __libc_format_buffer(buf, sizeof(buf), "%d", target_sdk_version_); + async_safe_format_buffer(buf, sizeof(buf), "%d", target_sdk_version_); params.push_back({ "SDK_VER", buf }); } diff --git a/linker/linker_debug.h b/linker/linker_debug.h index 42796e99b..7ceab0814 100644 --- a/linker/linker_debug.h +++ b/linker/linker_debug.h @@ -54,20 +54,21 @@ * To enable/disable specific debug options, change the defines above *********************************************************************/ -#include "private/libc_logging.h" #include +#include + __LIBC_HIDDEN__ extern int g_ld_debug_verbosity; #if LINKER_DEBUG_TO_LOG #define _PRINTVF(v, x...) \ do { \ - if (g_ld_debug_verbosity > (v)) __libc_format_log(5-(v), "linker", x); \ + if (g_ld_debug_verbosity > (v)) async_safe_format_log(5-(v), "linker", x); \ } while (0) #else /* !LINKER_DEBUG_TO_LOG */ #define _PRINTVF(v, x...) \ do { \ - if (g_ld_debug_verbosity > (v)) { __libc_format_fd(1, x); write(1, "\n", 1); } \ + if (g_ld_debug_verbosity > (v)) { async_safe_format_fd(1, x); write(1, "\n", 1); } \ } while (0) #endif /* !LINKER_DEBUG_TO_LOG */ diff --git a/linker/linker_globals.h b/linker/linker_globals.h index 1ed479c2e..d8134afc4 100644 --- a/linker/linker_globals.h +++ b/linker/linker_globals.h @@ -34,20 +34,20 @@ #include -#include "private/libc_logging.h" +#include #define DL_ERR(fmt, x...) \ do { \ - __libc_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \ + async_safe_format_buffer(linker_get_error_buffer(), linker_get_error_buffer_size(), fmt, ##x); \ /* If LD_DEBUG is set high enough, log every dlerror(3) message. */ \ } while (false) #define DL_WARN(fmt, x...) \ do { \ - __libc_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \ - __libc_format_fd(2, "WARNING: linker: "); \ - __libc_format_fd(2, fmt, ##x); \ - __libc_format_fd(2, "\n"); \ + async_safe_format_log(ANDROID_LOG_WARN, "linker", fmt, ##x); \ + async_safe_format_fd(2, "WARNING: linker: "); \ + async_safe_format_fd(2, fmt, ##x); \ + async_safe_format_fd(2, "\n"); \ } while (false) #define DL_ERR_AND_LOG(fmt, x...) \ diff --git a/linker/linker_libcxx_support.cpp b/linker/linker_libcxx_support.cpp index e7b23e056..11e0f40be 100644 --- a/linker/linker_libcxx_support.cpp +++ b/linker/linker_libcxx_support.cpp @@ -26,8 +26,8 @@ * SUCH DAMAGE. */ -#include "private/libc_logging.h" +#include void* __find_icu_symbol(const char* symbol_name __attribute__((__unused__))) { - __libc_fatal("__find_icu_symbol should not be called in the linker"); + async_safe_fatal("__find_icu_symbol should not be called in the linker"); } diff --git a/linker/linker_logger.cpp b/linker/linker_logger.cpp index 717667ca8..4c6603b6a 100644 --- a/linker/linker_logger.cpp +++ b/linker/linker_logger.cpp @@ -35,9 +35,10 @@ #include #include +#include + #include "android-base/strings.h" #include "private/CachedProperty.h" -#include "private/libc_logging.h" LinkerLogger g_linker_logger; bool g_greylist_disabled = false; @@ -59,8 +60,8 @@ static uint32_t ParseProperty(const std::string& value) { } else if (o == "dlsym") { flags |= kLogDlsym; } else { - __libc_format_log(ANDROID_LOG_WARN, "linker", "Ignoring unknown debug.ld option \"%s\"", - o.c_str()); + async_safe_format_log(ANDROID_LOG_WARN, "linker", "Ignoring unknown debug.ld option \"%s\"", + o.c_str()); } } @@ -95,8 +96,8 @@ void LinkerLogger::ResetState() { bool old_value = g_greylist_disabled; g_greylist_disabled = (strcmp(greylist_disabled.Get(), "true") == 0); if (g_greylist_disabled != old_value) { - __libc_format_log(ANDROID_LOG_INFO, "linker", "%s greylist", - g_greylist_disabled ? "Disabling" : "Enabling"); + async_safe_format_log(ANDROID_LOG_INFO, "linker", "%s greylist", + g_greylist_disabled ? "Disabling" : "Enabling"); } flags_ = 0; @@ -124,6 +125,6 @@ void LinkerLogger::Log(uint32_t type, const char* format, ...) { va_list ap; va_start(ap, format); - __libc_format_log_va_list(ANDROID_LOG_DEBUG, "linker", format, ap); + async_safe_format_log_va_list(ANDROID_LOG_DEBUG, "linker", format, ap); va_end(ap); } diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index 40f82a1bf..3d26e91f3 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -45,6 +45,8 @@ #include "debuggerd/handler.h" #endif +#include + #include extern void __libc_init_globals(KernelArgumentBlock&); @@ -189,7 +191,7 @@ static const char* get_executable_path() { char path[PATH_MAX]; ssize_t path_len = readlink("/proc/self/exe", path, sizeof(path)); if (path_len == -1 || path_len >= static_cast(sizeof(path))) { - __libc_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno)); + async_safe_fatal("readlink('/proc/self/exe') failed: %s", strerror(errno)); } executable_path = std::string(path, path_len); } @@ -267,13 +269,13 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( // the executable could be unlinked by this point and it should // not cause a crash (see http://b/31084669) if (TEMP_FAILURE_RETRY(stat("/proc/self/exe", &file_stat)) != 0) { - __libc_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno)); + async_safe_fatal("unable to stat \"/proc/self/exe\": %s", strerror(errno)); } const char* executable_path = get_executable_path(); soinfo* si = soinfo_alloc(&g_default_namespace, executable_path, &file_stat, 0, RTLD_GLOBAL); if (si == nullptr) { - __libc_fatal("Couldn't allocate soinfo: out of memory?"); + async_safe_fatal("Couldn't allocate soinfo: out of memory?"); } /* bootstrap the link map, the main exe always needs to be first */ @@ -319,7 +321,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( // tombstone for them. The tombstone never provided any detail relevant to // fixing the problem anyway, and the utility of drawing extra attention // to the problem is non-existent at this late date. - __libc_format_fd(STDERR_FILENO, + async_safe_format_fd(STDERR_FILENO, "\"%s\": error: Android 5.0 and later only support " "position-independent executables (-fPIE).\n", g_argv[0]); @@ -335,7 +337,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( init_default_namespace(executable_path); if (!si->prelink_image()) { - __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); + async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); } // add somain to global group @@ -369,10 +371,10 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( nullptr, true /* add_as_children */, true /* search_linked_namespaces */)) { - __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); + async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); } else if (needed_libraries_count == 0) { if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) { - __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); + async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); } si->increment_ref_count(); } @@ -380,7 +382,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args, ElfW( add_vdso(args); if (!get_cfi_shadow()->InitialLinkDone(solist)) { - __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); + async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", g_argv[0], linker_get_error_buffer()); } si->call_pre_init_constructors(); @@ -464,7 +466,7 @@ static ElfW(Addr) get_elf_exec_load_bias(const ElfW(Ehdr)* elf) { } static void __linker_cannot_link(const char* argv0) { - __libc_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer()); + async_safe_fatal("CANNOT LINK EXECUTABLE \"%s\": %s", argv0, linker_get_error_buffer()); } /* @@ -546,7 +548,7 @@ extern "C" ElfW(Addr) __linker_init(void* raw_args) { // This happens when user tries to run 'adb shell /system/bin/linker' // see also https://code.google.com/p/android/issues/detail?id=63174 if (reinterpret_cast(&_start) == entry_point) { - __libc_format_fd(STDOUT_FILENO, + async_safe_format_fd(STDOUT_FILENO, "This is %s, the helper program for dynamic executables.\n", args.argv[0]); exit(0); diff --git a/linker/linker_memory.cpp b/linker/linker_memory.cpp index f8852e122..472c4e891 100644 --- a/linker/linker_memory.cpp +++ b/linker/linker_memory.cpp @@ -32,7 +32,7 @@ #include #include -#include "private/libc_logging.h" +#include static LinkerMemoryAllocator g_linker_allocator; static pid_t fallback_tid = 0; @@ -41,7 +41,7 @@ static pid_t fallback_tid = 0; // case the linker heap is corrupted. Do not use this function. extern "C" void __linker_enable_fallback_allocator() { if (fallback_tid != 0) { - __libc_fatal("attempted to use currently-in-use fallback allocator"); + async_safe_fatal("attempted to use currently-in-use fallback allocator"); } fallback_tid = gettid(); @@ -49,7 +49,7 @@ extern "C" void __linker_enable_fallback_allocator() { extern "C" void __linker_disable_fallback_allocator() { if (fallback_tid == 0) { - __libc_fatal("attempted to disable unused fallback allocator"); + async_safe_fatal("attempted to disable unused fallback allocator"); } fallback_tid = 0; diff --git a/linker/linker_sleb128.h b/linker/linker_sleb128.h index 74b69e498..01e127d05 100644 --- a/linker/linker_sleb128.h +++ b/linker/linker_sleb128.h @@ -31,6 +31,8 @@ #include +#include + #include "linker_debug.h" // Helper classes for decoding LEB128, used in packed relocation data. @@ -50,7 +52,7 @@ class sleb128_decoder { do { if (current_ >= end_) { - __libc_fatal("sleb128_decoder ran out of bounds"); + async_safe_fatal("sleb128_decoder ran out of bounds"); } byte = *current_++; value |= (static_cast(byte & 127) << shift); diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp index 1d59dbb9f..fbff7cf60 100644 --- a/linker/linker_soinfo.cpp +++ b/linker/linker_soinfo.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include "linker_debug.h" #include "linker_globals.h" #include "linker_logger.h" @@ -636,7 +638,7 @@ ElfW(Addr) soinfo::resolve_symbol_address(const ElfW(Sym)* s) const { const char* soinfo::get_string(ElfW(Word) index) const { if (has_min_version(1) && (index >= strtab_size_)) { - __libc_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d", + async_safe_fatal("%s: strtab out of bounds error; STRSZ=%zd, name=%d", get_realpath(), strtab_size_, index); } diff --git a/linker/tests/Android.mk b/linker/tests/Android.mk index 61c43c908..8284beaac 100644 --- a/linker/tests/Android.mk +++ b/linker/tests/Android.mk @@ -51,9 +51,6 @@ LOCAL_SRC_FILES := \ ../linker_config.cpp \ ../linker_utils.cpp \ -# for __libc_fatal -LOCAL_SRC_FILES += ../../libc/bionic/libc_logging.cpp - -LOCAL_STATIC_LIBRARIES += libbase +LOCAL_STATIC_LIBRARIES += libasync_safe libbase include $(BUILD_NATIVE_TEST) diff --git a/tests/Android.bp b/tests/Android.bp index d4e3800fd..4605267ac 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -52,6 +52,7 @@ cc_test_library { defaults: ["bionic_tests_defaults"], srcs: [ "arpa_inet_test.cpp", + "async_safe_test.cpp", "assert_test.cpp", "buffer_tests.cpp", "bug_26110743_test.cpp", @@ -72,7 +73,6 @@ cc_test_library { "inttypes_test.cpp", "langinfo_test.cpp", "leak_test.cpp", - "libc_logging_test.cpp", "libgen_basename_test.cpp", "libgen_test.cpp", "linux_swab_test.cpp", @@ -151,6 +151,12 @@ cc_test_library { "external/tinyxml2", ], + target: { + android: { + whole_static_libs: ["libasync_safe"], + }, + }, + static_libs: [ "libtinyxml2", "liblog", diff --git a/tests/libc_logging_test.cpp b/tests/async_safe_test.cpp similarity index 55% rename from tests/libc_logging_test.cpp rename to tests/async_safe_test.cpp index 4150483e1..3d6fcaa8f 100644 --- a/tests/libc_logging_test.cpp +++ b/tests/async_safe_test.cpp @@ -17,122 +17,121 @@ #include #if defined(__BIONIC__) -#include "../libc/bionic/libc_logging.cpp" -extern int __libc_format_buffer(char* buffer, size_t buffer_size, const char* format, ...); +#include #endif // __BIONIC__ -TEST(libc_logging, smoke) { +TEST(async_safe_log, smoke) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "a"); + async_safe_format_buffer(buf, sizeof(buf), "a"); EXPECT_STREQ("a", buf); - __libc_format_buffer(buf, sizeof(buf), "%%"); + async_safe_format_buffer(buf, sizeof(buf), "%%"); EXPECT_STREQ("%", buf); - __libc_format_buffer(buf, sizeof(buf), "01234"); + async_safe_format_buffer(buf, sizeof(buf), "01234"); EXPECT_STREQ("01234", buf); - __libc_format_buffer(buf, sizeof(buf), "a%sb", "01234"); + async_safe_format_buffer(buf, sizeof(buf), "a%sb", "01234"); EXPECT_STREQ("a01234b", buf); char* s = NULL; - __libc_format_buffer(buf, sizeof(buf), "a%sb", s); + async_safe_format_buffer(buf, sizeof(buf), "a%sb", s); EXPECT_STREQ("a(null)b", buf); - __libc_format_buffer(buf, sizeof(buf), "aa%scc", "bb"); + async_safe_format_buffer(buf, sizeof(buf), "aa%scc", "bb"); EXPECT_STREQ("aabbcc", buf); - __libc_format_buffer(buf, sizeof(buf), "a%cc", 'b'); + async_safe_format_buffer(buf, sizeof(buf), "a%cc", 'b'); EXPECT_STREQ("abc", buf); - __libc_format_buffer(buf, sizeof(buf), "a%db", 1234); + async_safe_format_buffer(buf, sizeof(buf), "a%db", 1234); EXPECT_STREQ("a1234b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%db", -8123); + async_safe_format_buffer(buf, sizeof(buf), "a%db", -8123); EXPECT_STREQ("a-8123b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%hdb", static_cast(0x7fff0010)); + async_safe_format_buffer(buf, sizeof(buf), "a%hdb", static_cast(0x7fff0010)); EXPECT_STREQ("a16b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%hhdb", static_cast(0x7fffff10)); + async_safe_format_buffer(buf, sizeof(buf), "a%hhdb", static_cast(0x7fffff10)); EXPECT_STREQ("a16b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%lldb", 0x1000000000LL); + async_safe_format_buffer(buf, sizeof(buf), "a%lldb", 0x1000000000LL); EXPECT_STREQ("a68719476736b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%ldb", 70000L); + async_safe_format_buffer(buf, sizeof(buf), "a%ldb", 70000L); EXPECT_STREQ("a70000b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast(0xb0001234)); + async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast(0xb0001234)); EXPECT_STREQ("a0xb0001234b", buf); - __libc_format_buffer(buf, sizeof(buf), "a%xz", 0x12ab); + async_safe_format_buffer(buf, sizeof(buf), "a%xz", 0x12ab); EXPECT_STREQ("a12abz", buf); - __libc_format_buffer(buf, sizeof(buf), "a%Xz", 0x12ab); + async_safe_format_buffer(buf, sizeof(buf), "a%Xz", 0x12ab); EXPECT_STREQ("a12ABz", buf); - __libc_format_buffer(buf, sizeof(buf), "a%08xz", 0x123456); + async_safe_format_buffer(buf, sizeof(buf), "a%08xz", 0x123456); EXPECT_STREQ("a00123456z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%5dz", 1234); + async_safe_format_buffer(buf, sizeof(buf), "a%5dz", 1234); EXPECT_STREQ("a 1234z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%05dz", 1234); + async_safe_format_buffer(buf, sizeof(buf), "a%05dz", 1234); EXPECT_STREQ("a01234z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%8dz", 1234); + async_safe_format_buffer(buf, sizeof(buf), "a%8dz", 1234); EXPECT_STREQ("a 1234z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%-8dz", 1234); + async_safe_format_buffer(buf, sizeof(buf), "a%-8dz", 1234); EXPECT_STREQ("a1234 z", buf); - __libc_format_buffer(buf, sizeof(buf), "A%-11sZ", "abcdef"); + async_safe_format_buffer(buf, sizeof(buf), "A%-11sZ", "abcdef"); EXPECT_STREQ("Aabcdef Z", buf); - __libc_format_buffer(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); + async_safe_format_buffer(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); EXPECT_STREQ("Ahello:1234Z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); + async_safe_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); EXPECT_STREQ("a005:5:05z", buf); void* p = NULL; - __libc_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p); + async_safe_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p); EXPECT_STREQ("a5,0x0z", buf); - __libc_format_buffer(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); + async_safe_format_buffer(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); EXPECT_STREQ("a68719476736,6,7,8z", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ } -TEST(libc_logging, d_INT_MAX) { +TEST(async_safe_log, d_INT_MAX) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%d", INT_MAX); + async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MAX); EXPECT_STREQ("2147483647", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ } -TEST(libc_logging, d_INT_MIN) { +TEST(async_safe_log, d_INT_MIN) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%d", INT_MIN); + async_safe_format_buffer(buf, sizeof(buf), "%d", INT_MIN); EXPECT_STREQ("-2147483648", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ } -TEST(libc_logging, ld_LONG_MAX) { +TEST(async_safe_log, ld_LONG_MAX) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%ld", LONG_MAX); + async_safe_format_buffer(buf, sizeof(buf), "%ld", LONG_MAX); #if defined(__LP64__) EXPECT_STREQ("9223372036854775807", buf); #else @@ -143,10 +142,10 @@ TEST(libc_logging, ld_LONG_MAX) { #endif // __BIONIC__ } -TEST(libc_logging, ld_LONG_MIN) { +TEST(async_safe_log, ld_LONG_MIN) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%ld", LONG_MIN); + async_safe_format_buffer(buf, sizeof(buf), "%ld", LONG_MIN); #if defined(__LP64__) EXPECT_STREQ("-9223372036854775808", buf); #else @@ -157,32 +156,32 @@ TEST(libc_logging, ld_LONG_MIN) { #endif // __BIONIC__ } -TEST(libc_logging, lld_LLONG_MAX) { +TEST(async_safe_log, lld_LLONG_MAX) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%lld", LLONG_MAX); + async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MAX); EXPECT_STREQ("9223372036854775807", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ } -TEST(libc_logging, lld_LLONG_MIN) { +TEST(async_safe_log, lld_LLONG_MIN) { #if defined(__BIONIC__) char buf[BUFSIZ]; - __libc_format_buffer(buf, sizeof(buf), "%lld", LLONG_MIN); + async_safe_format_buffer(buf, sizeof(buf), "%lld", LLONG_MIN); EXPECT_STREQ("-9223372036854775808", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; #endif // __BIONIC__ } -TEST(libc_logging, buffer_overrun) { +TEST(async_safe_log, buffer_overrun) { #if defined(__BIONIC__) char buf[BUFSIZ]; - ASSERT_EQ(11, __libc_format_buffer(buf, sizeof(buf), "hello %s", "world")); + ASSERT_EQ(11, async_safe_format_buffer(buf, sizeof(buf), "hello %s", "world")); EXPECT_STREQ("hello world", buf); - ASSERT_EQ(11, __libc_format_buffer(buf, 8, "hello %s", "world")); + ASSERT_EQ(11, async_safe_format_buffer(buf, 8, "hello %s", "world")); EXPECT_STREQ("hello w", buf); #else // __BIONIC__ GTEST_LOG_(INFO) << "This test does nothing.\n"; -- 2.11.0