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
This commit is contained in:
Leonid Yuriev 2018-10-14 01:11:14 +03:00
parent ae2875e248
commit ded5269937
4 changed files with 42 additions and 32 deletions

View File

@ -868,6 +868,9 @@ void mdbx_panic(const char *fmt, ...)
#endif /* NDEBUG */ #endif /* NDEBUG */
#endif /* MDBX_DEBUG */ #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, ...) \ #define mdbx_print(fmt, ...) \
mdbx_debug_log(MDBX_DBG_PRINT, NULL, 0, fmt, ##__VA_ARGS__) 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 */ /* assert(3) variant in transaction context */
#define mdbx_tassert(txn, expr) mdbx_assert((txn)->mt_env, expr) #define mdbx_tassert(txn, expr) mdbx_assert((txn)->mt_env, expr)
#undef assert
#define assert(expr) mdbx_assert(NULL, expr)
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* Internal prototypes */ /* Internal prototypes */

View File

@ -40,9 +40,6 @@
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* Internal inlines */ /* 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 bool mdbx_is_power2(size_t x) { return (x & (x - 1)) == 0; }
static __inline size_t mdbx_roundup2(size_t value, size_t granularity) { 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); OutputDebugStringA(msg);
mdbx_free(msg); mdbx_free(msg);
} }
va_end(args);
return;
} }
#endif #else
if (function && line > 0) if (function && line > 0)
fprintf(stderr, "%s:%d ", function, line); fprintf(stderr, "%s:%d ", function, line);
else if (function) else if (function)
@ -1421,6 +1416,7 @@ void __cold mdbx_debug_log(int type, const char *function, int line,
fprintf(stderr, "%d: ", line); fprintf(stderr, "%d: ", line);
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
fflush(stderr); fflush(stderr);
#endif
} }
va_end(args); va_end(args);
} }

View File

@ -154,13 +154,8 @@ typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
/* Prototype should match libc runtime. ISO POSIX (2003) & LSB 3.1 */ /* Prototype should match libc runtime. ISO POSIX (2003) & LSB 3.1 */
__nothrow __noreturn void __assert_fail(const char *assertion, const char *file, __nothrow __noreturn void __assert_fail(const char *assertion, const char *file,
unsigned line, const char *function); unsigned line, const char *function);
#else
__extern_C __declspec(dllimport) void __cdecl _assert(char const *message,
char const *filename,
unsigned line);
#endif /* _MSC_VER */ #endif /* _MSC_VER */
#ifndef mdbx_assert_fail
void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg, void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg,
const char *func, int line) { const char *func, int line) {
#if MDBX_DEBUG #if MDBX_DEBUG
@ -174,30 +169,48 @@ void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg,
if (mdbx_debug_logger) if (mdbx_debug_logger)
mdbx_debug_log(MDBX_DBG_ASSERT, func, line, "assert: %s\n", msg); mdbx_debug_log(MDBX_DBG_ASSERT, func, line, "assert: %s\n", msg);
#ifndef _MSC_VER else {
__assert_fail(msg, "mdbx", line, func); #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 = "<troubles with assertion-message preparation>";
OutputDebugStringA(message);
if (IsDebuggerPresent())
DebugBreak();
#else #else
_assert(msg, func, line); __assert_fail(msg, "mdbx", line, func);
#endif /* _MSC_VER */ #endif
}
#if defined(_WIN32) || defined(_WIN64)
FatalExit(ERROR_UNHANDLED_ERROR);
#else
abort();
#endif
} }
#endif /* mdbx_assert_fail */
__cold void mdbx_panic(const char *fmt, ...) { __cold void mdbx_panic(const char *fmt, ...) {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
#ifdef _MSC_VER
if (IsDebuggerPresent()) { char *message = nullptr;
OutputDebugStringA("\r\n" FIXME "\r\n"); const int num = mdbx_vasprintf(&message, fmt, ap);
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
va_end(ap); va_end(ap);
if (num < 1 || !message)
message = "<troubles with panic-message preparation>";
#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(); abort();
#endif
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

View File

@ -393,11 +393,6 @@ static __inline void mdbx_invalidate_cache(void *addr, size_t nbytes) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* libc compatibility stuff */ /* 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) #if __GLIBC_PREREQ(2, 1)
#define mdbx_asprintf asprintf #define mdbx_asprintf asprintf
#define mdbx_vasprintf vasprintf #define mdbx_vasprintf vasprintf