From ded5269937ca4bad2a990b62461ff3ed2bacabc6 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Sun, 14 Oct 2018 01:11:14 +0300 Subject: [PATCH] mdbx-windows: rework mdbx_assert_fail() and mdbx_panic() to avoid dependency from CRT. 7 of 17 for https://github.com/leo-yuriev/libmdbx/issues/43 Change-Id: I40dc8d6a7d1d955c13c7d328ee904f0e6f30b248 --- src/bits.h | 6 ++++++ src/mdbx.c | 8 ++------ src/osal.c | 55 +++++++++++++++++++++++++++++++++--------------------- src/osal.h | 5 ----- 4 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/bits.h b/src/bits.h index 30ae690f..fc7b939e 100644 --- a/src/bits.h +++ b/src/bits.h @@ -868,6 +868,9 @@ void mdbx_panic(const char *fmt, ...) #endif /* NDEBUG */ #endif /* MDBX_DEBUG */ +LIBMDBX_API void mdbx_assert_fail(const MDBX_env *env, const char *msg, + const char *func, int line); + #define mdbx_print(fmt, ...) \ mdbx_debug_log(MDBX_DBG_PRINT, NULL, 0, fmt, ##__VA_ARGS__) @@ -967,6 +970,9 @@ void mdbx_panic(const char *fmt, ...) /* assert(3) variant in transaction context */ #define mdbx_tassert(txn, expr) mdbx_assert((txn)->mt_env, expr) +#undef assert +#define assert(expr) mdbx_assert(NULL, expr) + /*----------------------------------------------------------------------------*/ /* Internal prototypes */ diff --git a/src/mdbx.c b/src/mdbx.c index d1ad912c..e18b6a5b 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -40,9 +40,6 @@ /*----------------------------------------------------------------------------*/ /* Internal inlines */ -#undef assert -#define assert(expr) mdbx_assert(NULL, expr) - static __inline bool mdbx_is_power2(size_t x) { return (x & (x - 1)) == 0; } static __inline size_t mdbx_roundup2(size_t value, size_t granularity) { @@ -1409,10 +1406,8 @@ void __cold mdbx_debug_log(int type, const char *function, int line, OutputDebugStringA(msg); mdbx_free(msg); } - va_end(args); - return; } -#endif +#else if (function && line > 0) fprintf(stderr, "%s:%d ", function, line); else if (function) @@ -1421,6 +1416,7 @@ void __cold mdbx_debug_log(int type, const char *function, int line, fprintf(stderr, "%d: ", line); vfprintf(stderr, fmt, args); fflush(stderr); +#endif } va_end(args); } diff --git a/src/osal.c b/src/osal.c index 7306c1d0..99a2c9a9 100644 --- a/src/osal.c +++ b/src/osal.c @@ -154,13 +154,8 @@ typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 { /* Prototype should match libc runtime. ISO POSIX (2003) & LSB 3.1 */ __nothrow __noreturn void __assert_fail(const char *assertion, const char *file, unsigned line, const char *function); -#else -__extern_C __declspec(dllimport) void __cdecl _assert(char const *message, - char const *filename, - unsigned line); #endif /* _MSC_VER */ -#ifndef mdbx_assert_fail void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func, int line) { #if MDBX_DEBUG @@ -174,30 +169,48 @@ void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg, if (mdbx_debug_logger) mdbx_debug_log(MDBX_DBG_ASSERT, func, line, "assert: %s\n", msg); -#ifndef _MSC_VER - __assert_fail(msg, "mdbx", line, func); + else { +#if defined(_WIN32) || defined(_WIN64) + char *message = nullptr; + const int num = mdbx_asprintf(&message, "\r\nMDBX-ASSERTION: %s, %s:%u", + func ? func : "unknown", line); + if (num < 1 || !message) + message = ""; + OutputDebugStringA(message); + if (IsDebuggerPresent()) + DebugBreak(); #else - _assert(msg, func, line); -#endif /* _MSC_VER */ + __assert_fail(msg, "mdbx", line, func); +#endif + } + +#if defined(_WIN32) || defined(_WIN64) + FatalExit(ERROR_UNHANDLED_ERROR); +#else + abort(); +#endif } -#endif /* mdbx_assert_fail */ __cold void mdbx_panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); -#ifdef _MSC_VER - if (IsDebuggerPresent()) { - OutputDebugStringA("\r\n" FIXME "\r\n"); - FatalExit(ERROR_UNHANDLED_ERROR); - } -#elif _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L || \ - (__GLIBC_PREREQ(1, 0) && !__GLIBC_PREREQ(2, 10) && defined(_GNU_SOURCE)) - vdprintf(STDERR_FILENO, fmt, ap); -#else -#error FIXME -#endif + + char *message = nullptr; + const int num = mdbx_vasprintf(&message, fmt, ap); va_end(ap); + if (num < 1 || !message) + message = ""; + +#if defined(_WIN32) || defined(_WIN64) + OutputDebugStringA("\r\nMDBX-PANIC: "); + OutputDebugStringA(message); + if (IsDebuggerPresent()) + DebugBreak(); + FatalExit(ERROR_UNHANDLED_ERROR); +#else + __assert_fail(message, "mdbx", 0, "panic"); abort(); +#endif } /*----------------------------------------------------------------------------*/ diff --git a/src/osal.h b/src/osal.h index 3e2f6a68..e2da2611 100644 --- a/src/osal.h +++ b/src/osal.h @@ -393,11 +393,6 @@ static __inline void mdbx_invalidate_cache(void *addr, size_t nbytes) { /*----------------------------------------------------------------------------*/ /* libc compatibility stuff */ -#ifndef mdbx_assert_fail -void mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func, - int line); -#endif /* mdbx_assert_fail */ - #if __GLIBC_PREREQ(2, 1) #define mdbx_asprintf asprintf #define mdbx_vasprintf vasprintf