From 695713e931f0436aca56be9c0dacf2a5dd4e56e7 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Tue, 20 Jun 2017 17:28:42 -0700 Subject: [PATCH] Shave a stack frame off asserts. No-one cares about seeing "async_safe_fatal" (which you have to admit is a pretty confusing name for an app developer anyway). On arm: #00 pc 0001a43c /system/lib/libc.so (abort+63) #01 pc 0001a627 /system/lib/libc.so (__assert+14) And aarch64: #00 pc 000000000001d75c /system/lib64/libc.so (abort+120) #01 pc 000000000001dad0 /system/lib64/libc.so (__assert+44) Bug: N/A Test: ran `crasher assert` and `crasher64 assert` Change-Id: I00be71c566c74cdb00f8e95d634777155bc3da03 --- libc/async_safe/async_safe_log.cpp | 3 +-- libc/async_safe/include/async_safe/log.h | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp index 372f385b2b..99ff0c7f97 100644 --- a/libc/async_safe/async_safe_log.cpp +++ b/libc/async_safe/async_safe_log.cpp @@ -567,10 +567,9 @@ void async_safe_fatal_va_list(const char* prefix, const char* format, va_list ar android_set_abort_message(msg); } -void async_safe_fatal(const char* fmt, ...) { +void async_safe_fatal_no_abort(const char* fmt, ...) { va_list args; va_start(args, fmt); async_safe_fatal_va_list(nullptr, fmt, args); va_end(args); - abort(); } diff --git a/libc/async_safe/include/async_safe/log.h b/libc/async_safe/include/async_safe/log.h index f93f672650..6fdb84f0dd 100644 --- a/libc/async_safe/include/async_safe/log.h +++ b/libc/async_safe/include/async_safe/log.h @@ -33,6 +33,7 @@ #include #include #include +#include // These functions do not allocate memory to send data to the log. @@ -65,9 +66,19 @@ enum { }; // Formats a message to the log (priority 'fatal'), then aborts. -__noreturn void async_safe_fatal(const char* _Nonnull fmt, ...) __printflike(1, 2); +// Implemented as a macro so that async_safe_fatal isn't on the stack when we crash: +// we appear to go straight from the caller to abort, saving an uninteresting stack +// frame. +#define async_safe_fatal(...) \ + do { \ + async_safe_fatal_no_abort(__VA_ARGS__); \ + abort(); \ + } while (0) \ + -// This function does return, so callers that want to abort, must do so themselves. +// These functions do return, so callers that want to abort, must do so themselves, +// or use the macro above. +void async_safe_fatal_no_abort(const char* _Nonnull fmt, ...) __printflike(1, 2); #if defined(__arm__) || defined(__aarch64__) || defined(__x86_64__) void async_safe_fatal_va_list( const char* _Nullable prefix, const char* _Nonnull fmt, va_list);