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 /* 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 */

View File

@ -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);
}

View File

@ -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 = "<troubles with assertion-message preparation>";
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 = "<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();
#endif
}
/*----------------------------------------------------------------------------*/

View File

@ -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