/* -*- mode: C; c-basic-offset: 4 -*- */ #ident "Copyright (c) 2007-2010 Tokutek Inc. All rights reserved." #include <toku_portability.h> #include "toku_assert.h" #include <stdlib.h> #include <stdio.h> #if !TOKU_WINDOWS #include <execinfo.h> #endif #if !TOKU_WINDOWS #define N_POINTERS 1000 // These are statically allocated so that the backtrace can run without any calls to malloc() 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 (*do_assert_hook)(void) = NULL; static void toku_do_backtrace_abort(void) __attribute__((noreturn)); static void toku_do_backtrace_abort(void) { // backtrace #if !TOKU_WINDOWS int n = backtrace(backtrace_pointers, N_POINTERS); fprintf(stderr, "Backtrace: (Note: toku_do_assert=0x%p)\n", toku_do_assert); fflush(stderr); backtrace_symbols_fd(backtrace_pointers, n, fileno(stderr)); #endif fflush(stderr); if (toku_maybe_get_engine_status_text_p) { int r; int buffsize = 1024 * 32; char buff[buffsize]; r = toku_maybe_get_engine_status_text_p(buff, buffsize); fprintf(stderr, "Engine status:\n%s\n", buff); } else fprintf(stderr, "Engine status function not available\n"); fflush(stderr); #if TOKU_WINDOWS //Following commented methods will not always end the process (could hang). //They could be unacceptable for other reasons as well (popups, //flush buffers before quitting, etc) // abort() // assert(FALSE) (assert.h assert) // raise(SIGABRT) // divide by 0 // null dereference // _exit // exit // ExitProcess TerminateProcess(GetCurrentProcess(), 134); //Only way found so far to unconditionally //Terminate the process #endif if (do_assert_hook) do_assert_hook(); abort(); } 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); 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); toku_do_backtrace_abort(); } void toku_do_assert(int expr, const char *expr_as_string, const char *function, const char* file, int line, int caller_errno) { if (expr == 0) toku_do_assert_fail(expr_as_string, function, file, line, caller_errno); }