From 185986c61d4f84efcc02cc5766c77e876654a0a9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 22 Apr 2010 03:51:26 +0200 Subject: assert: store away assert msg before aborting, akin to glibc's __abort_msg --- log.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++------------------ log.h | 6 ++++++ macro.h | 16 ++++++++-------- 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/log.c b/log.c index d8cc4048c4..076fa00bfd 100644 --- a/log.c +++ b/log.c @@ -40,6 +40,10 @@ static int log_max_level = LOG_DEBUG; static int syslog_fd = -1; static int kmsg_fd = -1; +/* Akin to glibc's __abort_msg; which is private and we hance cannot + * use here. */ +static char *log_abort_msg = NULL; + void log_close_kmsg(void) { if (kmsg_fd >= 0) { @@ -245,6 +249,26 @@ static int write_to_kmsg( return 0; } +#define LOG_DISPATCH(level,file,line,func,format) \ + do { \ + va_list _ap; \ + bool written = false; \ + if (log_target == LOG_TARGET_KMSG) { \ + va_start(_ap, format); \ + written = write_to_kmsg(level, file, line, func, format, _ap) >= 0; \ + va_end(_ap); \ + } else if (log_target == LOG_TARGET_SYSLOG) { \ + va_start(_ap, format); \ + written = write_to_syslog(level, file, line, func, format, _ap) >= 0; \ + va_end(_ap); \ + } \ + if (!written) { \ + va_start(_ap, format); \ + write_to_console(level, file, line, func, format, _ap); \ + va_end(_ap); \ + } \ + } while (false) + void log_meta( int level, const char*file, @@ -252,32 +276,37 @@ void log_meta( const char *func, const char *format, ...) { - va_list ap; - bool written; int saved_errno; if (LOG_PRI(level) > log_max_level) return; saved_errno = errno; - written = false; - - if (log_target == LOG_TARGET_KMSG) { - va_start(ap, format); - written = write_to_kmsg(level, file, line, func, format, ap) >= 0; - va_end(ap); - } else if (log_target == LOG_TARGET_SYSLOG) { - va_start(ap, format); - written = write_to_syslog(level, file, line, func, format, ap) >= 0; - va_end(ap); - } + LOG_DISPATCH(level, file, line, func, format); + errno = saved_errno; +} - if (!written) { - va_start(ap, format); - write_to_console(level, file, line, func, format, ap); - va_end(ap); - } +void log_assert( + const char*file, + int line, + const char *func, + const char *format, ...) { + + static char buffer[LOG_BUFFER_MAX]; + va_list ap; + int saved_errno = errno; + + va_start(ap, format); + vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); + + char_array_0(buffer); + log_abort_msg = buffer; + + LOG_DISPATCH(LOG_CRIT, file, line, func, format); + abort(); + /* If the user chose to ignore this SIGABRT, we are happy to go on, as if nothing happened. */ errno = saved_errno; } diff --git a/log.h b/log.h index f424c191fa..0fc1834f6f 100644 --- a/log.h +++ b/log.h @@ -57,6 +57,12 @@ void log_meta( const char *func, const char *format, ...) _printf_attr(5,6); +_noreturn void log_assert( + const char*file, + int line, + const char *func, + const char *format, ...) _printf_attr(4,5); + #define log_debug(...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, __VA_ARGS__) #define log_info(...) log_meta(LOG_INFO, __FILE__, __LINE__, __func__, __VA_ARGS__) #define log_notice(...) log_meta(LOG_NOTICE, __FILE__, __LINE__, __func__, __VA_ARGS__) diff --git a/macro.h b/macro.h index d56585dc34..2379ee2de3 100644 --- a/macro.h +++ b/macro.h @@ -35,6 +35,7 @@ #define _deprecated __attribute__ ((deprecated)) #define _packed __attribute__ ((packed)) #define _malloc __attribute__ ((malloc)) +#define _weak __attribute__ ((weak)) #define _likely(x) (__builtin_expect(!!(x),1)) #define _unlikely(x) (__builtin_expect(!!(x),0)) @@ -69,11 +70,10 @@ static inline size_t ALIGN(size_t l) { #define assert_se(expr) \ do { \ - if (_unlikely(!(expr))) { \ - log_error("Assertion '%s' failed at %s:%u, function %s(). Aborting.", \ - #expr , __FILE__, __LINE__, __PRETTY_FUNCTION__); \ - abort(); \ - } \ + if (_unlikely(!(expr))) \ + log_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + "Assertion '%s' failed at %s:%u, function %s(). Aborting.", \ + #expr , __FILE__, __LINE__, __PRETTY_FUNCTION__); \ } while (false) \ /* We override the glibc assert() here. */ @@ -86,9 +86,9 @@ static inline size_t ALIGN(size_t l) { #define assert_not_reached(t) \ do { \ - log_error("Code should not be reached '%s' at %s:%u, function %s(). Aborting.", \ - t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ - abort(); \ + log_assert(__FILE__, __LINE__, __PRETTY_FUNCTION__, \ + "Code should not be reached '%s' at %s:%u, function %s(). Aborting.", \ + t, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ } while (false) #define assert_cc(expr) \ -- cgit v1.2.3-54-g00ecf