diff --git a/src/ydb.c b/src/ydb.c index bf8169bb42e6ca0e7324b250f910beeea91b99e3..5f64e717d8b708cb88bed37a5651cf1037fb7ad8 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -2108,9 +2108,12 @@ env_get_engine_status_text(DB_ENV * env, char * buff, int bufsiz) { } static int toku_maybe_get_engine_status_text (char* buff, int buffsize); +static void toku_maybe_set_env_panic(int code, char * msg); -// assign value to global pointer so that other files can access via tentative definition if linked to this library (.so) +// assign values to global pointers so that other files can access via tentative definition if linked to this library (.so) int (*toku_maybe_get_engine_status_text_p)(char* buff, int buffsize) = toku_maybe_get_engine_status_text; +void (*toku_maybe_set_env_panic_p)(int code, char* msg) = toku_maybe_set_env_panic; + // intended for use by toku_assert logic, when env is not known static int @@ -2127,6 +2130,18 @@ toku_maybe_get_engine_status_text (char * buff, int buffsize) { return r; } +// Set panic code and panic string if not already panicked, +// intended for use by toku_assert when about to abort(). +static void +toku_maybe_set_env_panic(int code, char * msg) { + DB_ENV * env = most_recent_env; + if (env) { + if (env->i->is_panicked == 0) { + env->i->is_panicked = code; + env->i->panic_string = toku_strdup(msg); + } + } +} static int locked_txn_begin(DB_ENV * env, DB_TXN * stxn, DB_TXN ** txn, u_int32_t flags); diff --git a/windows/toku_assert.c b/windows/toku_assert.c index 9498c79bc0e59a84184368a83fe5087e80165e30..96f1d70b5c503ada788c7bbe0a79a4fd419c6e9e 100644 --- a/windows/toku_assert.c +++ b/windows/toku_assert.c @@ -18,6 +18,8 @@ static void *backtrace_pointers[N_POINTERS]; #endif int (*toku_maybe_get_engine_status_text_p)(char* buff, int buffsize); // tentative definition: if linked to ydb, will have non-zero value +void (*toku_maybe_set_env_panic_p)(int code, char* msg); // tentative definition: if linked to ydb, will have non-zero value + void (*do_assert_hook)(void) = NULL; @@ -69,15 +71,33 @@ toku_do_backtrace_abort(void) { abort(); } + +static void +set_panic_if_not_panicked(int caller_errno, char * msg) { + int code = caller_errno ? caller_errno : -1; + if (toku_maybe_set_env_panic_p) { + toku_maybe_set_env_panic_p(code, msg); + } +} + + +#define MSGLEN 1024 + void toku_do_assert_fail (const char *expr_as_string, const char *function, const char *file, int line, int caller_errno) { - fprintf(stderr, "%s:%d %s: Assertion `%s' failed (errno=%d)\n", file, line, function, expr_as_string, caller_errno); + char msg[MSGLEN]; + snprintf(msg, MSGLEN, "%s:%d %s: Assertion `%s' failed (errno=%d)\n", file, line, function, expr_as_string, caller_errno); + fprintf(stderr, "%s", msg); + set_panic_if_not_panicked(caller_errno, msg); toku_do_backtrace_abort(); } void toku_do_assert_zero_fail (uintptr_t expr, const char *expr_as_string, const char *function, const char *file, int line, int caller_errno) { - fprintf(stderr, "%s:%d %s: Assertion `%s == 0' failed (errno=%d) (%s=%"PRIuPTR")\n", file, line, function, expr_as_string, caller_errno, expr_as_string, expr); + char msg[MSGLEN]; + snprintf(msg, MSGLEN, "%s:%d %s: Assertion `%s == 0' failed (errno=%d) (%s=%"PRIuPTR")\n", file, line, function, expr_as_string, caller_errno, expr_as_string, expr); + fprintf(stderr, "%s", msg); + set_panic_if_not_panicked(caller_errno, msg); toku_do_backtrace_abort(); }